1 /*
2 * cook.c - read and translate ELF files.
3 * Copyright (C) 1995 - 2006 Michael Riepe
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include <private.h>
21
22 #ifndef lint
23 static const char rcsid[] = "@(#) $Id: cook.c,v 1.29 2008/05/23 08:15:34 michael Exp $";
24 #endif /* lint */
25
26 const Elf_Scn _elf_scn_init = INIT_SCN;
27 const Scn_Data _elf_data_init = INIT_DATA;
28
29 Elf_Type
_elf_scn_type(unsigned t)30 _elf_scn_type(unsigned t) {
31 switch (t) {
32 case SHT_DYNAMIC: return ELF_T_DYN;
33 case SHT_DYNSYM: return ELF_T_SYM;
34 case SHT_HASH: return ELF_T_WORD;
35 case SHT_REL: return ELF_T_REL;
36 case SHT_RELA: return ELF_T_RELA;
37 case SHT_SYMTAB: return ELF_T_SYM;
38 case SHT_SYMTAB_SHNDX: return ELF_T_WORD; /* XXX: really? */
39 #if __LIBELF_SYMBOL_VERSIONS
40 #if __LIBELF_SUN_SYMBOL_VERSIONS
41 case SHT_SUNW_verdef: return ELF_T_VDEF;
42 case SHT_SUNW_verneed: return ELF_T_VNEED;
43 case SHT_SUNW_versym: return ELF_T_HALF;
44 #else /* __LIBELF_SUN_SYMBOL_VERSIONS */
45 case SHT_GNU_verdef: return ELF_T_VDEF;
46 case SHT_GNU_verneed: return ELF_T_VNEED;
47 case SHT_GNU_versym: return ELF_T_HALF;
48 #endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
49 #endif /* __LIBELF_SYMBOL_VERSIONS */
50 }
51 return ELF_T_BYTE;
52 }
53
54 /*
55 * Check for overflow on 32-bit systems
56 */
57 #define overflow(a,b,t) (sizeof(a) < sizeof(t) && (t)(a) != (b))
58
59 #define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR: \
60 ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR: \
61 ERROR_INTERNAL))
62 #define memerr(t) ((t)==ELF_T_EHDR?ERROR_MEM_EHDR: \
63 ((t)==ELF_T_PHDR?ERROR_MEM_PHDR: \
64 ERROR_INTERNAL))
65
66 Elf_Data*
_elf_xlatetom(const Elf * elf,Elf_Data * dst,const Elf_Data * src)67 _elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) {
68 if (elf->e_class == ELFCLASS32) {
69 return elf32_xlatetom(dst, src, elf->e_encoding);
70 }
71 #if __LIBELF64
72 else if (elf->e_class == ELFCLASS64) {
73 return elf64_xlatetom(dst, src, elf->e_encoding);
74 }
75 #endif /* __LIBELF64 */
76 seterr(ERROR_UNIMPLEMENTED);
77 return NULL;
78 }
79
80 static char*
_elf_item(void * buf,Elf * elf,Elf_Type type,size_t off)81 _elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) {
82 Elf_Data src, dst;
83
84 elf_assert(valid_type(type));
85 if (off < 0 || off > elf->e_size) {
86 seterr(ERROR_OUTSIDE);
87 return NULL;
88 }
89
90 src.d_type = type;
91 src.d_version = elf->e_version;
92 src.d_size = _fsize(elf->e_class, src.d_version, type);
93 elf_assert(src.d_size);
94 if ((elf->e_size - off) < src.d_size) {
95 seterr(truncerr(type));
96 return NULL;
97 }
98
99 dst.d_version = _elf_version;
100 dst.d_size = _msize(elf->e_class, dst.d_version, type);
101 elf_assert(dst.d_size);
102
103 if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) {
104 seterr(memerr(type));
105 return NULL;
106 }
107
108 elf_assert(elf->e_data);
109 if (elf->e_rawdata) {
110 src.d_buf = elf->e_rawdata + off;
111 }
112 else {
113 src.d_buf = elf->e_data + off;
114 }
115
116 if (_elf_xlatetom(elf, &dst, &src)) {
117 return (char*)dst.d_buf;
118 }
119 if (dst.d_buf != buf) {
120 free(dst.d_buf);
121 }
122 return NULL;
123 }
124
125 static int
_elf_cook_phdr(Elf * elf)126 _elf_cook_phdr(Elf *elf) {
127 size_t num, off, entsz;
128
129 if (elf->e_class == ELFCLASS32) {
130 num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum;
131 off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff;
132 entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize;
133 }
134 #if __LIBELF64
135 else if (elf->e_class == ELFCLASS64) {
136 num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum;
137 off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff;
138 entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize;
139 /*
140 * Check for overflow on 32-bit systems
141 */
142 if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) {
143 seterr(ERROR_OUTSIDE);
144 return 0;
145 }
146 }
147 #endif /* __LIBELF64 */
148 else {
149 seterr(ERROR_UNIMPLEMENTED);
150 return 0;
151 }
152 if (off) {
153 Elf_Scn *scn;
154 size_t size;
155 unsigned i;
156 char *p;
157
158 if (num == PN_XNUM) {
159 /*
160 * Overflow in ehdr->e_phnum.
161 * Get real value from first SHDR.
162 */
163 if (!(scn = elf->e_scn_1)) {
164 seterr(ERROR_NOSUCHSCN);
165 return 0;
166 }
167 if (elf->e_class == ELFCLASS32) {
168 num = scn->s_shdr32.sh_info;
169 }
170 #if __LIBELF64
171 else if (elf->e_class == ELFCLASS64) {
172 num = scn->s_shdr64.sh_info;
173 }
174 #endif /* __LIBELF64 */
175 /* we already had this
176 else {
177 seterr(ERROR_UNIMPLEMENTED);
178 return 0;
179 }
180 */
181 }
182
183 size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR);
184 elf_assert(size);
185 #if ENABLE_EXTENDED_FORMAT
186 if (entsz < size) {
187 #else /* ENABLE_EXTENDED_FORMAT */
188 if (entsz != size) {
189 #endif /* ENABLE_EXTENDED_FORMAT */
190 seterr(ERROR_EHDR_PHENTSIZE);
191 return 0;
192 }
193 size = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
194 elf_assert(size);
195 if (!(p = malloc(num * size))) {
196 seterr(memerr(ELF_T_PHDR));
197 return 0;
198 }
199 for (i = 0; i < num; i++) {
200 if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) {
201 free(p);
202 return 0;
203 }
204 }
205 elf->e_phdr = p;
206 elf->e_phnum = num;
207 }
208 return 1;
209 }
210
211 static int
212 _elf_cook_shdr(Elf *elf) {
213 size_t num, off, entsz;
214
215 if (elf->e_class == ELFCLASS32) {
216 num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum;
217 off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff;
218 entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize;
219 }
220 #if __LIBELF64
221 else if (elf->e_class == ELFCLASS64) {
222 num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum;
223 off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff;
224 entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize;
225 /*
226 * Check for overflow on 32-bit systems
227 */
228 if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) {
229 seterr(ERROR_OUTSIDE);
230 return 0;
231 }
232 }
233 #endif /* __LIBELF64 */
234 else {
235 seterr(ERROR_UNIMPLEMENTED);
236 return 0;
237 }
238 if (off) {
239 struct tmp {
240 Elf_Scn scn;
241 Scn_Data data;
242 } *head;
243 Elf_Data src, dst;
244 Elf_Scn *scn;
245 Scn_Data *sd;
246 unsigned i;
247
248 if (off < 0 || off > elf->e_size) {
249 seterr(ERROR_OUTSIDE);
250 return 0;
251 }
252
253 src.d_type = ELF_T_SHDR;
254 src.d_version = elf->e_version;
255 src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR);
256 elf_assert(src.d_size);
257 #if ENABLE_EXTENDED_FORMAT
258 if (entsz < src.d_size) {
259 #else /* ENABLE_EXTENDED_FORMAT */
260 if (entsz != src.d_size) {
261 #endif /* ENABLE_EXTENDED_FORMAT */
262 seterr(ERROR_EHDR_SHENTSIZE);
263 return 0;
264 }
265 dst.d_version = EV_CURRENT;
266
267 if (num == 0) {
268 union {
269 Elf32_Shdr sh32;
270 #if __LIBELF64
271 Elf64_Shdr sh64;
272 #endif /* __LIBELF64 */
273 } u;
274
275 /*
276 * Overflow in ehdr->e_shnum.
277 * Get real value from first SHDR.
278 */
279 if (elf->e_size - off < entsz) {
280 seterr(ERROR_TRUNC_SHDR);
281 return 0;
282 }
283 if (elf->e_rawdata) {
284 src.d_buf = elf->e_rawdata + off;
285 }
286 else {
287 src.d_buf = elf->e_data + off;
288 }
289 dst.d_buf = &u;
290 dst.d_size = sizeof(u);
291 if (!_elf_xlatetom(elf, &dst, &src)) {
292 return 0;
293 }
294 elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
295 elf_assert(dst.d_type == ELF_T_SHDR);
296 if (elf->e_class == ELFCLASS32) {
297 num = u.sh32.sh_size;
298 }
299 #if __LIBELF64
300 else if (elf->e_class == ELFCLASS64) {
301 num = u.sh64.sh_size;
302 /*
303 * Check for overflow on 32-bit systems
304 */
305 if (overflow(num, u.sh64.sh_size, Elf64_Xword)) {
306 seterr(ERROR_OUTSIDE);
307 return 0;
308 }
309 }
310 #endif /* __LIBELF64 */
311 }
312
313 if ((elf->e_size - off) / entsz < num) {
314 seterr(ERROR_TRUNC_SHDR);
315 return 0;
316 }
317
318 if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) {
319 seterr(ERROR_MEM_SCN);
320 return 0;
321 }
322 for (scn = NULL, i = num; i-- > 0; ) {
323 head[i].scn = _elf_scn_init;
324 head[i].data = _elf_data_init;
325 head[i].scn.s_link = scn;
326 if (!scn) {
327 elf->e_scn_n = &head[i].scn;
328 }
329 scn = &head[i].scn;
330 sd = &head[i].data;
331
332 if (elf->e_rawdata) {
333 src.d_buf = elf->e_rawdata + off + i * entsz;
334 }
335 else {
336 src.d_buf = elf->e_data + off + i * entsz;
337 }
338 dst.d_buf = &scn->s_uhdr;
339 dst.d_size = sizeof(scn->s_uhdr);
340 if (!_elf_xlatetom(elf, &dst, &src)) {
341 elf->e_scn_n = NULL;
342 free(head);
343 return 0;
344 }
345 elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
346 elf_assert(dst.d_type == ELF_T_SHDR);
347
348 scn->s_elf = elf;
349 scn->s_index = i;
350 scn->s_data_1 = sd;
351 scn->s_data_n = sd;
352
353 sd->sd_scn = scn;
354
355 if (elf->e_class == ELFCLASS32) {
356 Elf32_Shdr *shdr = &scn->s_shdr32;
357
358 scn->s_type = shdr->sh_type;
359 scn->s_size = shdr->sh_size;
360 scn->s_offset = shdr->sh_offset;
361 sd->sd_data.d_align = shdr->sh_addralign;
362 sd->sd_data.d_type = _elf_scn_type(scn->s_type);
363 }
364 #if __LIBELF64
365 else if (elf->e_class == ELFCLASS64) {
366 Elf64_Shdr *shdr = &scn->s_shdr64;
367
368 scn->s_type = shdr->sh_type;
369 scn->s_size = shdr->sh_size;
370 scn->s_offset = shdr->sh_offset;
371 sd->sd_data.d_align = shdr->sh_addralign;
372 /*
373 * Check for overflow on 32-bit systems
374 */
375 if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword)
376 || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off)
377 || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) {
378 seterr(ERROR_OUTSIDE);
379 return 0;
380 }
381 sd->sd_data.d_type = _elf_scn_type(scn->s_type);
382 /*
383 * QUIRKS MODE:
384 *
385 * Some 64-bit architectures use 64-bit entries in the
386 * .hash section. This violates the ELF standard, and
387 * should be fixed. It's mostly harmless as long as the
388 * binary and the machine running your program have the
389 * same byte order, but you're in trouble if they don't,
390 * and if the entry size is wrong.
391 *
392 * As a workaround, I let libelf guess the right size
393 * for the binary. This relies pretty much on the fact
394 * that the binary provides correct data in the section
395 * headers. If it doesn't, it's probably broken anyway.
396 * Therefore, libelf uses a standard conforming value
397 * when it's not absolutely sure.
398 */
399 if (scn->s_type == SHT_HASH) {
400 int override = 0;
401
402 /*
403 * sh_entsize must reflect the entry size
404 */
405 if (shdr->sh_entsize == ELF64_FSZ_ADDR) {
406 override++;
407 }
408 /*
409 * sh_size must be a multiple of sh_entsize
410 */
411 if (shdr->sh_size % ELF64_FSZ_ADDR == 0) {
412 override++;
413 }
414 /*
415 * There must be room for at least 2 entries
416 */
417 if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) {
418 override++;
419 }
420 /*
421 * sh_addralign must be correctly set
422 */
423 if (shdr->sh_addralign == ELF64_FSZ_ADDR) {
424 override++;
425 }
426 /*
427 * The section must be properly aligned
428 */
429 if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) {
430 override++;
431 }
432 /* XXX: also look at the data? */
433 /*
434 * Make a conservative decision...
435 */
436 if (override >= 5) {
437 sd->sd_data.d_type = ELF_T_ADDR;
438 }
439 }
440 /*
441 * END QUIRKS MODE.
442 */
443 }
444 #endif /* __LIBELF64 */
445 /* we already had this
446 else {
447 seterr(ERROR_UNIMPLEMENTED);
448 return 0;
449 }
450 */
451
452 sd->sd_data.d_size = scn->s_size;
453 sd->sd_data.d_version = _elf_version;
454 }
455 elf_assert(scn == &head[0].scn);
456 elf->e_scn_1 = &head[0].scn;
457 head[0].scn.s_freeme = 1;
458 }
459 return 1;
460 }
461
462 static int
463 _elf_cook_file(Elf *elf) {
464 elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0);
465 if (!elf->e_ehdr) {
466 return 0;
467 }
468 /*
469 * Note: _elf_cook_phdr may require the first section header!
470 */
471 if (!_elf_cook_shdr(elf)) {
472 return 0;
473 }
474 if (!_elf_cook_phdr(elf)) {
475 return 0;
476 }
477 return 1;
478 }
479
480 int
481 _elf_cook(Elf *elf) {
482 elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
483 elf_assert(_elf_data_init.sd_magic == DATA_MAGIC);
484 elf_assert(elf);
485 elf_assert(elf->e_magic == ELF_MAGIC);
486 elf_assert(elf->e_kind == ELF_K_ELF);
487 elf_assert(!elf->e_ehdr);
488 if (!valid_version(elf->e_version)) {
489 seterr(ERROR_UNKNOWN_VERSION);
490 }
491 else if (!valid_encoding(elf->e_encoding)) {
492 seterr(ERROR_UNKNOWN_ENCODING);
493 }
494 else if (valid_class(elf->e_class)) {
495 return _elf_cook_file(elf);
496 }
497 else {
498 seterr(ERROR_UNKNOWN_CLASS);
499 }
500 return 0;
501 }
502