]>
Commit | Line | Data |
---|---|---|
96b9de17 JB |
1 | 2005-11-26 Jakub Bogusz <qboosh at pld-linux dot org> |
2 | ||
3 | * src/elflint.c (valid_e_machine) Add EM_ALPHA to valid machines. | |
4 | (check_hash): Support hash bucket size of 8 on alpha and s390x. | |
5 | (check_sections): Support arch-specific section flags. | |
6 | * libebl/alpha_symbol.c: Update, including: | |
7 | (reloc_map_table) Include appear field. | |
8 | (alpha_reloc_type_name) Updated for new reloc_map_table. | |
9 | (alpha_reloc_type_check) Likewise. | |
10 | (alpha_reloc_valid_use) New function. | |
11 | (alpha_reloc_simple_type) Likewise. | |
12 | * libebl/alpha_init.c (alpha_init): Initialize reloc_valid_use and | |
13 | reloc_simple_type fields. | |
14 | * libebl/libebl_alpha.h: Add alpha_reloc_valid_use and | |
15 | alpha_reloc_simple_type functions. | |
16 | * libebl/Makefile.am: Link libebl_alpha.so with libelf. | |
17 | * libelf/elf32_getshdr.c: Fix assert condition; handle unaligned | |
18 | section header with same endianess properly. | |
19 | ||
20 | --- elfutils-0.116/src/elflint.c.orig 2005-11-26 10:28:00.000000000 +0100 | |
21 | +++ elfutils-0.116/src/elflint.c 2005-11-26 14:01:18.000000000 +0100 | |
22 | @@ -331,7 +331,7 @@ | |
23 | EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, | |
24 | EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, | |
25 | EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, | |
26 | - EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA | |
27 | + EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA | |
28 | }; | |
29 | #define nvalid_e_machine \ | |
30 | (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) | |
31 | @@ -1664,6 +1664,16 @@ | |
32 | section [%2d] '%s': hash table not for dynamic symbol table\n"), | |
33 | idx, section_name (ebl, idx)); | |
34 | ||
35 | + bool bighash = | |
36 | + (ehdr->e_machine == EM_ALPHA) || | |
37 | + ((ehdr->e_machine == EM_S390) && (ehdr->e_ident[EI_CLASS] == ELFCLASS64)); | |
38 | + | |
39 | + if (bighash) { | |
40 | + if (shdr->sh_entsize != 8) /* alpha and s390x use non-standard hash bucket size of 8 */ | |
41 | + ERROR (gettext ("\ | |
42 | +section [%2d] '%s': entry size is not 8\n"), | |
43 | + idx, section_name (ebl, idx)); | |
44 | + } else | |
45 | if (shdr->sh_entsize != sizeof (Elf32_Word)) | |
46 | ERROR (gettext ("\ | |
47 | section [%2d] '%s': entry size does not match Elf32_Word\n"), | |
48 | @@ -1681,8 +1691,15 @@ | |
49 | return; | |
50 | } | |
51 | ||
52 | - Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; | |
53 | - Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; | |
54 | + uint64_t nbucket, nchain; | |
55 | + | |
56 | + if (bighash) { | |
57 | + nbucket = ((Elf64_Xword *) data->d_buf)[0]; | |
58 | + nchain = ((Elf64_Xword *) data->d_buf)[1]; | |
59 | + } else { | |
60 | + nbucket = ((Elf32_Word *) data->d_buf)[0]; | |
61 | + nchain = ((Elf32_Word *) data->d_buf)[1]; | |
62 | + } | |
63 | ||
64 | if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) | |
65 | ERROR (gettext ("\ | |
66 | @@ -1694,29 +1711,41 @@ | |
67 | { | |
68 | size_t symsize = symshdr->sh_size / symshdr->sh_entsize; | |
69 | size_t cnt; | |
70 | - Elf32_Word *buf, *end; | |
71 | + void *buf, *end; | |
72 | + uint64_t val; | |
73 | ||
74 | if (nchain < symshdr->sh_size / symshdr->sh_entsize) | |
75 | ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"), | |
76 | idx, section_name (ebl, idx)); | |
77 | ||
78 | + if (bighash) { | |
79 | + buf = ((Elf64_Xword *) data->d_buf) + 2; | |
80 | + end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size); | |
81 | + } else { | |
82 | buf = ((Elf32_Word *) data->d_buf) + 2; | |
83 | end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size); | |
84 | - for (cnt = 2; cnt < 2 + nbucket; ++cnt) | |
85 | + } | |
86 | + for (cnt = 2; cnt < 2 + nbucket; ++cnt) { | |
87 | if (buf >= end) | |
88 | return; | |
89 | - else if (*buf++ >= symsize) | |
90 | + val = bighash ? *(Elf64_Xword *)buf : *(Elf32_Word *)buf; | |
91 | + if (val >= symsize) | |
92 | ERROR (gettext ("\ | |
93 | section [%2d] '%s': hash bucket reference %zu out of bounds\n"), | |
94 | idx, section_name (ebl, idx), cnt - 2); | |
95 | + buf += bighash ? 8 : sizeof(Elf32_Word); | |
96 | + } | |
97 | ||
98 | - for (; cnt < 2 + nbucket + nchain; ++cnt) | |
99 | + for (; cnt < 2 + nbucket + nchain; ++cnt) { | |
100 | if (buf >= end) | |
101 | return; | |
102 | - else if (*buf++ >= symsize) | |
103 | + val = bighash ? *(Elf64_Xword *)buf : *(Elf32_Word *)buf; | |
104 | + if (val >= symsize) | |
105 | ERROR (gettext ("\ | |
106 | section [%2d] '%s': hash chain reference %zu out of bounds\n"), | |
107 | idx, section_name (ebl, idx), cnt - 2 - nbucket); | |
108 | + buf += bighash ? 8 : sizeof(Elf32_Word); | |
109 | + } | |
110 | } | |
111 | } | |
112 | ||
113 | @@ -2744,9 +2773,30 @@ | |
114 | cnt, section_name (ebl, cnt), | |
115 | (int) shdr->sh_type); | |
116 | ||
117 | -#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ | |
118 | +#define GALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ | |
119 | | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ | |
120 | | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) | |
121 | + uint64_t ALL_SH_FLAGS = GALL_SH_FLAGS; /* generic */ | |
122 | + switch (ehdr->e_machine) { | |
123 | + case EM_MIPS: | |
124 | + ALL_SH_FLAGS |= SHF_MIPS_GPREL | SHF_MIPS_MERGE | SHF_MIPS_ADDR | | |
125 | + SHF_MIPS_STRINGS | SHF_MIPS_NOSTRIP | SHF_MIPS_LOCAL | | |
126 | + SHF_MIPS_NAMES | SHF_MIPS_NODUPE; | |
127 | + break; | |
128 | + case EM_PARISC: | |
129 | + ALL_SH_FLAGS |= SHF_PARISC_SHORT | SHF_PARISC_HUGE | SHF_PARISC_SBP; | |
130 | + break; | |
131 | + case EM_ALPHA: | |
132 | + ALL_SH_FLAGS |= SHF_ALPHA_GPREL; | |
133 | + break; | |
134 | + case EM_ARM: | |
135 | + ALL_SH_FLAGS |= SHF_ARM_ENTRYSECT | SHF_ARM_COMDEF; | |
136 | + break; | |
137 | + case EM_IA_64: | |
138 | + ALL_SH_FLAGS |= SHF_IA_64_SHORT | SHF_IA_64_NORECOV; | |
139 | + break; | |
140 | + } | |
141 | + | |
142 | if (shdr->sh_flags & ~ALL_SH_FLAGS) | |
143 | ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" | |
144 | " %#" PRIx64 "\n"), | |
145 | --- elfutils-0.116/libebl/alpha_symbol.c.orig 2005-08-07 09:59:17.000000000 +0200 | |
146 | +++ elfutils-0.116/libebl/alpha_symbol.c 2005-11-26 14:41:48.000000000 +0100 | |
147 | @@ -16,6 +16,7 @@ | |
148 | # include <config.h> | |
149 | #endif | |
150 | ||
151 | +#include <assert.h> | |
152 | #include <elf.h> | |
153 | #include <stddef.h> | |
154 | ||
155 | @@ -31,41 +32,45 @@ | |
156 | ||
157 | ||
158 | /* Relocation mapping table. */ | |
159 | -static const char *reloc_map_table[] = | |
160 | +static struct | |
161 | +{ | |
162 | + const char *name; | |
163 | + enum { both = 0, rel = 1, exec = 2 } appear; | |
164 | +} reloc_map_table[] = | |
165 | { | |
166 | - [R_ALPHA_NONE] = "R_ALPHA_NONE", | |
167 | - [R_ALPHA_REFLONG] = "R_ALPHA_REFLONG", | |
168 | - [R_ALPHA_REFQUAD] = "R_ALPHA_REFQUAD", | |
169 | - [R_ALPHA_GPREL32] = "R_ALPHA_GPREL32", | |
170 | - [R_ALPHA_LITERAL] = "R_ALPHA_LITERAL", | |
171 | - [R_ALPHA_LITUSE] = "R_ALPHA_LITUSE", | |
172 | - [R_ALPHA_GPDISP] = "R_ALPHA_GPDISP", | |
173 | - [R_ALPHA_BRADDR] = "R_ALPHA_BRADDR", | |
174 | - [R_ALPHA_HINT] = "R_ALPHA_HINT", | |
175 | - [R_ALPHA_SREL16] = "R_ALPHA_SREL16", | |
176 | - [R_ALPHA_SREL32] = "R_ALPHA_SREL32", | |
177 | - [R_ALPHA_SREL64] = "R_ALPHA_SREL64", | |
178 | - [R_ALPHA_GPRELHIGH] = "R_ALPHA_GPRELHIGH", | |
179 | - [R_ALPHA_GPRELLOW] = "R_ALPHA_GPRELLOW", | |
180 | - [R_ALPHA_GPREL16] = "R_ALPHA_GPREL16", | |
181 | - [R_ALPHA_COPY] = "R_ALPHA_COPY", | |
182 | - [R_ALPHA_GLOB_DAT] = "R_ALPHA_GLOB_DAT", | |
183 | - [R_ALPHA_JMP_SLOT] = "R_ALPHA_JMP_SLOT", | |
184 | - [R_ALPHA_RELATIVE] = "R_ALPHA_RELATIVE", | |
185 | - [R_ALPHA_TLS_GD_HI] = "R_ALPHA_TLS_GD_HI", | |
186 | - [R_ALPHA_TLSGD] = "R_ALPHA_TLSGD", | |
187 | - [R_ALPHA_TLS_LDM] = "R_ALPHA_TLS_LDM", | |
188 | - [R_ALPHA_DTPMOD64] = "R_ALPHA_DTPMOD64", | |
189 | - [R_ALPHA_GOTDTPREL] = "R_ALPHA_GOTDTPREL", | |
190 | - [R_ALPHA_DTPREL64] = "R_ALPHA_DTPREL64", | |
191 | - [R_ALPHA_DTPRELHI] = "R_ALPHA_DTPRELHI", | |
192 | - [R_ALPHA_DTPRELLO] = "R_ALPHA_DTPRELLO", | |
193 | - [R_ALPHA_DTPREL16] = "R_ALPHA_DTPREL16", | |
194 | - [R_ALPHA_GOTTPREL] = "R_ALPHA_GOTTPREL", | |
195 | - [R_ALPHA_TPREL64] = "R_ALPHA_TPREL64", | |
196 | - [R_ALPHA_TPRELHI] = "R_ALPHA_TPRELHI", | |
197 | - [R_ALPHA_TPRELLO] = "R_ALPHA_TPRELLO", | |
198 | - [R_ALPHA_TPREL16] = "R_ALPHA_TPREL16" | |
199 | + [R_ALPHA_NONE] = { "R_ALPHA_NONE", both }, | |
200 | + [R_ALPHA_REFLONG] = { "R_ALPHA_REFLONG", both }, | |
201 | + [R_ALPHA_REFQUAD] = { "R_ALPHA_REFQUAD", both }, | |
202 | + [R_ALPHA_GPREL32] = { "R_ALPHA_GPREL32", rel }, | |
203 | + [R_ALPHA_LITERAL] = { "R_ALPHA_LITERAL", rel }, | |
204 | + [R_ALPHA_LITUSE] = { "R_ALPHA_LITUSE", rel }, | |
205 | + [R_ALPHA_GPDISP] = { "R_ALPHA_GPDISP", rel }, | |
206 | + [R_ALPHA_BRADDR] = { "R_ALPHA_BRADDR", rel }, | |
207 | + [R_ALPHA_HINT] = { "R_ALPHA_HINT", rel }, | |
208 | + [R_ALPHA_SREL16] = { "R_ALPHA_SREL16", rel }, | |
209 | + [R_ALPHA_SREL32] = { "R_ALPHA_SREL32", rel }, | |
210 | + [R_ALPHA_SREL64] = { "R_ALPHA_SREL64", rel }, | |
211 | + [R_ALPHA_GPRELHIGH] = { "R_ALPHA_GPRELHIGH", rel }, | |
212 | + [R_ALPHA_GPRELLOW] = { "R_ALPHA_GPRELLOW", rel }, | |
213 | + [R_ALPHA_GPREL16] = { "R_ALPHA_GPREL16", rel }, | |
214 | + [R_ALPHA_COPY] = { "R_ALPHA_COPY", exec }, | |
215 | + [R_ALPHA_GLOB_DAT] = { "R_ALPHA_GLOB_DAT", exec }, | |
216 | + [R_ALPHA_JMP_SLOT] = { "R_ALPHA_JMP_SLOT", exec }, | |
217 | + [R_ALPHA_RELATIVE] = { "R_ALPHA_RELATIVE", exec }, | |
218 | + [R_ALPHA_TLS_GD_HI] = { "R_ALPHA_TLS_GD_HI", rel }, | |
219 | + [R_ALPHA_TLSGD] = { "R_ALPHA_TLSGD", rel }, | |
220 | + [R_ALPHA_TLS_LDM] = { "R_ALPHA_TLS_LDM", rel }, | |
221 | + [R_ALPHA_DTPMOD64] = { "R_ALPHA_DTPMOD64", exec }, | |
222 | + [R_ALPHA_GOTDTPREL] = { "R_ALPHA_GOTDTPREL", rel }, | |
223 | + [R_ALPHA_DTPREL64] = { "R_ALPHA_DTPREL64", exec }, | |
224 | + [R_ALPHA_DTPRELHI] = { "R_ALPHA_DTPRELHI", rel }, | |
225 | + [R_ALPHA_DTPRELLO] = { "R_ALPHA_DTPRELLO", rel }, | |
226 | + [R_ALPHA_DTPREL16] = { "R_ALPHA_DTPREL16", rel }, | |
227 | + [R_ALPHA_GOTTPREL] = { "R_ALPHA_GOTTPREL", rel }, | |
228 | + [R_ALPHA_TPREL64] = { "R_ALPHA_TPREL64", exec }, | |
229 | + [R_ALPHA_TPRELHI] = { "R_ALPHA_TPRELHI", rel }, | |
230 | + [R_ALPHA_TPRELLO] = { "R_ALPHA_TPRELLO", rel }, | |
231 | + [R_ALPHA_TPREL16] = { "R_ALPHA_TPREL16", rel } | |
232 | }; | |
233 | ||
234 | ||
235 | @@ -74,12 +79,10 @@ | |
236 | alpha_reloc_type_name (int type, char *buf __attribute__ ((unused)), | |
237 | size_t len __attribute__ ((unused))) | |
238 | { | |
239 | - if (type < 0 | |
240 | - || ((size_t) type | |
241 | - >= sizeof (reloc_map_table) / sizeof (reloc_map_table[0]))) | |
242 | + if (type < 0 || type >= R_ALPHA_NUM) | |
243 | return NULL; | |
244 | ||
245 | - return reloc_map_table[type]; | |
246 | + return reloc_map_table[type].name; | |
247 | } | |
248 | ||
249 | ||
250 | @@ -87,10 +90,43 @@ | |
251 | bool | |
252 | alpha_reloc_type_check (int type) | |
253 | { | |
254 | - return (type >= R_ALPHA_NONE | |
255 | - && ((size_t) type | |
256 | - < sizeof (reloc_map_table) / sizeof (reloc_map_table[0])) | |
257 | - && reloc_map_table[type] != NULL) ? true : false; | |
258 | + return (type >= R_ALPHA_NONE && type < R_ALPHA_NUM | |
259 | + && reloc_map_table[type].name != NULL) ? true : false; | |
260 | +} | |
261 | + | |
262 | +/* Check for correct relocation type use. */ | |
263 | +bool | |
264 | +alpha_reloc_valid_use (Elf *elf, int type) | |
265 | +{ | |
266 | + if (type < R_ALPHA_NONE || type >= R_ALPHA_NUM | |
267 | + || reloc_map_table[type].name == NULL) | |
268 | + return false; | |
269 | + | |
270 | + Elf64_Ehdr *ehdr = elf64_getehdr (elf); | |
271 | + assert (ehdr != NULL); | |
272 | + if (reloc_map_table[type].appear == rel) | |
273 | + return ehdr->e_type == ET_REL; | |
274 | + | |
275 | + if (reloc_map_table[type].appear == exec) | |
276 | + return ehdr->e_type != ET_REL; | |
277 | + | |
278 | + assert (reloc_map_table[type].appear == both); | |
279 | + return true; | |
280 | +} | |
281 | + | |
282 | +/* Check for the simple reloc types. */ | |
283 | +Elf_Type | |
284 | +alpha_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type) | |
285 | +{ | |
286 | + switch (type) | |
287 | + { | |
288 | + case R_ALPHA_REFLONG: | |
289 | + return ELF_T_WORD; | |
290 | + case R_ALPHA_REFQUAD: | |
291 | + return ELF_T_XWORD; | |
292 | + default: | |
293 | + return ELF_T_NUM; | |
294 | + } | |
295 | } | |
296 | ||
297 | ||
298 | --- elfutils-0.116/libebl/Makefile.am.orig 2005-11-26 10:28:00.000000000 +0100 | |
299 | +++ elfutils-0.116/libebl/Makefile.am 2005-11-26 12:52:21.000000000 +0100 | |
300 | @@ -120,7 +120,7 @@ | |
301 | libebl_alpha.so: libebl_alpha_pic.a libebl_alpha.map | |
302 | $(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \ | |
303 | -Wl,--version-script,$(srcdir)/libebl_alpha.map \ | |
304 | - -Wl,-z,defs $(libmudflap) | |
305 | + -Wl,-z,defs $(libelf) $(libmudflap) | |
306 | $(textrel_check) | |
307 | ||
308 | ||
309 | --- elfutils-0.116/libebl/alpha_init.c.orig 2005-08-07 09:58:18.000000000 +0200 | |
310 | +++ elfutils-0.116/libebl/alpha_init.c 2005-11-26 11:34:19.000000000 +0100 | |
311 | @@ -34,6 +34,8 @@ | |
312 | eh->name = "Alpha"; | |
313 | eh->reloc_type_name = alpha_reloc_type_name; | |
314 | eh->reloc_type_check = alpha_reloc_type_check; | |
315 | + eh->reloc_valid_use = alpha_reloc_valid_use; | |
316 | + eh->reloc_simple_type = alpha_reloc_simple_type; | |
317 | eh->dynamic_tag_name = alpha_dynamic_tag_name; | |
318 | eh->dynamic_tag_check = alpha_dynamic_tag_check; | |
319 | eh->copy_reloc_p = alpha_copy_reloc_p; | |
320 | --- elfutils-0.116/libebl/libebl_alpha.h.orig 2005-08-07 09:59:53.000000000 +0200 | |
321 | +++ elfutils-0.116/libebl/libebl_alpha.h 2005-11-26 12:49:21.000000000 +0100 | |
322 | @@ -31,6 +31,12 @@ | |
323 | /* Check relocation type. */ | |
324 | extern bool alpha_reloc_type_check (int type); | |
325 | ||
326 | +/* Check relocation type use. */ | |
327 | +extern bool alpha_reloc_valid_use (Elf *elf, int type); | |
328 | + | |
329 | +/* Check for the simple reloc types. */ | |
330 | +extern Elf_Type alpha_reloc_simple_type (Elf *elf, int type); | |
331 | + | |
332 | /* Name of dynamic tag. */ | |
333 | extern const char *alpha_dynamic_tag_name (int64_t tag, char *buf, size_t len); | |
334 | ||
335 | --- elfutils-0.116/libelf/elf32_getshdr.c.orig 2005-11-26 10:28:00.000000000 +0100 | |
336 | +++ elfutils-0.116/libelf/elf32_getshdr.c 2005-11-26 20:52:02.000000000 +0100 | |
337 | @@ -91,8 +91,8 @@ | |
338 | /* All the data is already mapped. If we could use it | |
339 | directly this would already have happened. */ | |
340 | assert (ehdr->e_ident[EI_DATA] != MY_ELFDATA | |
341 | - || (! ALLOW_UNALIGNED | |
342 | - && (ehdr->e_shoff | |
343 | + || ((! ALLOW_UNALIGNED) | |
344 | + && ((uintptr_t) ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff) | |
345 | & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0)); | |
346 | ||
347 | /* First see whether the information in the ELF header is | |
348 | @@ -106,9 +106,12 @@ | |
349 | } | |
350 | ||
351 | /* Now copy the data and at the same time convert the byte | |
352 | - order. */ | |
353 | + order, if needed. */ | |
354 | + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) | |
355 | + memcpy (shdr, ((char*) elf->map_address + elf->start_offset + ehdr->e_shoff), size); | |
356 | + else { | |
357 | if (ALLOW_UNALIGNED | |
358 | - || (ehdr->e_shoff | |
359 | + || ((uintptr_t) ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff) | |
360 | & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0) | |
361 | notcvt = (ElfW2(LIBELFBITS,Shdr) *) | |
362 | ((char *) elf->map_address | |
363 | @@ -134,6 +137,7 @@ | |
364 | CONVERT_TO (shdr[cnt].sh_addralign, notcvt[cnt].sh_addralign); | |
365 | CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize); | |
366 | } | |
367 | + } | |
368 | } | |
369 | else if (likely (elf->fildes != -1)) | |
370 | { |