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