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 };
954