2013-11-13 Christophe Lyon <christophe.lyon@linaro.org>
[official-gcc.git] / libiberty / simple-object-elf.c
blob4196c537cde5820ca536be6edd407525b0ca8671
1 /* simple-object-elf.c -- routines to manipulate ELF object files.
2 Copyright 2010 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Google.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
8 later version.
10 This program 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
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 51 Franklin Street - Fifth Floor,
18 Boston, MA 02110-1301, USA. */
20 #include "config.h"
21 #include "libiberty.h"
22 #include "simple-object.h"
24 #include <errno.h>
25 #include <stddef.h>
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
31 #ifdef HAVE_STDINT_H
32 #include <stdint.h>
33 #endif
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
39 #ifdef HAVE_INTTYPES_H
40 #include <inttypes.h>
41 #endif
43 #include "simple-object-common.h"
45 /* ELF structures and constants. */
47 /* 32-bit ELF file header. */
49 typedef struct {
50 unsigned char e_ident[16]; /* ELF "magic number" */
51 unsigned char e_type[2]; /* Identifies object file type */
52 unsigned char e_machine[2]; /* Specifies required architecture */
53 unsigned char e_version[4]; /* Identifies object file version */
54 unsigned char e_entry[4]; /* Entry point virtual address */
55 unsigned char e_phoff[4]; /* Program header table file offset */
56 unsigned char e_shoff[4]; /* Section header table file offset */
57 unsigned char e_flags[4]; /* Processor-specific flags */
58 unsigned char e_ehsize[2]; /* ELF header size in bytes */
59 unsigned char e_phentsize[2]; /* Program header table entry size */
60 unsigned char e_phnum[2]; /* Program header table entry count */
61 unsigned char e_shentsize[2]; /* Section header table entry size */
62 unsigned char e_shnum[2]; /* Section header table entry count */
63 unsigned char e_shstrndx[2]; /* Section header string table index */
64 } Elf32_External_Ehdr;
66 /* 64-bit ELF file header. */
68 typedef struct {
69 unsigned char e_ident[16]; /* ELF "magic number" */
70 unsigned char e_type[2]; /* Identifies object file type */
71 unsigned char e_machine[2]; /* Specifies required architecture */
72 unsigned char e_version[4]; /* Identifies object file version */
73 unsigned char e_entry[8]; /* Entry point virtual address */
74 unsigned char e_phoff[8]; /* Program header table file offset */
75 unsigned char e_shoff[8]; /* Section header table file offset */
76 unsigned char e_flags[4]; /* Processor-specific flags */
77 unsigned char e_ehsize[2]; /* ELF header size in bytes */
78 unsigned char e_phentsize[2]; /* Program header table entry size */
79 unsigned char e_phnum[2]; /* Program header table entry count */
80 unsigned char e_shentsize[2]; /* Section header table entry size */
81 unsigned char e_shnum[2]; /* Section header table entry count */
82 unsigned char e_shstrndx[2]; /* Section header string table index */
83 } Elf64_External_Ehdr;
85 /* Indexes and values in e_ident field of Ehdr. */
87 #define EI_MAG0 0 /* File identification byte 0 index */
88 #define ELFMAG0 0x7F /* Magic number byte 0 */
90 #define EI_MAG1 1 /* File identification byte 1 index */
91 #define ELFMAG1 'E' /* Magic number byte 1 */
93 #define EI_MAG2 2 /* File identification byte 2 index */
94 #define ELFMAG2 'L' /* Magic number byte 2 */
96 #define EI_MAG3 3 /* File identification byte 3 index */
97 #define ELFMAG3 'F' /* Magic number byte 3 */
99 #define EI_CLASS 4 /* File class */
100 #define ELFCLASSNONE 0 /* Invalid class */
101 #define ELFCLASS32 1 /* 32-bit objects */
102 #define ELFCLASS64 2 /* 64-bit objects */
104 #define EI_DATA 5 /* Data encoding */
105 #define ELFDATANONE 0 /* Invalid data encoding */
106 #define ELFDATA2LSB 1 /* 2's complement, little endian */
107 #define ELFDATA2MSB 2 /* 2's complement, big endian */
109 #define EI_VERSION 6 /* File version */
110 #define EV_CURRENT 1 /* Current version */
112 #define EI_OSABI 7 /* Operating System/ABI indication */
114 /* Values for e_type field of Ehdr. */
116 #define ET_REL 1 /* Relocatable file */
118 /* Values for e_machine field of Ehdr. */
120 #define EM_SPARC 2 /* SUN SPARC */
121 #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
123 /* Special section index values. */
125 #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
126 #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
128 /* 32-bit ELF program header. */
130 typedef struct {
131 unsigned char p_type[4]; /* Identifies program segment type */
132 unsigned char p_offset[4]; /* Segment file offset */
133 unsigned char p_vaddr[4]; /* Segment virtual address */
134 unsigned char p_paddr[4]; /* Segment physical address */
135 unsigned char p_filesz[4]; /* Segment size in file */
136 unsigned char p_memsz[4]; /* Segment size in memory */
137 unsigned char p_flags[4]; /* Segment flags */
138 unsigned char p_align[4]; /* Segment alignment, file & memory */
139 } Elf32_External_Phdr;
141 /* 64-bit ELF program header. */
143 typedef struct {
144 unsigned char p_type[4]; /* Identifies program segment type */
145 unsigned char p_flags[4]; /* Segment flags */
146 unsigned char p_offset[8]; /* Segment file offset */
147 unsigned char p_vaddr[8]; /* Segment virtual address */
148 unsigned char p_paddr[8]; /* Segment physical address */
149 unsigned char p_filesz[8]; /* Segment size in file */
150 unsigned char p_memsz[8]; /* Segment size in memory */
151 unsigned char p_align[8]; /* Segment alignment, file & memory */
152 } Elf64_External_Phdr;
154 /* 32-bit ELF section header */
156 typedef struct {
157 unsigned char sh_name[4]; /* Section name, index in string tbl */
158 unsigned char sh_type[4]; /* Type of section */
159 unsigned char sh_flags[4]; /* Miscellaneous section attributes */
160 unsigned char sh_addr[4]; /* Section virtual addr at execution */
161 unsigned char sh_offset[4]; /* Section file offset */
162 unsigned char sh_size[4]; /* Size of section in bytes */
163 unsigned char sh_link[4]; /* Index of another section */
164 unsigned char sh_info[4]; /* Additional section information */
165 unsigned char sh_addralign[4]; /* Section alignment */
166 unsigned char sh_entsize[4]; /* Entry size if section holds table */
167 } Elf32_External_Shdr;
169 /* 64-bit ELF section header. */
171 typedef struct {
172 unsigned char sh_name[4]; /* Section name, index in string tbl */
173 unsigned char sh_type[4]; /* Type of section */
174 unsigned char sh_flags[8]; /* Miscellaneous section attributes */
175 unsigned char sh_addr[8]; /* Section virtual addr at execution */
176 unsigned char sh_offset[8]; /* Section file offset */
177 unsigned char sh_size[8]; /* Size of section in bytes */
178 unsigned char sh_link[4]; /* Index of another section */
179 unsigned char sh_info[4]; /* Additional section information */
180 unsigned char sh_addralign[8]; /* Section alignment */
181 unsigned char sh_entsize[8]; /* Entry size if section holds table */
182 } Elf64_External_Shdr;
184 /* Values for sh_type field. */
186 #define SHT_PROGBITS 1 /* Program data */
187 #define SHT_STRTAB 3 /* A string table */
189 /* Functions to fetch and store different ELF types, depending on the
190 endianness and size. */
192 struct elf_type_functions
194 unsigned short (*fetch_Elf_Half) (const unsigned char *);
195 unsigned int (*fetch_Elf_Word) (const unsigned char *);
196 ulong_type (*fetch_Elf_Addr) (const unsigned char *);
197 void (*set_Elf_Half) (unsigned char *, unsigned short);
198 void (*set_Elf_Word) (unsigned char *, unsigned int);
199 void (*set_Elf_Addr) (unsigned char *, ulong_type);
202 static const struct elf_type_functions elf_big_32_functions =
204 simple_object_fetch_big_16,
205 simple_object_fetch_big_32,
206 simple_object_fetch_big_32_ulong,
207 simple_object_set_big_16,
208 simple_object_set_big_32,
209 simple_object_set_big_32_ulong
212 static const struct elf_type_functions elf_little_32_functions =
214 simple_object_fetch_little_16,
215 simple_object_fetch_little_32,
216 simple_object_fetch_little_32_ulong,
217 simple_object_set_little_16,
218 simple_object_set_little_32,
219 simple_object_set_little_32_ulong
222 #ifdef UNSIGNED_64BIT_TYPE
224 static const struct elf_type_functions elf_big_64_functions =
226 simple_object_fetch_big_16,
227 simple_object_fetch_big_32,
228 simple_object_fetch_big_64,
229 simple_object_set_big_16,
230 simple_object_set_big_32,
231 simple_object_set_big_64
234 static const struct elf_type_functions elf_little_64_functions =
236 simple_object_fetch_little_16,
237 simple_object_fetch_little_32,
238 simple_object_fetch_little_64,
239 simple_object_set_little_16,
240 simple_object_set_little_32,
241 simple_object_set_little_64
244 #endif
246 /* Hideous macro to fetch the value of a field from an external ELF
247 struct of some sort. TYPEFUNCS is the set of type functions.
248 BUFFER points to the external data. STRUCTTYPE is the appropriate
249 struct type. FIELD is a field within the struct. TYPE is the type
250 of the field in the struct: Elf_Half, Elf_Word, or Elf_Addr. */
252 #define ELF_FETCH_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE) \
253 ((TYPEFUNCS)->fetch_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD)))
255 /* Even more hideous macro to fetch the value of FIELD from BUFFER.
256 SIZE is 32 or 64. STRUCTTYPE is the name of the struct from
257 elf/external.h: Ehdr, Shdr, etc. FIELD is the name of a field in
258 the struct. TYPE is the type of the field in the struct: Elf_Half,
259 Elf_Word, or Elf_Addr. */
261 #define ELF_FETCH_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER, \
262 FIELD, TYPE) \
263 ELF_FETCH_STRUCT_FIELD (TYPEFUNCS, \
264 Elf ## SIZE ## _External_ ## STRUCTTYPE, \
265 FIELD, BUFFER, TYPE)
267 /* Like ELF_FETCH_SIZED_FIELD but taking an ELFCLASS value. */
269 #define ELF_FETCH_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER, \
270 FIELD, TYPE) \
271 ((CLASS) == ELFCLASS32 \
272 ? ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD, \
273 TYPE) \
274 : ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD, \
275 TYPE))
277 /* Hideous macro to set the value of a field in an external ELF
278 structure to VAL. TYPEFUNCS is the set of type functions. BUFFER
279 points to the external data. STRUCTTYPE is the appropriate
280 structure type. FIELD is a field within the struct. TYPE is the
281 type of the field in the struct: Elf_Half, Elf_Word, or
282 Elf_Addr. */
284 #define ELF_SET_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE, VAL) \
285 (TYPEFUNCS)->set_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD), (VAL))
287 /* Even more hideous macro to set the value of FIELD in BUFFER to VAL.
288 SIZE is 32 or 64. STRUCTTYPE is the name of the struct from
289 elf/external.h: Ehdr, Shdr, etc. FIELD is the name of a field in
290 the struct. TYPE is the type of the field in the struct: Elf_Half,
291 Elf_Word, or Elf_Addr. */
293 #define ELF_SET_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER, FIELD, \
294 TYPE, VAL) \
295 ELF_SET_STRUCT_FIELD (TYPEFUNCS, \
296 Elf ## SIZE ## _External_ ## STRUCTTYPE, \
297 FIELD, BUFFER, TYPE, VAL)
299 /* Like ELF_SET_SIZED_FIELD but taking an ELFCLASS value. */
301 #define ELF_SET_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER, FIELD, \
302 TYPE, VAL) \
303 ((CLASS) == ELFCLASS32 \
304 ? ELF_SET_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD, \
305 TYPE, VAL) \
306 : ELF_SET_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD, \
307 TYPE, VAL))
309 /* Private data for an simple_object_read. */
311 struct simple_object_elf_read
313 /* Type functions. */
314 const struct elf_type_functions* type_functions;
315 /* Elf data. */
316 unsigned char ei_data;
317 /* Elf class. */
318 unsigned char ei_class;
319 /* ELF OS ABI. */
320 unsigned char ei_osabi;
321 /* Elf machine number. */
322 unsigned short machine;
323 /* Processor specific flags. */
324 unsigned int flags;
325 /* File offset of section headers. */
326 ulong_type shoff;
327 /* Number of sections. */
328 unsigned int shnum;
329 /* Index of string table section header. */
330 unsigned int shstrndx;
333 /* Private data for an simple_object_attributes. */
335 struct simple_object_elf_attributes
337 /* Type functions. */
338 const struct elf_type_functions* type_functions;
339 /* Elf data. */
340 unsigned char ei_data;
341 /* Elf class. */
342 unsigned char ei_class;
343 /* ELF OS ABI. */
344 unsigned char ei_osabi;
345 /* Elf machine number. */
346 unsigned short machine;
347 /* Processor specific flags. */
348 unsigned int flags;
351 /* See if we have an ELF file. */
353 static void *
354 simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
355 int descriptor, off_t offset,
356 const char *segment_name ATTRIBUTE_UNUSED,
357 const char **errmsg, int *err)
359 unsigned char ei_data;
360 unsigned char ei_class;
361 const struct elf_type_functions *type_functions;
362 unsigned char ehdr[sizeof (Elf64_External_Ehdr)];
363 struct simple_object_elf_read *eor;
365 if (header[EI_MAG0] != ELFMAG0
366 || header[EI_MAG1] != ELFMAG1
367 || header[EI_MAG2] != ELFMAG2
368 || header[EI_MAG3] != ELFMAG3
369 || header[EI_VERSION] != EV_CURRENT)
371 *errmsg = NULL;
372 *err = 0;
373 return NULL;
376 ei_data = header[EI_DATA];
377 if (ei_data != ELFDATA2LSB && ei_data != ELFDATA2MSB)
379 *errmsg = "unknown ELF endianness";
380 *err = 0;
381 return NULL;
384 ei_class = header[EI_CLASS];
385 switch (ei_class)
387 case ELFCLASS32:
388 type_functions = (ei_data == ELFDATA2LSB
389 ? &elf_little_32_functions
390 : &elf_big_32_functions);
391 break;
393 case ELFCLASS64:
394 #ifndef UNSIGNED_64BIT_TYPE
395 *errmsg = "64-bit ELF objects not supported";
396 *err = 0;
397 return NULL;
398 #else
399 type_functions = (ei_data == ELFDATA2LSB
400 ? &elf_little_64_functions
401 : &elf_big_64_functions);
402 break;
403 #endif
405 default:
406 *errmsg = "unrecognized ELF size";
407 *err = 0;
408 return NULL;
411 if (!simple_object_internal_read (descriptor, offset, ehdr, sizeof ehdr,
412 errmsg, err))
413 return NULL;
415 eor = XNEW (struct simple_object_elf_read);
416 eor->type_functions = type_functions;
417 eor->ei_data = ei_data;
418 eor->ei_class = ei_class;
419 eor->ei_osabi = header[EI_OSABI];
420 eor->machine = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
421 e_machine, Elf_Half);
422 eor->flags = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
423 e_flags, Elf_Word);
424 eor->shoff = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
425 e_shoff, Elf_Addr);
426 eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
427 e_shnum, Elf_Half);
428 eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
429 e_shstrndx, Elf_Half);
431 if ((eor->shnum == 0 || eor->shstrndx == SHN_XINDEX)
432 && eor->shoff != 0)
434 unsigned char shdr[sizeof (Elf64_External_Shdr)];
436 /* Object file has more than 0xffff sections. */
438 if (!simple_object_internal_read (descriptor, offset + eor->shoff, shdr,
439 (ei_class == ELFCLASS32
440 ? sizeof (Elf32_External_Shdr)
441 : sizeof (Elf64_External_Shdr)),
442 errmsg, err))
444 XDELETE (eor);
445 return NULL;
448 if (eor->shnum == 0)
449 eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
450 shdr, sh_size, Elf_Addr);
452 if (eor->shstrndx == SHN_XINDEX)
454 eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
455 shdr, sh_link, Elf_Word);
457 /* Versions of the GNU binutils between 2.12 and 2.18 did
458 not handle objects with more than SHN_LORESERVE sections
459 correctly. All large section indexes were offset by
460 0x100. There is more information at
461 http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
462 Fortunately these object files are easy to detect, as the
463 GNU binutils always put the section header string table
464 near the end of the list of sections. Thus if the
465 section header string table index is larger than the
466 number of sections, then we know we have to subtract
467 0x100 to get the real section index. */
468 if (eor->shstrndx >= eor->shnum
469 && eor->shstrndx >= SHN_LORESERVE + 0x100)
470 eor->shstrndx -= 0x100;
474 if (eor->shstrndx >= eor->shnum)
476 *errmsg = "invalid ELF shstrndx >= shnum";
477 *err = 0;
478 XDELETE (eor);
479 return NULL;
482 return (void *) eor;
485 /* Find all sections in an ELF file. */
487 static const char *
488 simple_object_elf_find_sections (simple_object_read *sobj,
489 int (*pfn) (void *, const char *,
490 off_t offset, off_t length),
491 void *data,
492 int *err)
494 struct simple_object_elf_read *eor =
495 (struct simple_object_elf_read *) sobj->data;
496 const struct elf_type_functions *type_functions = eor->type_functions;
497 unsigned char ei_class = eor->ei_class;
498 size_t shdr_size;
499 unsigned int shnum;
500 unsigned char *shdrs;
501 const char *errmsg;
502 unsigned char *shstrhdr;
503 size_t name_size;
504 off_t shstroff;
505 unsigned char *names;
506 unsigned int i;
508 shdr_size = (ei_class == ELFCLASS32
509 ? sizeof (Elf32_External_Shdr)
510 : sizeof (Elf64_External_Shdr));
512 /* Read the section headers. We skip section 0, which is not a
513 useful section. */
515 shnum = eor->shnum;
516 shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
518 if (!simple_object_internal_read (sobj->descriptor,
519 sobj->offset + eor->shoff + shdr_size,
520 shdrs,
521 shdr_size * (shnum - 1),
522 &errmsg, err))
524 XDELETEVEC (shdrs);
525 return errmsg;
528 /* Read the section names. */
530 shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size;
531 name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
532 shstrhdr, sh_size, Elf_Addr);
533 shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
534 shstrhdr, sh_offset, Elf_Addr);
535 names = XNEWVEC (unsigned char, name_size);
536 if (!simple_object_internal_read (sobj->descriptor,
537 sobj->offset + shstroff,
538 names, name_size, &errmsg, err))
540 XDELETEVEC (names);
541 XDELETEVEC (shdrs);
542 return errmsg;
545 for (i = 1; i < shnum; ++i)
547 unsigned char *shdr;
548 unsigned int sh_name;
549 const char *name;
550 off_t offset;
551 off_t length;
553 shdr = shdrs + (i - 1) * shdr_size;
554 sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
555 shdr, sh_name, Elf_Word);
556 if (sh_name >= name_size)
558 *err = 0;
559 XDELETEVEC (names);
560 XDELETEVEC (shdrs);
561 return "ELF section name out of range";
564 name = (const char *) names + sh_name;
565 offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
566 shdr, sh_offset, Elf_Addr);
567 length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
568 shdr, sh_size, Elf_Addr);
570 if (!(*pfn) (data, name, offset, length))
571 break;
574 XDELETEVEC (names);
575 XDELETEVEC (shdrs);
577 return NULL;
580 /* Fetch the attributes for an simple_object_read. */
582 static void *
583 simple_object_elf_fetch_attributes (simple_object_read *sobj,
584 const char **errmsg ATTRIBUTE_UNUSED,
585 int *err ATTRIBUTE_UNUSED)
587 struct simple_object_elf_read *eor =
588 (struct simple_object_elf_read *) sobj->data;
589 struct simple_object_elf_attributes *ret;
591 ret = XNEW (struct simple_object_elf_attributes);
592 ret->type_functions = eor->type_functions;
593 ret->ei_data = eor->ei_data;
594 ret->ei_class = eor->ei_class;
595 ret->ei_osabi = eor->ei_osabi;
596 ret->machine = eor->machine;
597 ret->flags = eor->flags;
598 return ret;
601 /* Release the privata data for an simple_object_read. */
603 static void
604 simple_object_elf_release_read (void *data)
606 XDELETE (data);
609 /* Compare two attributes structures. */
611 static const char *
612 simple_object_elf_attributes_merge (void *todata, void *fromdata, int *err)
614 struct simple_object_elf_attributes *to =
615 (struct simple_object_elf_attributes *) todata;
616 struct simple_object_elf_attributes *from =
617 (struct simple_object_elf_attributes *) fromdata;
619 if (to->ei_data != from->ei_data || to->ei_class != from->ei_class)
621 *err = 0;
622 return "ELF object format mismatch";
625 if (to->machine != from->machine)
627 int ok;
629 /* EM_SPARC and EM_SPARC32PLUS are compatible and force an
630 output of EM_SPARC32PLUS. */
631 ok = 0;
632 switch (to->machine)
634 case EM_SPARC:
635 if (from->machine == EM_SPARC32PLUS)
637 to->machine = from->machine;
638 ok = 1;
640 break;
642 case EM_SPARC32PLUS:
643 if (from->machine == EM_SPARC)
644 ok = 1;
645 break;
647 default:
648 break;
651 if (!ok)
653 *err = 0;
654 return "ELF machine number mismatch";
658 return NULL;
661 /* Release the private data for an attributes structure. */
663 static void
664 simple_object_elf_release_attributes (void *data)
666 XDELETE (data);
669 /* Prepare to write out a file. */
671 static void *
672 simple_object_elf_start_write (void *attributes_data,
673 const char **errmsg ATTRIBUTE_UNUSED,
674 int *err ATTRIBUTE_UNUSED)
676 struct simple_object_elf_attributes *attrs =
677 (struct simple_object_elf_attributes *) attributes_data;
678 struct simple_object_elf_attributes *ret;
680 /* We're just going to record the attributes, but we need to make a
681 copy because the user may delete them. */
682 ret = XNEW (struct simple_object_elf_attributes);
683 *ret = *attrs;
684 return ret;
687 /* Write out an ELF ehdr. */
689 static int
690 simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
691 const char **errmsg, int *err)
693 struct simple_object_elf_attributes *attrs =
694 (struct simple_object_elf_attributes *) sobj->data;
695 const struct elf_type_functions* fns;
696 unsigned char cl;
697 size_t ehdr_size;
698 unsigned char buf[sizeof (Elf64_External_Ehdr)];
699 simple_object_write_section *section;
700 unsigned int shnum;
702 fns = attrs->type_functions;
703 cl = attrs->ei_class;
705 shnum = 0;
706 for (section = sobj->sections; section != NULL; section = section->next)
707 ++shnum;
708 if (shnum > 0)
710 /* Add a section header for the dummy section and one for
711 .shstrtab. */
712 shnum += 2;
715 ehdr_size = (cl == ELFCLASS32
716 ? sizeof (Elf32_External_Ehdr)
717 : sizeof (Elf64_External_Ehdr));
718 memset (buf, 0, sizeof (Elf64_External_Ehdr));
720 buf[EI_MAG0] = ELFMAG0;
721 buf[EI_MAG1] = ELFMAG1;
722 buf[EI_MAG2] = ELFMAG2;
723 buf[EI_MAG3] = ELFMAG3;
724 buf[EI_CLASS] = cl;
725 buf[EI_DATA] = attrs->ei_data;
726 buf[EI_VERSION] = EV_CURRENT;
727 buf[EI_OSABI] = attrs->ei_osabi;
729 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_type, Elf_Half, ET_REL);
730 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_machine, Elf_Half, attrs->machine);
731 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_version, Elf_Word, EV_CURRENT);
732 /* e_entry left as zero. */
733 /* e_phoff left as zero. */
734 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shoff, Elf_Addr, ehdr_size);
735 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_flags, Elf_Word, attrs->flags);
736 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_ehsize, Elf_Half, ehdr_size);
737 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_phentsize, Elf_Half,
738 (cl == ELFCLASS32
739 ? sizeof (Elf32_External_Phdr)
740 : sizeof (Elf64_External_Phdr)));
741 /* e_phnum left as zero. */
742 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half,
743 (cl == ELFCLASS32
744 ? sizeof (Elf32_External_Shdr)
745 : sizeof (Elf64_External_Shdr)));
746 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, shnum);
747 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half,
748 shnum == 0 ? 0 : shnum - 1);
750 return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
751 errmsg, err);
754 /* Write out an ELF shdr. */
756 static int
757 simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
758 off_t offset, unsigned int sh_name,
759 unsigned int sh_type, unsigned int sh_flags,
760 unsigned int sh_offset, unsigned int sh_size,
761 unsigned int sh_addralign, const char **errmsg,
762 int *err)
764 struct simple_object_elf_attributes *attrs =
765 (struct simple_object_elf_attributes *) sobj->data;
766 const struct elf_type_functions* fns;
767 unsigned char cl;
768 size_t shdr_size;
769 unsigned char buf[sizeof (Elf64_External_Shdr)];
771 fns = attrs->type_functions;
772 cl = attrs->ei_class;
774 shdr_size = (cl == ELFCLASS32
775 ? sizeof (Elf32_External_Shdr)
776 : sizeof (Elf64_External_Shdr));
777 memset (buf, 0, sizeof (Elf64_External_Shdr));
779 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name);
780 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type);
781 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
782 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
783 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
784 /* sh_link left as zero. */
785 /* sh_info left as zero. */
786 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
787 /* sh_entsize left as zero. */
789 return simple_object_internal_write (descriptor, offset, buf, shdr_size,
790 errmsg, err);
793 /* Write out a complete ELF file.
794 Ehdr
795 initial dummy Shdr
796 user-created Shdrs
797 .shstrtab Shdr
798 user-created section data
799 .shstrtab data */
801 static const char *
802 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
803 int *err)
805 struct simple_object_elf_attributes *attrs =
806 (struct simple_object_elf_attributes *) sobj->data;
807 unsigned char cl;
808 size_t ehdr_size;
809 size_t shdr_size;
810 const char *errmsg;
811 simple_object_write_section *section;
812 unsigned int shnum;
813 size_t shdr_offset;
814 size_t sh_offset;
815 size_t sh_name;
816 unsigned char zero;
818 if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err))
819 return errmsg;
821 cl = attrs->ei_class;
822 if (cl == ELFCLASS32)
824 ehdr_size = sizeof (Elf32_External_Ehdr);
825 shdr_size = sizeof (Elf32_External_Shdr);
827 else
829 ehdr_size = sizeof (Elf64_External_Ehdr);
830 shdr_size = sizeof (Elf64_External_Shdr);
833 shnum = 0;
834 for (section = sobj->sections; section != NULL; section = section->next)
835 ++shnum;
836 if (shnum == 0)
837 return NULL;
839 /* Add initial dummy Shdr and .shstrtab. */
840 shnum += 2;
842 shdr_offset = ehdr_size;
843 sh_offset = shdr_offset + shnum * shdr_size;
845 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
846 0, 0, 0, 0, 0, 0, &errmsg, err))
847 return errmsg;
849 shdr_offset += shdr_size;
851 sh_name = 1;
852 for (section = sobj->sections; section != NULL; section = section->next)
854 size_t mask;
855 size_t new_sh_offset;
856 size_t sh_size;
857 struct simple_object_write_section_buffer *buffer;
859 mask = (1U << section->align) - 1;
860 new_sh_offset = sh_offset + mask;
861 new_sh_offset &= ~ mask;
862 while (new_sh_offset > sh_offset)
864 unsigned char zeroes[16];
865 size_t write;
867 memset (zeroes, 0, sizeof zeroes);
868 write = new_sh_offset - sh_offset;
869 if (write > sizeof zeroes)
870 write = sizeof zeroes;
871 if (!simple_object_internal_write (descriptor, sh_offset, zeroes,
872 write, &errmsg, err))
873 return errmsg;
874 sh_offset += write;
877 sh_size = 0;
878 for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
880 if (!simple_object_internal_write (descriptor, sh_offset + sh_size,
881 ((const unsigned char *)
882 buffer->buffer),
883 buffer->size, &errmsg, err))
884 return errmsg;
885 sh_size += buffer->size;
888 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
889 sh_name, SHT_PROGBITS, 0, sh_offset,
890 sh_size, 1U << section->align,
891 &errmsg, err))
892 return errmsg;
894 shdr_offset += shdr_size;
895 sh_name += strlen (section->name) + 1;
896 sh_offset += sh_size;
899 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
900 sh_name, SHT_STRTAB, 0, sh_offset,
901 sh_name + strlen (".shstrtab") + 1,
902 1, &errmsg, err))
903 return errmsg;
905 /* .shstrtab has a leading zero byte. */
906 zero = 0;
907 if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1,
908 &errmsg, err))
909 return errmsg;
910 ++sh_offset;
912 for (section = sobj->sections; section != NULL; section = section->next)
914 size_t len;
916 len = strlen (section->name) + 1;
917 if (!simple_object_internal_write (descriptor, sh_offset,
918 (const unsigned char *) section->name,
919 len, &errmsg, err))
920 return errmsg;
921 sh_offset += len;
924 if (!simple_object_internal_write (descriptor, sh_offset,
925 (const unsigned char *) ".shstrtab",
926 strlen (".shstrtab") + 1, &errmsg, err))
927 return errmsg;
929 return NULL;
932 /* Release the private data for an simple_object_write structure. */
934 static void
935 simple_object_elf_release_write (void *data)
937 XDELETE (data);
940 /* The ELF functions. */
942 const struct simple_object_functions simple_object_elf_functions =
944 simple_object_elf_match,
945 simple_object_elf_find_sections,
946 simple_object_elf_fetch_attributes,
947 simple_object_elf_release_read,
948 simple_object_elf_attributes_merge,
949 simple_object_elf_release_attributes,
950 simple_object_elf_start_write,
951 simple_object_elf_write_to_file,
952 simple_object_elf_release_write