OSDN Git Service

include/:
[pf3gnuchains/gcc-fork.git] / libiberty / simple-object-elf.c
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.
4
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.
9
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.
14
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.  */
19
20 #include "config.h"
21 #include "libiberty.h"
22 #include "simple-object.h"
23
24 #include <errno.h>
25 #include <stddef.h>
26
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
30
31 #ifdef HAVE_STDINT_H
32 #include <stdint.h>
33 #endif
34
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
38
39 #ifdef HAVE_INTTYPES_H
40 #include <inttypes.h>
41 #endif
42
43 #include "simple-object-common.h"
44
45 /* ELF structures and constants.  */
46
47 /* 32-bit ELF file header.  */
48
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;
65
66 /* 64-bit ELF file header.  */
67
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;
84
85 /* Indexes and values in e_ident field of Ehdr.  */
86
87 #define EI_MAG0         0       /* File identification byte 0 index */
88 #define ELFMAG0            0x7F /* Magic number byte 0 */
89
90 #define EI_MAG1         1       /* File identification byte 1 index */
91 #define ELFMAG1             'E' /* Magic number byte 1 */
92
93 #define EI_MAG2         2       /* File identification byte 2 index */
94 #define ELFMAG2             'L' /* Magic number byte 2 */
95
96 #define EI_MAG3         3       /* File identification byte 3 index */
97 #define ELFMAG3             'F' /* Magic number byte 3 */
98
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 */
103
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 */
108
109 #define EI_VERSION      6       /* File version */
110 #define EV_CURRENT      1               /* Current version */
111
112 #define EI_OSABI        7       /* Operating System/ABI indication */
113
114 /* Values for e_type field of Ehdr.  */
115
116 #define ET_REL          1       /* Relocatable file */
117
118 /* Values for e_machine field of Ehdr.  */
119
120 #define EM_SPARC          2     /* SUN SPARC */
121 #define EM_SPARC32PLUS   18     /* Sun's "v8plus" */
122
123 /* Special section index values.  */
124
125 #define SHN_LORESERVE   0xFF00          /* Begin range of reserved indices */
126 #define SHN_XINDEX      0xFFFF          /* Section index is held elsewhere */
127
128 /* 32-bit ELF program header.  */
129
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;
140
141 /* 64-bit ELF program header.  */
142
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;
153
154 /* 32-bit ELF section header */
155
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;
168
169 /* 64-bit ELF section header.  */
170
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;
183
184 /* Values for sh_type field.  */
185
186 #define SHT_PROGBITS    1               /* Program data */
187 #define SHT_STRTAB      3               /* A string table */
188
189 /* Functions to fetch and store different ELF types, depending on the
190    endianness and size.  */
191
192 struct elf_type_functions
193 {
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);
200 };
201
202 static const struct elf_type_functions elf_big_32_functions =
203 {
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
210 };
211
212 static const struct elf_type_functions elf_little_32_functions =
213 {
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
220 };
221
222 #ifdef UNSIGNED_64BIT_TYPE
223
224 static const struct elf_type_functions elf_big_64_functions =
225 {
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
232 };
233
234 static const struct elf_type_functions elf_little_64_functions =
235 {
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
242 };
243
244 #endif
245
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.  */
251
252 #define ELF_FETCH_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE) \
253   ((TYPEFUNCS)->fetch_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD)))
254
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.  */
260
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)
266
267 /* Like ELF_FETCH_SIZED_FIELD but taking an ELFCLASS value.  */
268
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))
276
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.  */
283
284 #define ELF_SET_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE, VAL) \
285   (TYPEFUNCS)->set_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD), (VAL))
286
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.  */
292
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)
298
299 /* Like ELF_SET_SIZED_FIELD but taking an ELFCLASS value.  */
300
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))
308
309 /* Private data for an simple_object_read.  */
310
311 struct simple_object_elf_read
312 {
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;
331 };
332
333 /* Private data for an simple_object_attributes.  */
334
335 struct simple_object_elf_attributes
336 {
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;
349 };
350
351 /* See if we have an ELF file.  */
352
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)
358 {
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;
364
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)
370     {
371       *errmsg = NULL;
372       *err = 0;
373       return NULL;
374     }
375
376   ei_data = header[EI_DATA];
377   if (ei_data != ELFDATA2LSB && ei_data != ELFDATA2MSB)
378     {
379       *errmsg = "unknown ELF endianness";
380       *err = 0;
381       return NULL;
382     }
383
384   ei_class = header[EI_CLASS];
385   switch (ei_class)
386     {
387     case ELFCLASS32:
388       type_functions = (ei_data == ELFDATA2LSB
389                         ? &elf_little_32_functions
390                         : &elf_big_32_functions);
391       break;
392
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
404
405     default:
406       *errmsg = "unrecognized ELF size";
407       *err = 0;
408       return NULL;
409     }
410
411   if (!simple_object_internal_read (descriptor, offset, ehdr, sizeof ehdr,
412                                     errmsg, err))
413     return NULL;
414
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);
430
431   if ((eor->shnum == 0 || eor->shstrndx == SHN_XINDEX)
432       && eor->shoff != 0)
433     {
434       unsigned char shdr[sizeof (Elf64_External_Shdr)];
435
436       /* Object file has more than 0xffff sections.  */
437
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))
443         {
444           XDELETE (eor);
445           return NULL;
446         }
447
448       if (eor->shnum == 0)
449         eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
450                                       shdr, sh_size, Elf_Addr);
451
452       if (eor->shstrndx == SHN_XINDEX)
453         {
454           eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
455                                            shdr, sh_link, Elf_Word);
456
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;
471         }
472     }
473
474   if (eor->shstrndx >= eor->shnum)
475     {
476       *errmsg = "invalid ELF shstrndx >= shnum";
477       *err = 0;
478       XDELETE (eor);
479       return NULL;
480     }
481
482   return (void *) eor;
483 }
484
485 /* Find all sections in an ELF file.  */
486
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)
493 {
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;
507
508   shdr_size = (ei_class == ELFCLASS32
509                ? sizeof (Elf32_External_Shdr)
510                : sizeof (Elf64_External_Shdr));
511
512   /* Read the section headers.  We skip section 0, which is not a
513      useful section.  */
514
515   shnum = eor->shnum;
516   shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
517
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))
523     {
524       XDELETEVEC (shdrs);
525       return errmsg;
526     }
527
528   /* Read the section names.  */
529
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))
539     {
540       XDELETEVEC (names);
541       XDELETEVEC (shdrs);
542       return errmsg;
543     }
544
545   for (i = 1; i < shnum; ++i)
546     {
547       unsigned char *shdr;
548       unsigned int sh_name;
549       const char *name;
550       off_t offset;
551       off_t length;
552
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)
557         {
558           *err = 0;
559           XDELETEVEC (names);
560           XDELETEVEC (shdrs);
561           return "ELF section name out of range";
562         }
563
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);
569
570       if (!(*pfn) (data, name, offset, length))
571         break;
572     }
573
574   XDELETEVEC (names);
575   XDELETEVEC (shdrs);
576
577   return NULL;
578 }
579
580 /* Fetch the attributes for an simple_object_read.  */
581
582 static void *
583 simple_object_elf_fetch_attributes (simple_object_read *sobj,
584                                     const char **errmsg ATTRIBUTE_UNUSED,
585                                     int *err ATTRIBUTE_UNUSED)
586 {
587   struct simple_object_elf_read *eor =
588     (struct simple_object_elf_read *) sobj->data;
589   struct simple_object_elf_attributes *ret;
590
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;
599 }
600
601 /* Release the privata data for an simple_object_read.  */
602
603 static void
604 simple_object_elf_release_read (void *data)
605 {
606   XDELETE (data);
607 }
608
609 /* Compare two attributes structures.  */
610
611 static const char *
612 simple_object_elf_attributes_merge (void *todata, void *fromdata, int *err)
613 {
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;
618
619   if (to->ei_data != from->ei_data || to->ei_class != from->ei_class)
620     {
621       *err = 0;
622       return "ELF object format mismatch";
623     }
624
625   if (to->machine != from->machine)
626     {
627       int ok;
628
629       /* EM_SPARC and EM_SPARC32PLUS are compatible and force an
630          output of EM_SPARC32PLUS.  */
631       ok = 0;
632       switch (to->machine)
633         {
634         case EM_SPARC:
635           if (from->machine == EM_SPARC32PLUS)
636             {
637               to->machine = from->machine;
638               ok = 1;
639             }
640           break;
641
642         case EM_SPARC32PLUS:
643           if (from->machine == EM_SPARC)
644             ok = 1;
645           break;
646
647         default:
648           break;
649         }
650
651       if (!ok)
652         {
653           *err = 0;
654           return "ELF machine number mismatch";
655         }
656     }
657
658   return NULL;
659 }
660
661 /* Release the private data for an attributes structure.  */
662
663 static void
664 simple_object_elf_release_attributes (void *data)
665 {
666   XDELETE (data);
667 }
668
669 /* Prepare to write out a file.  */
670
671 static void *
672 simple_object_elf_start_write (void *attributes_data,
673                                const char **errmsg ATTRIBUTE_UNUSED,
674                                int *err ATTRIBUTE_UNUSED)
675 {
676   struct simple_object_elf_attributes *attrs =
677     (struct simple_object_elf_attributes *) attributes_data;
678   struct simple_object_elf_attributes *ret;
679
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;
685 }
686
687 /* Write out an ELF ehdr.  */
688
689 static int
690 simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
691                               const char **errmsg, int *err)
692 {
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
702   fns = attrs->type_functions;
703   cl = attrs->ei_class;
704
705   shnum = 0;
706   for (section = sobj->sections; section != NULL; section = section->next)
707     ++shnum;
708   if (shnum > 0)
709     {
710       /* Add a section header for the dummy section and one for
711          .shstrtab.  */
712       shnum += 2;
713     }
714
715   ehdr_size = (cl == ELFCLASS32
716                ? sizeof (Elf32_External_Ehdr)
717                : sizeof (Elf64_External_Ehdr));
718   memset (buf, 0, sizeof (Elf64_External_Ehdr));
719
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;
728
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);
749
750   return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
751                                        errmsg, err);
752 }
753
754 /* Write out an ELF shdr.  */
755
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)
763 {
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)];
770
771   fns = attrs->type_functions;
772   cl = attrs->ei_class;
773
774   shdr_size = (cl == ELFCLASS32
775                ? sizeof (Elf32_External_Shdr)
776                : sizeof (Elf64_External_Shdr));
777   memset (buf, 0, sizeof (Elf64_External_Shdr));
778
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.  */
788
789   return simple_object_internal_write (descriptor, offset, buf, shdr_size,
790                                        errmsg, err);
791 }
792
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  */
800
801 static const char *
802 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
803                                  int *err)
804 {
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;
817
818   if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err))
819     return errmsg;
820
821   cl = attrs->ei_class;
822   if (cl == ELFCLASS32)
823     {
824       ehdr_size = sizeof (Elf32_External_Ehdr);
825       shdr_size = sizeof (Elf32_External_Shdr);
826     }
827   else
828     {
829       ehdr_size = sizeof (Elf64_External_Ehdr);
830       shdr_size = sizeof (Elf64_External_Shdr);
831     }
832
833   shnum = 0;
834   for (section = sobj->sections; section != NULL; section = section->next)
835     ++shnum;
836   if (shnum == 0)
837     return NULL;
838
839   /* Add initial dummy Shdr and .shstrtab.  */
840   shnum += 2;
841
842   shdr_offset = ehdr_size;
843   sh_offset = shdr_offset + shnum * shdr_size;
844
845   if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
846                                      0, 0, 0, 0, 0, 0, &errmsg, err))
847     return errmsg;
848
849   shdr_offset += shdr_size;
850
851   sh_name = 1;
852   for (section = sobj->sections; section != NULL; section = section->next)
853     {
854       size_t mask;
855       size_t new_sh_offset;
856       size_t sh_size;
857       struct simple_object_write_section_buffer *buffer;
858
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)
863         {
864           unsigned char zeroes[16];
865           size_t write;
866
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;
875         }
876
877       sh_size = 0;
878       for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
879         {
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;
886         }
887
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;
893
894       shdr_offset += shdr_size;
895       sh_name += strlen (section->name) + 1;
896       sh_offset += sh_size;
897     }
898
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;
904
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;
911
912   for (section = sobj->sections; section != NULL; section = section->next)
913     {
914       size_t len;
915
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;
922     }
923
924   if (!simple_object_internal_write (descriptor, sh_offset,
925                                      (const unsigned char *) ".shstrtab",
926                                      strlen (".shstrtab") + 1, &errmsg, err))
927     return errmsg;
928
929   return NULL;
930 }
931
932 /* Release the private data for an simple_object_write structure.  */
933
934 static void
935 simple_object_elf_release_write (void *data)
936 {
937   XDELETE (data);
938 }
939
940 /* The ELF functions.  */
941
942 const struct simple_object_functions simple_object_elf_functions =
943 {
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
953 };