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