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
5This program is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 51 Franklin Street - Fifth Floor,
18Boston, 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
49typedef 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
68typedef 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
125typedef 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
138typedef 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
151typedef 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
166typedef 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
187struct 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
197static 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
207static 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
219static 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
229static 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
306struct 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
330struct 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
348static void *
349simple_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
482static const char *
483simple_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
577static void *
578simple_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
598static void
599simple_object_elf_release_read (void *data)
600{
601  XDELETE (data);
602}
603
604/* Compare two attributes structures.  */
605
606static const char *
607simple_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
626static void
627simple_object_elf_release_attributes (void *data)
628{
629  XDELETE (data);
630}
631
632/* Prepare to write out a file.  */
633
634static void *
635simple_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
652static int
653simple_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
719static int
720simple_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
764static const char *
765simple_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
897static void
898simple_object_elf_release_write (void *data)
899{
900  XDELETE (data);
901}
902
903/* The ELF functions.  */
904
905const 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