Update dom_info
[official-gcc.git] / libiberty / simple-object-elf.c
blob8594cf99f417c5742066a39d62a9e41299c75de1
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;
701 unsigned int shstrndx;
703 fns = attrs->type_functions;
704 cl = attrs->ei_class;
706 shnum = 0;
707 for (section = sobj->sections; section != NULL; section = section->next)
708 ++shnum;
709 if (shnum > 0)
711 /* Add a section header for the dummy section and one for
712 .shstrtab. */
713 shnum += 2;
716 ehdr_size = (cl == ELFCLASS32
717 ? sizeof (Elf32_External_Ehdr)
718 : sizeof (Elf64_External_Ehdr));
719 memset (buf, 0, sizeof (Elf64_External_Ehdr));
721 buf[EI_MAG0] = ELFMAG0;
722 buf[EI_MAG1] = ELFMAG1;
723 buf[EI_MAG2] = ELFMAG2;
724 buf[EI_MAG3] = ELFMAG3;
725 buf[EI_CLASS] = cl;
726 buf[EI_DATA] = attrs->ei_data;
727 buf[EI_VERSION] = EV_CURRENT;
728 buf[EI_OSABI] = attrs->ei_osabi;
730 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_type, Elf_Half, ET_REL);
731 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_machine, Elf_Half, attrs->machine);
732 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_version, Elf_Word, EV_CURRENT);
733 /* e_entry left as zero. */
734 /* e_phoff left as zero. */
735 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shoff, Elf_Addr, ehdr_size);
736 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_flags, Elf_Word, attrs->flags);
737 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_ehsize, Elf_Half, ehdr_size);
738 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_phentsize, Elf_Half,
739 (cl == ELFCLASS32
740 ? sizeof (Elf32_External_Phdr)
741 : sizeof (Elf64_External_Phdr)));
742 /* e_phnum left as zero. */
743 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half,
744 (cl == ELFCLASS32
745 ? sizeof (Elf32_External_Shdr)
746 : sizeof (Elf64_External_Shdr)));
747 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half,
748 shnum >= SHN_LORESERVE ? 0 : shnum);
749 if (shnum == 0)
750 shstrndx = 0;
751 else
753 shstrndx = shnum - 1;
754 if (shstrndx >= SHN_LORESERVE)
755 shstrndx = SHN_XINDEX;
757 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx);
759 return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
760 errmsg, err);
763 /* Write out an ELF shdr. */
765 static int
766 simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
767 off_t offset, unsigned int sh_name,
768 unsigned int sh_type, unsigned int sh_flags,
769 unsigned int sh_offset, unsigned int sh_size,
770 unsigned int sh_link, unsigned int sh_addralign,
771 const char **errmsg, int *err)
773 struct simple_object_elf_attributes *attrs =
774 (struct simple_object_elf_attributes *) sobj->data;
775 const struct elf_type_functions* fns;
776 unsigned char cl;
777 size_t shdr_size;
778 unsigned char buf[sizeof (Elf64_External_Shdr)];
780 fns = attrs->type_functions;
781 cl = attrs->ei_class;
783 shdr_size = (cl == ELFCLASS32
784 ? sizeof (Elf32_External_Shdr)
785 : sizeof (Elf64_External_Shdr));
786 memset (buf, 0, sizeof (Elf64_External_Shdr));
788 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name);
789 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type);
790 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
791 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
792 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
793 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link);
794 /* sh_info left as zero. */
795 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
796 /* sh_entsize left as zero. */
798 return simple_object_internal_write (descriptor, offset, buf, shdr_size,
799 errmsg, err);
802 /* Write out a complete ELF file.
803 Ehdr
804 initial dummy Shdr
805 user-created Shdrs
806 .shstrtab Shdr
807 user-created section data
808 .shstrtab data */
810 static const char *
811 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
812 int *err)
814 struct simple_object_elf_attributes *attrs =
815 (struct simple_object_elf_attributes *) sobj->data;
816 unsigned char cl;
817 size_t ehdr_size;
818 size_t shdr_size;
819 const char *errmsg;
820 simple_object_write_section *section;
821 unsigned int shnum;
822 size_t shdr_offset;
823 size_t sh_offset;
824 unsigned int first_sh_size;
825 unsigned int first_sh_link;
826 size_t sh_name;
827 unsigned char zero;
829 if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err))
830 return errmsg;
832 cl = attrs->ei_class;
833 if (cl == ELFCLASS32)
835 ehdr_size = sizeof (Elf32_External_Ehdr);
836 shdr_size = sizeof (Elf32_External_Shdr);
838 else
840 ehdr_size = sizeof (Elf64_External_Ehdr);
841 shdr_size = sizeof (Elf64_External_Shdr);
844 shnum = 0;
845 for (section = sobj->sections; section != NULL; section = section->next)
846 ++shnum;
847 if (shnum == 0)
848 return NULL;
850 /* Add initial dummy Shdr and .shstrtab. */
851 shnum += 2;
853 shdr_offset = ehdr_size;
854 sh_offset = shdr_offset + shnum * shdr_size;
856 if (shnum < SHN_LORESERVE)
857 first_sh_size = 0;
858 else
859 first_sh_size = shnum;
860 if (shnum - 1 < SHN_LORESERVE)
861 first_sh_link = 0;
862 else
863 first_sh_link = shnum - 1;
864 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
865 0, 0, 0, 0, first_sh_size, first_sh_link,
866 0, &errmsg, err))
867 return errmsg;
869 shdr_offset += shdr_size;
871 sh_name = 1;
872 for (section = sobj->sections; section != NULL; section = section->next)
874 size_t mask;
875 size_t new_sh_offset;
876 size_t sh_size;
877 struct simple_object_write_section_buffer *buffer;
879 mask = (1U << section->align) - 1;
880 new_sh_offset = sh_offset + mask;
881 new_sh_offset &= ~ mask;
882 while (new_sh_offset > sh_offset)
884 unsigned char zeroes[16];
885 size_t write;
887 memset (zeroes, 0, sizeof zeroes);
888 write = new_sh_offset - sh_offset;
889 if (write > sizeof zeroes)
890 write = sizeof zeroes;
891 if (!simple_object_internal_write (descriptor, sh_offset, zeroes,
892 write, &errmsg, err))
893 return errmsg;
894 sh_offset += write;
897 sh_size = 0;
898 for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
900 if (!simple_object_internal_write (descriptor, sh_offset + sh_size,
901 ((const unsigned char *)
902 buffer->buffer),
903 buffer->size, &errmsg, err))
904 return errmsg;
905 sh_size += buffer->size;
908 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
909 sh_name, SHT_PROGBITS, 0, sh_offset,
910 sh_size, 0, 1U << section->align,
911 &errmsg, err))
912 return errmsg;
914 shdr_offset += shdr_size;
915 sh_name += strlen (section->name) + 1;
916 sh_offset += sh_size;
919 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
920 sh_name, SHT_STRTAB, 0, sh_offset,
921 sh_name + strlen (".shstrtab") + 1, 0,
922 1, &errmsg, err))
923 return errmsg;
925 /* .shstrtab has a leading zero byte. */
926 zero = 0;
927 if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1,
928 &errmsg, err))
929 return errmsg;
930 ++sh_offset;
932 for (section = sobj->sections; section != NULL; section = section->next)
934 size_t len;
936 len = strlen (section->name) + 1;
937 if (!simple_object_internal_write (descriptor, sh_offset,
938 (const unsigned char *) section->name,
939 len, &errmsg, err))
940 return errmsg;
941 sh_offset += len;
944 if (!simple_object_internal_write (descriptor, sh_offset,
945 (const unsigned char *) ".shstrtab",
946 strlen (".shstrtab") + 1, &errmsg, err))
947 return errmsg;
949 return NULL;
952 /* Release the private data for an simple_object_write structure. */
954 static void
955 simple_object_elf_release_write (void *data)
957 XDELETE (data);
960 /* The ELF functions. */
962 const struct simple_object_functions simple_object_elf_functions =
964 simple_object_elf_match,
965 simple_object_elf_find_sections,
966 simple_object_elf_fetch_attributes,
967 simple_object_elf_release_read,
968 simple_object_elf_attributes_merge,
969 simple_object_elf_release_attributes,
970 simple_object_elf_start_write,
971 simple_object_elf_write_to_file,
972 simple_object_elf_release_write