]>
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. | |
96b9de17 JB |
6 | * libelf/elf32_getshdr.c: Fix assert condition; handle unaligned |
7 | section header with same endianess properly. | |
8 | ||
9 | --- elfutils-0.116/src/elflint.c.orig 2005-11-26 10:28:00.000000000 +0100 | |
10 | +++ elfutils-0.116/src/elflint.c 2005-11-26 14:01:18.000000000 +0100 | |
11 | @@ -331,7 +331,7 @@ | |
12 | EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, | |
13 | EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, | |
14 | EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, | |
15 | - EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA | |
16 | + EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA | |
17 | }; | |
18 | #define nvalid_e_machine \ | |
19 | (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) | |
20 | @@ -1664,6 +1664,16 @@ | |
21 | section [%2d] '%s': hash table not for dynamic symbol table\n"), | |
22 | idx, section_name (ebl, idx)); | |
23 | ||
24 | + bool bighash = | |
25 | + (ehdr->e_machine == EM_ALPHA) || | |
26 | + ((ehdr->e_machine == EM_S390) && (ehdr->e_ident[EI_CLASS] == ELFCLASS64)); | |
27 | + | |
28 | + if (bighash) { | |
29 | + if (shdr->sh_entsize != 8) /* alpha and s390x use non-standard hash bucket size of 8 */ | |
30 | + ERROR (gettext ("\ | |
31 | +section [%2d] '%s': entry size is not 8\n"), | |
32 | + idx, section_name (ebl, idx)); | |
33 | + } else | |
34 | if (shdr->sh_entsize != sizeof (Elf32_Word)) | |
35 | ERROR (gettext ("\ | |
36 | section [%2d] '%s': entry size does not match Elf32_Word\n"), | |
37 | @@ -1681,8 +1691,15 @@ | |
38 | return; | |
39 | } | |
40 | ||
41 | - Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; | |
42 | - Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; | |
43 | + uint64_t nbucket, nchain; | |
44 | + | |
45 | + if (bighash) { | |
46 | + nbucket = ((Elf64_Xword *) data->d_buf)[0]; | |
47 | + nchain = ((Elf64_Xword *) data->d_buf)[1]; | |
48 | + } else { | |
49 | + nbucket = ((Elf32_Word *) data->d_buf)[0]; | |
50 | + nchain = ((Elf32_Word *) data->d_buf)[1]; | |
51 | + } | |
52 | ||
53 | if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) | |
54 | ERROR (gettext ("\ | |
55 | @@ -1694,29 +1711,41 @@ | |
56 | { | |
57 | size_t symsize = symshdr->sh_size / symshdr->sh_entsize; | |
58 | size_t cnt; | |
59 | - Elf32_Word *buf, *end; | |
60 | + void *buf, *end; | |
61 | + uint64_t val; | |
62 | ||
63 | if (nchain < symshdr->sh_size / symshdr->sh_entsize) | |
64 | ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"), | |
65 | idx, section_name (ebl, idx)); | |
66 | ||
67 | + if (bighash) { | |
68 | + buf = ((Elf64_Xword *) data->d_buf) + 2; | |
69 | + end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size); | |
70 | + } else { | |
71 | buf = ((Elf32_Word *) data->d_buf) + 2; | |
72 | end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size); | |
73 | - for (cnt = 2; cnt < 2 + nbucket; ++cnt) | |
74 | + } | |
75 | + for (cnt = 2; cnt < 2 + nbucket; ++cnt) { | |
76 | if (buf >= end) | |
77 | return; | |
78 | - else if (*buf++ >= symsize) | |
79 | + val = bighash ? *(Elf64_Xword *)buf : *(Elf32_Word *)buf; | |
80 | + if (val >= symsize) | |
81 | ERROR (gettext ("\ | |
82 | section [%2d] '%s': hash bucket reference %zu out of bounds\n"), | |
83 | idx, section_name (ebl, idx), cnt - 2); | |
84 | + buf += bighash ? 8 : sizeof(Elf32_Word); | |
85 | + } | |
86 | ||
87 | - for (; cnt < 2 + nbucket + nchain; ++cnt) | |
88 | + for (; cnt < 2 + nbucket + nchain; ++cnt) { | |
89 | if (buf >= end) | |
90 | return; | |
91 | - else if (*buf++ >= symsize) | |
92 | + val = bighash ? *(Elf64_Xword *)buf : *(Elf32_Word *)buf; | |
93 | + if (val >= symsize) | |
94 | ERROR (gettext ("\ | |
95 | section [%2d] '%s': hash chain reference %zu out of bounds\n"), | |
96 | idx, section_name (ebl, idx), cnt - 2 - nbucket); | |
97 | + buf += bighash ? 8 : sizeof(Elf32_Word); | |
98 | + } | |
99 | } | |
100 | } | |
101 | ||
102 | @@ -2744,9 +2773,30 @@ | |
103 | cnt, section_name (ebl, cnt), | |
104 | (int) shdr->sh_type); | |
105 | ||
106 | -#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ | |
107 | +#define GALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ | |
108 | | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ | |
109 | | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) | |
110 | + uint64_t ALL_SH_FLAGS = GALL_SH_FLAGS; /* generic */ | |
111 | + switch (ehdr->e_machine) { | |
112 | + case EM_MIPS: | |
113 | + ALL_SH_FLAGS |= SHF_MIPS_GPREL | SHF_MIPS_MERGE | SHF_MIPS_ADDR | | |
114 | + SHF_MIPS_STRINGS | SHF_MIPS_NOSTRIP | SHF_MIPS_LOCAL | | |
115 | + SHF_MIPS_NAMES | SHF_MIPS_NODUPE; | |
116 | + break; | |
117 | + case EM_PARISC: | |
118 | + ALL_SH_FLAGS |= SHF_PARISC_SHORT | SHF_PARISC_HUGE | SHF_PARISC_SBP; | |
119 | + break; | |
120 | + case EM_ALPHA: | |
121 | + ALL_SH_FLAGS |= SHF_ALPHA_GPREL; | |
122 | + break; | |
123 | + case EM_ARM: | |
124 | + ALL_SH_FLAGS |= SHF_ARM_ENTRYSECT | SHF_ARM_COMDEF; | |
125 | + break; | |
126 | + case EM_IA_64: | |
127 | + ALL_SH_FLAGS |= SHF_IA_64_SHORT | SHF_IA_64_NORECOV; | |
128 | + break; | |
129 | + } | |
130 | + | |
131 | if (shdr->sh_flags & ~ALL_SH_FLAGS) | |
132 | ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" | |
133 | " %#" PRIx64 "\n"), | |
96b9de17 JB |
134 | --- elfutils-0.116/libelf/elf32_getshdr.c.orig 2005-11-26 10:28:00.000000000 +0100 |
135 | +++ elfutils-0.116/libelf/elf32_getshdr.c 2005-11-26 20:52:02.000000000 +0100 | |
136 | @@ -91,8 +91,8 @@ | |
137 | /* All the data is already mapped. If we could use it | |
138 | directly this would already have happened. */ | |
139 | assert (ehdr->e_ident[EI_DATA] != MY_ELFDATA | |
140 | - || (! ALLOW_UNALIGNED | |
141 | - && (ehdr->e_shoff | |
142 | + || ((! ALLOW_UNALIGNED) | |
143 | + && ((uintptr_t) ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff) | |
144 | & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0)); | |
145 | ||
146 | /* First see whether the information in the ELF header is | |
147 | @@ -106,9 +106,12 @@ | |
148 | } | |
149 | ||
150 | /* Now copy the data and at the same time convert the byte | |
151 | - order. */ | |
152 | + order, if needed. */ | |
153 | + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) | |
154 | + memcpy (shdr, ((char*) elf->map_address + elf->start_offset + ehdr->e_shoff), size); | |
155 | + else { | |
156 | if (ALLOW_UNALIGNED | |
157 | - || (ehdr->e_shoff | |
158 | + || ((uintptr_t) ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff) | |
159 | & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0) | |
160 | notcvt = (ElfW2(LIBELFBITS,Shdr) *) | |
161 | ((char *) elf->map_address | |
162 | @@ -134,6 +137,7 @@ | |
163 | CONVERT_TO (shdr[cnt].sh_addralign, notcvt[cnt].sh_addralign); | |
164 | CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize); | |
165 | } | |
166 | + } | |
167 | } | |
168 | else if (likely (elf->fildes != -1)) | |
169 | { |