xref: /netbsd-src/external/gpl3/binutils/dist/libiberty/simple-object-elf.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
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 /* Special section index values.  */
119 
120 #define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
121 #define SHN_XINDEX	0xFFFF		/* Section index is held elsewhere */
122 
123 /* 32-bit ELF program header.  */
124 
125 typedef struct {
126   unsigned char	p_type[4];		/* Identifies program segment type */
127   unsigned char	p_offset[4];		/* Segment file offset */
128   unsigned char	p_vaddr[4];		/* Segment virtual address */
129   unsigned char	p_paddr[4];		/* Segment physical address */
130   unsigned char	p_filesz[4];		/* Segment size in file */
131   unsigned char	p_memsz[4];		/* Segment size in memory */
132   unsigned char	p_flags[4];		/* Segment flags */
133   unsigned char	p_align[4];		/* Segment alignment, file & memory */
134 } Elf32_External_Phdr;
135 
136 /* 64-bit ELF program header.  */
137 
138 typedef struct {
139   unsigned char	p_type[4];		/* Identifies program segment type */
140   unsigned char	p_flags[4];		/* Segment flags */
141   unsigned char	p_offset[8];		/* Segment file offset */
142   unsigned char	p_vaddr[8];		/* Segment virtual address */
143   unsigned char	p_paddr[8];		/* Segment physical address */
144   unsigned char	p_filesz[8];		/* Segment size in file */
145   unsigned char	p_memsz[8];		/* Segment size in memory */
146   unsigned char	p_align[8];		/* Segment alignment, file & memory */
147 } Elf64_External_Phdr;
148 
149 /* 32-bit ELF section header */
150 
151 typedef struct {
152   unsigned char	sh_name[4];		/* Section name, index in string tbl */
153   unsigned char	sh_type[4];		/* Type of section */
154   unsigned char	sh_flags[4];		/* Miscellaneous section attributes */
155   unsigned char	sh_addr[4];		/* Section virtual addr at execution */
156   unsigned char	sh_offset[4];		/* Section file offset */
157   unsigned char	sh_size[4];		/* Size of section in bytes */
158   unsigned char	sh_link[4];		/* Index of another section */
159   unsigned char	sh_info[4];		/* Additional section information */
160   unsigned char	sh_addralign[4];	/* Section alignment */
161   unsigned char	sh_entsize[4];		/* Entry size if section holds table */
162 } Elf32_External_Shdr;
163 
164 /* 64-bit ELF section header.  */
165 
166 typedef struct {
167   unsigned char	sh_name[4];		/* Section name, index in string tbl */
168   unsigned char	sh_type[4];		/* Type of section */
169   unsigned char	sh_flags[8];		/* Miscellaneous section attributes */
170   unsigned char	sh_addr[8];		/* Section virtual addr at execution */
171   unsigned char	sh_offset[8];		/* Section file offset */
172   unsigned char	sh_size[8];		/* Size of section in bytes */
173   unsigned char	sh_link[4];		/* Index of another section */
174   unsigned char	sh_info[4];		/* Additional section information */
175   unsigned char	sh_addralign[8];	/* Section alignment */
176   unsigned char	sh_entsize[8];		/* Entry size if section holds table */
177 } Elf64_External_Shdr;
178 
179 /* Values for sh_type field.  */
180 
181 #define SHT_PROGBITS	1		/* Program data */
182 #define SHT_STRTAB	3		/* A string table */
183 
184 /* Functions to fetch and store different ELF types, depending on the
185    endianness and size.  */
186 
187 struct elf_type_functions
188 {
189   unsigned short (*fetch_Elf_Half) (const unsigned char *);
190   unsigned int (*fetch_Elf_Word) (const unsigned char *);
191   ulong_type (*fetch_Elf_Addr) (const unsigned char *);
192   void (*set_Elf_Half) (unsigned char *, unsigned short);
193   void (*set_Elf_Word) (unsigned char *, unsigned int);
194   void (*set_Elf_Addr) (unsigned char *, ulong_type);
195 };
196 
197 static const struct elf_type_functions elf_big_32_functions =
198 {
199   simple_object_fetch_big_16,
200   simple_object_fetch_big_32,
201   simple_object_fetch_big_32_ulong,
202   simple_object_set_big_16,
203   simple_object_set_big_32,
204   simple_object_set_big_32_ulong
205 };
206 
207 static const struct elf_type_functions elf_little_32_functions =
208 {
209   simple_object_fetch_little_16,
210   simple_object_fetch_little_32,
211   simple_object_fetch_little_32_ulong,
212   simple_object_set_little_16,
213   simple_object_set_little_32,
214   simple_object_set_little_32_ulong
215 };
216 
217 #ifdef UNSIGNED_64BIT_TYPE
218 
219 static const struct elf_type_functions elf_big_64_functions =
220 {
221   simple_object_fetch_big_16,
222   simple_object_fetch_big_32,
223   simple_object_fetch_big_64,
224   simple_object_set_big_16,
225   simple_object_set_big_32,
226   simple_object_set_big_64
227 };
228 
229 static const struct elf_type_functions elf_little_64_functions =
230 {
231   simple_object_fetch_little_16,
232   simple_object_fetch_little_32,
233   simple_object_fetch_little_64,
234   simple_object_set_little_16,
235   simple_object_set_little_32,
236   simple_object_set_little_64
237 };
238 
239 #endif
240 
241 /* Hideous macro to fetch the value of a field from an external ELF
242    struct of some sort.  TYPEFUNCS is the set of type functions.
243    BUFFER points to the external data.  STRUCTTYPE is the appropriate
244    struct type.  FIELD is a field within the struct.  TYPE is the type
245    of the field in the struct: Elf_Half, Elf_Word, or Elf_Addr.  */
246 
247 #define ELF_FETCH_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE) \
248   ((TYPEFUNCS)->fetch_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD)))
249 
250 /* Even more hideous macro to fetch the value of FIELD from BUFFER.
251    SIZE is 32 or 64.  STRUCTTYPE is the name of the struct from
252    elf/external.h: Ehdr, Shdr, etc.  FIELD is the name of a field in
253    the struct.  TYPE is the type of the field in the struct: Elf_Half,
254    Elf_Word, or Elf_Addr.  */
255 
256 #define ELF_FETCH_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER,	\
257 			      FIELD, TYPE)				\
258   ELF_FETCH_STRUCT_FIELD (TYPEFUNCS,					\
259 			  Elf ## SIZE ## _External_ ## STRUCTTYPE,	\
260 			  FIELD, BUFFER, TYPE)
261 
262 /* Like ELF_FETCH_SIZED_FIELD but taking an ELFCLASS value.  */
263 
264 #define ELF_FETCH_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER,		\
265 			FIELD, TYPE)					\
266   ((CLASS) == ELFCLASS32						\
267     ? ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD,	\
268 			     TYPE)					\
269     : ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD,	\
270 			     TYPE))
271 
272 /* Hideous macro to set the value of a field in an external ELF
273    structure to VAL.  TYPEFUNCS is the set of type functions.  BUFFER
274    points to the external data.  STRUCTTYPE is the appropriate
275    structure type.  FIELD is a field within the struct.  TYPE is the
276    type of the field in the struct: Elf_Half, Elf_Word, or
277    Elf_Addr.  */
278 
279 #define ELF_SET_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE, VAL) \
280   (TYPEFUNCS)->set_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD), (VAL))
281 
282 /* Even more hideous macro to set the value of FIELD in BUFFER to VAL.
283    SIZE is 32 or 64.  STRUCTTYPE is the name of the struct from
284    elf/external.h: Ehdr, Shdr, etc.  FIELD is the name of a field in
285    the struct.  TYPE is the type of the field in the struct: Elf_Half,
286    Elf_Word, or Elf_Addr.  */
287 
288 #define ELF_SET_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER, FIELD, \
289 			    TYPE, VAL)					\
290   ELF_SET_STRUCT_FIELD (TYPEFUNCS,					\
291 			Elf ## SIZE ## _External_ ## STRUCTTYPE,	\
292 			FIELD, BUFFER, TYPE, VAL)
293 
294 /* Like ELF_SET_SIZED_FIELD but taking an ELFCLASS value.  */
295 
296 #define ELF_SET_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER, FIELD,	\
297 		      TYPE, VAL)					\
298   ((CLASS) == ELFCLASS32						\
299     ? ELF_SET_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD,	\
300 			   TYPE, VAL)					\
301     : ELF_SET_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD,	\
302 			   TYPE, VAL))
303 
304 /* Private data for an simple_object_read.  */
305 
306 struct simple_object_elf_read
307 {
308   /* Type functions.  */
309   const struct elf_type_functions* type_functions;
310   /* Elf data.  */
311   unsigned char ei_data;
312   /* Elf class.  */
313   unsigned char ei_class;
314   /* ELF OS ABI.  */
315   unsigned char ei_osabi;
316   /* Elf machine number.  */
317   unsigned short machine;
318   /* Processor specific flags.  */
319   unsigned int flags;
320   /* File offset of section headers.  */
321   ulong_type shoff;
322   /* Number of sections.  */
323   unsigned int shnum;
324   /* Index of string table section header.  */
325   unsigned int shstrndx;
326 };
327 
328 /* Private data for an simple_object_attributes.  */
329 
330 struct simple_object_elf_attributes
331 {
332   /* Type functions.  */
333   const struct elf_type_functions* type_functions;
334   /* Elf data.  */
335   unsigned char ei_data;
336   /* Elf class.  */
337   unsigned char ei_class;
338   /* ELF OS ABI.  */
339   unsigned char ei_osabi;
340   /* Elf machine number.  */
341   unsigned short machine;
342   /* Processor specific flags.  */
343   unsigned int flags;
344 };
345 
346 /* See if we have an ELF file.  */
347 
348 static void *
349 simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
350 			 int descriptor, off_t offset,
351 			 const char *segment_name ATTRIBUTE_UNUSED,
352 			 const char **errmsg, int *err)
353 {
354   unsigned char ei_data;
355   unsigned char ei_class;
356   const struct elf_type_functions *type_functions;
357   unsigned char ehdr[sizeof (Elf64_External_Ehdr)];
358   struct simple_object_elf_read *eor;
359 
360   if (header[EI_MAG0] != ELFMAG0
361       || header[EI_MAG1] != ELFMAG1
362       || header[EI_MAG2] != ELFMAG2
363       || header[EI_MAG3] != ELFMAG3
364       || header[EI_VERSION] != EV_CURRENT)
365     {
366       *errmsg = NULL;
367       *err = 0;
368       return NULL;
369     }
370 
371   ei_data = header[EI_DATA];
372   if (ei_data != ELFDATA2LSB && ei_data != ELFDATA2MSB)
373     {
374       *errmsg = "unknown ELF endianness";
375       *err = 0;
376       return NULL;
377     }
378 
379   ei_class = header[EI_CLASS];
380   switch (ei_class)
381     {
382     case ELFCLASS32:
383       type_functions = (ei_data == ELFDATA2LSB
384 			? &elf_little_32_functions
385 			: &elf_big_32_functions);
386       break;
387 
388     case ELFCLASS64:
389 #ifndef UNSIGNED_64BIT_TYPE
390       *errmsg = "64-bit ELF objects not supported";
391       *err = 0;
392       return NULL;
393 #else
394       type_functions = (ei_data == ELFDATA2LSB
395 			? &elf_little_64_functions
396 			: &elf_big_64_functions);
397       break;
398 #endif
399 
400     default:
401       *errmsg = "unrecognized ELF size";
402       *err = 0;
403       return NULL;
404     }
405 
406   if (!simple_object_internal_read (descriptor, offset, ehdr, sizeof ehdr,
407 				    errmsg, err))
408     return NULL;
409 
410   eor = XNEW (struct simple_object_elf_read);
411   eor->type_functions = type_functions;
412   eor->ei_data = ei_data;
413   eor->ei_class = ei_class;
414   eor->ei_osabi = header[EI_OSABI];
415   eor->machine = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
416 				  e_machine, Elf_Half);
417   eor->flags = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
418 				e_flags, Elf_Word);
419   eor->shoff = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
420 				e_shoff, Elf_Addr);
421   eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
422 				e_shnum, Elf_Half);
423   eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
424 				   e_shstrndx, Elf_Half);
425 
426   if ((eor->shnum == 0 || eor->shstrndx == SHN_XINDEX)
427       && eor->shoff != 0)
428     {
429       unsigned char shdr[sizeof (Elf64_External_Shdr)];
430 
431       /* Object file has more than 0xffff sections.  */
432 
433       if (!simple_object_internal_read (descriptor, offset + eor->shoff, shdr,
434 					(ei_class == ELFCLASS32
435 					 ? sizeof (Elf32_External_Shdr)
436 					 : sizeof (Elf64_External_Shdr)),
437 					errmsg, err))
438 	{
439 	  XDELETE (eor);
440 	  return NULL;
441 	}
442 
443       if (eor->shnum == 0)
444 	eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
445 				      shdr, sh_size, Elf_Addr);
446 
447       if (eor->shstrndx == SHN_XINDEX)
448 	{
449 	  eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
450 					   shdr, sh_link, Elf_Word);
451 
452 	  /* Versions of the GNU binutils between 2.12 and 2.18 did
453 	     not handle objects with more than SHN_LORESERVE sections
454 	     correctly.  All large section indexes were offset by
455 	     0x100.  There is more information at
456 	     http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
457 	     Fortunately these object files are easy to detect, as the
458 	     GNU binutils always put the section header string table
459 	     near the end of the list of sections.  Thus if the
460 	     section header string table index is larger than the
461 	     number of sections, then we know we have to subtract
462 	     0x100 to get the real section index.  */
463 	  if (eor->shstrndx >= eor->shnum
464 	      && eor->shstrndx >= SHN_LORESERVE + 0x100)
465 	    eor->shstrndx -= 0x100;
466 	}
467     }
468 
469   if (eor->shstrndx >= eor->shnum)
470     {
471       *errmsg = "invalid ELF shstrndx >= shnum";
472       *err = 0;
473       XDELETE (eor);
474       return NULL;
475     }
476 
477   return (void *) eor;
478 }
479 
480 /* Find all sections in an ELF file.  */
481 
482 static const char *
483 simple_object_elf_find_sections (simple_object_read *sobj,
484 				 int (*pfn) (void *, const char *,
485 					     off_t offset, off_t length),
486 				 void *data,
487 				 int *err)
488 {
489   struct simple_object_elf_read *eor =
490     (struct simple_object_elf_read *) sobj->data;
491   const struct elf_type_functions *type_functions = eor->type_functions;
492   unsigned char ei_class = eor->ei_class;
493   size_t shdr_size;
494   unsigned int shnum;
495   unsigned char *shdrs;
496   const char *errmsg;
497   unsigned char *shstrhdr;
498   size_t name_size;
499   off_t shstroff;
500   unsigned char *names;
501   unsigned int i;
502 
503   shdr_size = (ei_class == ELFCLASS32
504 	       ? sizeof (Elf32_External_Shdr)
505 	       : sizeof (Elf64_External_Shdr));
506 
507   /* Read the section headers.  We skip section 0, which is not a
508      useful section.  */
509 
510   shnum = eor->shnum;
511   shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
512 
513   if (!simple_object_internal_read (sobj->descriptor,
514 				    sobj->offset + eor->shoff + shdr_size,
515 				    shdrs,
516 				    shdr_size * (shnum - 1),
517 				    &errmsg, err))
518     {
519       XDELETEVEC (shdrs);
520       return errmsg;
521     }
522 
523   /* Read the section names.  */
524 
525   shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size;
526   name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
527 			       shstrhdr, sh_size, Elf_Addr);
528   shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
529 			      shstrhdr, sh_offset, Elf_Addr);
530   names = XNEWVEC (unsigned char, name_size);
531   if (!simple_object_internal_read (sobj->descriptor,
532 				    sobj->offset + shstroff,
533 				    names, name_size, &errmsg, err))
534     {
535       XDELETEVEC (names);
536       XDELETEVEC (shdrs);
537       return errmsg;
538     }
539 
540   for (i = 1; i < shnum; ++i)
541     {
542       unsigned char *shdr;
543       unsigned int sh_name;
544       const char *name;
545       off_t offset;
546       off_t length;
547 
548       shdr = shdrs + (i - 1) * shdr_size;
549       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
550 				 shdr, sh_name, Elf_Word);
551       if (sh_name >= name_size)
552 	{
553 	  *err = 0;
554 	  XDELETEVEC (names);
555 	  XDELETEVEC (shdrs);
556 	  return "ELF section name out of range";
557 	}
558 
559       name = (const char *) names + sh_name;
560       offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
561 				shdr, sh_offset, Elf_Addr);
562       length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
563 				shdr, sh_size, Elf_Addr);
564 
565       if (!(*pfn) (data, name, offset, length))
566 	break;
567     }
568 
569   XDELETEVEC (names);
570   XDELETEVEC (shdrs);
571 
572   return NULL;
573 }
574 
575 /* Fetch the attributes for an simple_object_read.  */
576 
577 static void *
578 simple_object_elf_fetch_attributes (simple_object_read *sobj,
579 				    const char **errmsg ATTRIBUTE_UNUSED,
580 				    int *err ATTRIBUTE_UNUSED)
581 {
582   struct simple_object_elf_read *eor =
583     (struct simple_object_elf_read *) sobj->data;
584   struct simple_object_elf_attributes *ret;
585 
586   ret = XNEW (struct simple_object_elf_attributes);
587   ret->type_functions = eor->type_functions;
588   ret->ei_data = eor->ei_data;
589   ret->ei_class = eor->ei_class;
590   ret->ei_osabi = eor->ei_osabi;
591   ret->machine = eor->machine;
592   ret->flags = eor->flags;
593   return ret;
594 }
595 
596 /* Release the privata data for an simple_object_read.  */
597 
598 static void
599 simple_object_elf_release_read (void *data)
600 {
601   XDELETE (data);
602 }
603 
604 /* Compare two attributes structures.  */
605 
606 static const char *
607 simple_object_elf_attributes_compare (void *data1, void *data2, int *err)
608 {
609   struct simple_object_elf_attributes *attrs1 =
610     (struct simple_object_elf_attributes *) data1;
611   struct simple_object_elf_attributes *attrs2 =
612     (struct simple_object_elf_attributes *) data2;
613 
614   if (attrs1->ei_data != attrs2->ei_data
615       || attrs1->ei_class != attrs2->ei_class
616       || attrs1->machine != attrs2->machine)
617     {
618       *err = 0;
619       return "ELF object format mismatch";
620     }
621   return NULL;
622 }
623 
624 /* Release the private data for an attributes structure.  */
625 
626 static void
627 simple_object_elf_release_attributes (void *data)
628 {
629   XDELETE (data);
630 }
631 
632 /* Prepare to write out a file.  */
633 
634 static void *
635 simple_object_elf_start_write (void *attributes_data,
636 			       const char **errmsg ATTRIBUTE_UNUSED,
637 			       int *err ATTRIBUTE_UNUSED)
638 {
639   struct simple_object_elf_attributes *attrs =
640     (struct simple_object_elf_attributes *) attributes_data;
641   struct simple_object_elf_attributes *ret;
642 
643   /* We're just going to record the attributes, but we need to make a
644      copy because the user may delete them.  */
645   ret = XNEW (struct simple_object_elf_attributes);
646   *ret = *attrs;
647   return ret;
648 }
649 
650 /* Write out an ELF ehdr.  */
651 
652 static int
653 simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
654 			      const char **errmsg, int *err)
655 {
656   struct simple_object_elf_attributes *attrs =
657     (struct simple_object_elf_attributes *) sobj->data;
658   const struct elf_type_functions* fns;
659   unsigned char cl;
660   size_t ehdr_size;
661   unsigned char buf[sizeof (Elf64_External_Ehdr)];
662   simple_object_write_section *section;
663   unsigned int shnum;
664 
665   fns = attrs->type_functions;
666   cl = attrs->ei_class;
667 
668   shnum = 0;
669   for (section = sobj->sections; section != NULL; section = section->next)
670     ++shnum;
671   if (shnum > 0)
672     {
673       /* Add a section header for the dummy section and one for
674 	 .shstrtab.  */
675       shnum += 2;
676     }
677 
678   ehdr_size = (cl == ELFCLASS32
679 	       ? sizeof (Elf32_External_Ehdr)
680 	       : sizeof (Elf64_External_Ehdr));
681   memset (buf, 0, sizeof (Elf64_External_Ehdr));
682 
683   buf[EI_MAG0] = ELFMAG0;
684   buf[EI_MAG1] = ELFMAG1;
685   buf[EI_MAG2] = ELFMAG2;
686   buf[EI_MAG3] = ELFMAG3;
687   buf[EI_CLASS] = cl;
688   buf[EI_DATA] = attrs->ei_data;
689   buf[EI_VERSION] = EV_CURRENT;
690   buf[EI_OSABI] = attrs->ei_osabi;
691 
692   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_type, Elf_Half, ET_REL);
693   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_machine, Elf_Half, attrs->machine);
694   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_version, Elf_Word, EV_CURRENT);
695   /* e_entry left as zero.  */
696   /* e_phoff left as zero.  */
697   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shoff, Elf_Addr, ehdr_size);
698   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_flags, Elf_Word, attrs->flags);
699   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_ehsize, Elf_Half, ehdr_size);
700   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_phentsize, Elf_Half,
701 		 (cl == ELFCLASS32
702 		  ? sizeof (Elf32_External_Phdr)
703 		  : sizeof (Elf64_External_Phdr)));
704   /* e_phnum left as zero.  */
705   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half,
706 		 (cl == ELFCLASS32
707 		  ? sizeof (Elf32_External_Shdr)
708 		  : sizeof (Elf64_External_Shdr)));
709   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, shnum);
710   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half,
711 		 shnum == 0 ? 0 : shnum - 1);
712 
713   return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
714 				       errmsg, err);
715 }
716 
717 /* Write out an ELF shdr.  */
718 
719 static int
720 simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
721 			      off_t offset, unsigned int sh_name,
722 			      unsigned int sh_type, unsigned int sh_flags,
723 			      unsigned int sh_offset, unsigned int sh_size,
724 			      unsigned int sh_addralign, const char **errmsg,
725 			      int *err)
726 {
727   struct simple_object_elf_attributes *attrs =
728     (struct simple_object_elf_attributes *) sobj->data;
729   const struct elf_type_functions* fns;
730   unsigned char cl;
731   size_t shdr_size;
732   unsigned char buf[sizeof (Elf64_External_Shdr)];
733 
734   fns = attrs->type_functions;
735   cl = attrs->ei_class;
736 
737   shdr_size = (cl == ELFCLASS32
738 	       ? sizeof (Elf32_External_Shdr)
739 	       : sizeof (Elf64_External_Shdr));
740   memset (buf, 0, sizeof (Elf64_External_Shdr));
741 
742   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name);
743   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type);
744   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
745   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
746   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
747   /* sh_link left as zero.  */
748   /* sh_info left as zero.  */
749   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
750   /* sh_entsize left as zero.  */
751 
752   return simple_object_internal_write (descriptor, offset, buf, shdr_size,
753 				       errmsg, err);
754 }
755 
756 /* Write out a complete ELF file.
757    Ehdr
758    initial dummy Shdr
759    user-created Shdrs
760    .shstrtab Shdr
761    user-created section data
762    .shstrtab data  */
763 
764 static const char *
765 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
766 				 int *err)
767 {
768   struct simple_object_elf_attributes *attrs =
769     (struct simple_object_elf_attributes *) sobj->data;
770   unsigned char cl;
771   size_t ehdr_size;
772   size_t shdr_size;
773   const char *errmsg;
774   simple_object_write_section *section;
775   unsigned int shnum;
776   size_t shdr_offset;
777   size_t sh_offset;
778   size_t sh_name;
779   unsigned char zero;
780 
781   if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err))
782     return errmsg;
783 
784   cl = attrs->ei_class;
785   if (cl == ELFCLASS32)
786     {
787       ehdr_size = sizeof (Elf32_External_Ehdr);
788       shdr_size = sizeof (Elf32_External_Shdr);
789     }
790   else
791     {
792       ehdr_size = sizeof (Elf64_External_Ehdr);
793       shdr_size = sizeof (Elf64_External_Shdr);
794     }
795 
796   shnum = 0;
797   for (section = sobj->sections; section != NULL; section = section->next)
798     ++shnum;
799   if (shnum == 0)
800     return NULL;
801 
802   /* Add initial dummy Shdr and .shstrtab.  */
803   shnum += 2;
804 
805   shdr_offset = ehdr_size;
806   sh_offset = shdr_offset + shnum * shdr_size;
807 
808   if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
809 				     0, 0, 0, 0, 0, 0, &errmsg, err))
810     return errmsg;
811 
812   shdr_offset += shdr_size;
813 
814   sh_name = 1;
815   for (section = sobj->sections; section != NULL; section = section->next)
816     {
817       size_t mask;
818       size_t new_sh_offset;
819       size_t sh_size;
820       struct simple_object_write_section_buffer *buffer;
821 
822       mask = (1U << section->align) - 1;
823       new_sh_offset = sh_offset + mask;
824       new_sh_offset &= ~ mask;
825       while (new_sh_offset > sh_offset)
826 	{
827 	  unsigned char zeroes[16];
828 	  size_t write;
829 
830 	  memset (zeroes, 0, sizeof zeroes);
831 	  write = new_sh_offset - sh_offset;
832 	  if (write > sizeof zeroes)
833 	    write = sizeof zeroes;
834 	  if (!simple_object_internal_write (descriptor, sh_offset, zeroes,
835 					     write, &errmsg, err))
836 	    return errmsg;
837 	  sh_offset += write;
838 	}
839 
840       sh_size = 0;
841       for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
842 	{
843 	  if (!simple_object_internal_write (descriptor, sh_offset + sh_size,
844 					     ((const unsigned char *)
845 					      buffer->buffer),
846 					     buffer->size, &errmsg, err))
847 	    return errmsg;
848 	  sh_size += buffer->size;
849 	}
850 
851       if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
852 					 sh_name, SHT_PROGBITS, 0, sh_offset,
853 					 sh_size, 1U << section->align,
854 					 &errmsg, err))
855 	return errmsg;
856 
857       shdr_offset += shdr_size;
858       sh_name += strlen (section->name) + 1;
859       sh_offset += sh_size;
860     }
861 
862   if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
863 				     sh_name, SHT_STRTAB, 0, sh_offset,
864 				     sh_name + strlen (".shstrtab") + 1,
865 				     1, &errmsg, err))
866     return errmsg;
867 
868   /* .shstrtab has a leading zero byte.  */
869   zero = 0;
870   if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1,
871 				     &errmsg, err))
872     return errmsg;
873   ++sh_offset;
874 
875   for (section = sobj->sections; section != NULL; section = section->next)
876     {
877       size_t len;
878 
879       len = strlen (section->name) + 1;
880       if (!simple_object_internal_write (descriptor, sh_offset,
881 					 (const unsigned char *) section->name,
882 					 len, &errmsg, err))
883 	return errmsg;
884       sh_offset += len;
885     }
886 
887   if (!simple_object_internal_write (descriptor, sh_offset,
888 				     (const unsigned char *) ".shstrtab",
889 				     strlen (".shstrtab") + 1, &errmsg, err))
890     return errmsg;
891 
892   return NULL;
893 }
894 
895 /* Release the private data for an simple_object_write structure.  */
896 
897 static void
898 simple_object_elf_release_write (void *data)
899 {
900   XDELETE (data);
901 }
902 
903 /* The ELF functions.  */
904 
905 const struct simple_object_functions simple_object_elf_functions =
906 {
907   simple_object_elf_match,
908   simple_object_elf_find_sections,
909   simple_object_elf_fetch_attributes,
910   simple_object_elf_release_read,
911   simple_object_elf_attributes_compare,
912   simple_object_elf_release_attributes,
913   simple_object_elf_start_write,
914   simple_object_elf_write_to_file,
915   simple_object_elf_release_write
916 };
917