Branch data Line data Source code
1 : : /* Update symbol information and section index in symbol table at the
2 : : given index.
3 : : Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
4 : : This file is part of elfutils.
5 : : Written by Ulrich Drepper <drepper@redhat.com>, 2000.
6 : :
7 : : This file is free software; you can redistribute it and/or modify
8 : : it under the terms of either
9 : :
10 : : * the GNU Lesser General Public License as published by the Free
11 : : Software Foundation; either version 3 of the License, or (at
12 : : your option) any later version
13 : :
14 : : or
15 : :
16 : : * the GNU General Public License as published by the Free
17 : : Software Foundation; either version 2 of the License, or (at
18 : : your option) any later version
19 : :
20 : : or both in parallel, as here.
21 : :
22 : : elfutils is distributed in the hope that it will be useful, but
23 : : WITHOUT ANY WARRANTY; without even the implied warranty of
24 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 : : General Public License for more details.
26 : :
27 : : You should have received copies of the GNU General Public License and
28 : : the GNU Lesser General Public License along with this program. If
29 : : not, see <http://www.gnu.org/licenses/>. */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : # include <config.h>
33 : : #endif
34 : :
35 : : #include <gelf.h>
36 : : #include <stdlib.h>
37 : : #include <string.h>
38 : :
39 : : #include "libelfP.h"
40 : :
41 : :
42 : : int
43 : 919 : gelf_update_symshndx (symdata, shndxdata, ndx, src, srcshndx)
44 : : Elf_Data *symdata;
45 : : Elf_Data *shndxdata;
46 : : int ndx;
47 : : GElf_Sym *src;
48 : : Elf32_Word srcshndx;
49 : : {
50 : 919 : Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
51 : 919 : Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
52 : : Elf_Scn *scn;
53 : 919 : Elf32_Word *shndx = NULL;
54 : 919 : int result = 0;
55 : :
56 [ + - ]: 919 : if (symdata == NULL)
57 : : return 0;
58 : :
59 [ - + ]: 919 : if (unlikely (ndx < 0))
60 : : {
61 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
62 : 0 : return 0;
63 : : }
64 : :
65 [ - + ]: 919 : if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
66 : : {
67 : : /* The type of the data better should match. */
68 : 0 : __libelf_seterrno (ELF_E_DATA_MISMATCH);
69 : 0 : return 0;
70 : : }
71 : :
72 : 919 : scn = symdata_scn->s;
73 : : /* We simply have to believe the user that the two sections belong to
74 : : the same ELF file. */
75 : : rwlock_wrlock (scn->elf->lock);
76 : :
77 : : /* The user is not required to pass a data descriptor for an extended
78 : : section index table. */
79 [ - + ]: 919 : if (shndxdata_scn != NULL)
80 : : {
81 [ # # ]: 0 : if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
82 : : {
83 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
84 : 0 : goto out;
85 : : }
86 : :
87 : 0 : shndx = &((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
88 : : }
89 : : /* But if s/he does not the extended sectio index must be zero. */
90 [ - + ]: 919 : else if (unlikely (srcshndx != 0))
91 : : {
92 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
93 : 0 : goto out;
94 : : }
95 : :
96 [ + + ]: 919 : if (scn->elf->class == ELFCLASS32)
97 : : {
98 : : Elf32_Sym *sym;
99 : :
100 : : /* There is the possibility that the values in the input are
101 : : too large. */
102 [ + - ]: 333 : if (unlikely (src->st_value > 0xffffffffull)
103 [ - + ]: 333 : || unlikely (src->st_size > 0xffffffffull))
104 : : {
105 : 0 : __libelf_seterrno (ELF_E_INVALID_DATA);
106 : 0 : goto out;
107 : : }
108 : :
109 : : /* Check whether we have to resize the data buffer. */
110 [ - + ]: 333 : if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
111 : : {
112 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
113 : 0 : goto out;
114 : : }
115 : :
116 : 333 : sym = &((Elf32_Sym *) symdata_scn->d.d_buf)[ndx];
117 : :
118 : : #define COPY(name) \
119 : : sym->name = src->name
120 : 333 : COPY (st_name);
121 : 333 : COPY (st_value);
122 : 333 : COPY (st_size);
123 : : /* Please note that we can simply copy the `st_info' element since
124 : : the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
125 : : for the 64 bit variant. */
126 : 333 : COPY (st_info);
127 : 333 : COPY (st_other);
128 : 333 : COPY (st_shndx);
129 : : }
130 : : else
131 : : {
132 : : /* Check whether we have to resize the data buffer. */
133 [ - + ]: 586 : if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
134 : : {
135 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
136 : 0 : goto out;
137 : : }
138 : :
139 : 586 : ((Elf64_Sym *) symdata_scn->d.d_buf)[ndx] = *src;
140 : : }
141 : :
142 : : /* Now we can store the section index. */
143 [ - + ]: 919 : if (shndx != NULL)
144 : 0 : *shndx = srcshndx;
145 : :
146 : 919 : result = 1;
147 : :
148 : : /* Mark the section as modified. */
149 : 919 : scn->flags |= ELF_F_DIRTY;
150 : :
151 : : out:
152 : : rwlock_unlock (scn->elf->lock);
153 : :
154 : 919 : return result;
155 : : }
|