Home | History | Annotate | Line # | Download | only in libiberty
      1   1.1  christos /* simple-object-elf.c -- routines to manipulate ELF object files.
      2  1.10  christos    Copyright (C) 2010-2025 Free Software Foundation, Inc.
      3   1.1  christos    Written by Ian Lance Taylor, Google.
      4   1.1  christos 
      5   1.1  christos This program is free software; you can redistribute it and/or modify it
      6   1.1  christos under the terms of the GNU General Public License as published by the
      7   1.1  christos Free Software Foundation; either version 2, or (at your option) any
      8   1.1  christos later version.
      9   1.1  christos 
     10   1.1  christos This program is distributed in the hope that it will be useful,
     11   1.1  christos but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   1.1  christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   1.1  christos GNU General Public License for more details.
     14   1.1  christos 
     15   1.1  christos You should have received a copy of the GNU General Public License
     16   1.1  christos along with this program; if not, write to the Free Software
     17   1.1  christos Foundation, 51 Franklin Street - Fifth Floor,
     18   1.1  christos Boston, MA 02110-1301, USA.  */
     19   1.1  christos 
     20   1.1  christos #include "config.h"
     21   1.1  christos #include "libiberty.h"
     22   1.1  christos #include "simple-object.h"
     23   1.1  christos 
     24   1.1  christos #include <errno.h>
     25   1.7  christos /* mingw.org's MinGW doesn't have ENOTSUP.  */
     26   1.7  christos #ifndef ENOTSUP
     27   1.7  christos # define ENOTSUP ENOSYS
     28   1.7  christos #endif
     29   1.1  christos #include <stddef.h>
     30   1.1  christos 
     31   1.1  christos #ifdef HAVE_STDLIB_H
     32   1.1  christos #include <stdlib.h>
     33   1.1  christos #endif
     34   1.1  christos 
     35   1.1  christos #ifdef HAVE_STDINT_H
     36   1.1  christos #include <stdint.h>
     37   1.1  christos #endif
     38   1.1  christos 
     39   1.1  christos #ifdef HAVE_STRING_H
     40   1.1  christos #include <string.h>
     41   1.1  christos #endif
     42   1.1  christos 
     43   1.1  christos #ifdef HAVE_INTTYPES_H
     44   1.1  christos #include <inttypes.h>
     45   1.1  christos #endif
     46   1.1  christos 
     47   1.1  christos #include "simple-object-common.h"
     48   1.1  christos 
     49   1.1  christos /* ELF structures and constants.  */
     50   1.1  christos 
     51   1.1  christos /* 32-bit ELF file header.  */
     52   1.1  christos 
     53   1.1  christos typedef struct {
     54   1.1  christos   unsigned char	e_ident[16];		/* ELF "magic number" */
     55   1.1  christos   unsigned char	e_type[2];		/* Identifies object file type */
     56   1.1  christos   unsigned char	e_machine[2];		/* Specifies required architecture */
     57   1.1  christos   unsigned char	e_version[4];		/* Identifies object file version */
     58   1.1  christos   unsigned char	e_entry[4];		/* Entry point virtual address */
     59   1.1  christos   unsigned char	e_phoff[4];		/* Program header table file offset */
     60   1.1  christos   unsigned char	e_shoff[4];		/* Section header table file offset */
     61   1.1  christos   unsigned char	e_flags[4];		/* Processor-specific flags */
     62   1.1  christos   unsigned char	e_ehsize[2];		/* ELF header size in bytes */
     63   1.1  christos   unsigned char	e_phentsize[2];		/* Program header table entry size */
     64   1.1  christos   unsigned char	e_phnum[2];		/* Program header table entry count */
     65   1.1  christos   unsigned char	e_shentsize[2];		/* Section header table entry size */
     66   1.1  christos   unsigned char	e_shnum[2];		/* Section header table entry count */
     67   1.1  christos   unsigned char	e_shstrndx[2];		/* Section header string table index */
     68   1.1  christos } Elf32_External_Ehdr;
     69   1.1  christos 
     70   1.1  christos /* 64-bit ELF file header.  */
     71   1.1  christos 
     72   1.1  christos typedef struct {
     73   1.1  christos   unsigned char	e_ident[16];		/* ELF "magic number" */
     74   1.1  christos   unsigned char	e_type[2];		/* Identifies object file type */
     75   1.1  christos   unsigned char	e_machine[2];		/* Specifies required architecture */
     76   1.1  christos   unsigned char	e_version[4];		/* Identifies object file version */
     77   1.1  christos   unsigned char	e_entry[8];		/* Entry point virtual address */
     78   1.1  christos   unsigned char	e_phoff[8];		/* Program header table file offset */
     79   1.1  christos   unsigned char	e_shoff[8];		/* Section header table file offset */
     80   1.1  christos   unsigned char	e_flags[4];		/* Processor-specific flags */
     81   1.1  christos   unsigned char	e_ehsize[2];		/* ELF header size in bytes */
     82   1.1  christos   unsigned char	e_phentsize[2];		/* Program header table entry size */
     83   1.1  christos   unsigned char	e_phnum[2];		/* Program header table entry count */
     84   1.1  christos   unsigned char	e_shentsize[2];		/* Section header table entry size */
     85   1.1  christos   unsigned char	e_shnum[2];		/* Section header table entry count */
     86   1.1  christos   unsigned char	e_shstrndx[2];		/* Section header string table index */
     87   1.1  christos } Elf64_External_Ehdr;
     88   1.1  christos 
     89   1.1  christos /* Indexes and values in e_ident field of Ehdr.  */
     90   1.1  christos 
     91   1.1  christos #define EI_MAG0		0	/* File identification byte 0 index */
     92   1.1  christos #define ELFMAG0		   0x7F	/* Magic number byte 0 */
     93   1.1  christos 
     94   1.1  christos #define EI_MAG1		1	/* File identification byte 1 index */
     95   1.1  christos #define ELFMAG1		    'E'	/* Magic number byte 1 */
     96   1.1  christos 
     97   1.1  christos #define EI_MAG2		2	/* File identification byte 2 index */
     98   1.1  christos #define ELFMAG2		    'L'	/* Magic number byte 2 */
     99   1.1  christos 
    100   1.1  christos #define EI_MAG3		3	/* File identification byte 3 index */
    101   1.1  christos #define ELFMAG3		    'F'	/* Magic number byte 3 */
    102   1.1  christos 
    103   1.1  christos #define EI_CLASS	4	/* File class */
    104   1.1  christos #define ELFCLASSNONE	      0	/* Invalid class */
    105   1.1  christos #define ELFCLASS32	      1	/* 32-bit objects */
    106   1.1  christos #define ELFCLASS64	      2	/* 64-bit objects */
    107   1.1  christos 
    108   1.1  christos #define EI_DATA		5	/* Data encoding */
    109   1.1  christos #define ELFDATANONE	      0	/* Invalid data encoding */
    110   1.1  christos #define ELFDATA2LSB	      1	/* 2's complement, little endian */
    111   1.1  christos #define ELFDATA2MSB	      2	/* 2's complement, big endian */
    112   1.1  christos 
    113   1.1  christos #define EI_VERSION	6	/* File version */
    114   1.1  christos #define EV_CURRENT	1		/* Current version */
    115   1.1  christos 
    116   1.1  christos #define EI_OSABI	7	/* Operating System/ABI indication */
    117   1.1  christos 
    118   1.1  christos /* Values for e_type field of Ehdr.  */
    119   1.1  christos 
    120   1.1  christos #define ET_REL		1	/* Relocatable file */
    121   1.1  christos 
    122   1.1  christos /* Values for e_machine field of Ehdr.  */
    123   1.1  christos 
    124   1.1  christos #define EM_SPARC	  2	/* SUN SPARC */
    125   1.1  christos #define EM_SPARC32PLUS	 18	/* Sun's "v8plus" */
    126   1.1  christos 
    127   1.1  christos /* Special section index values.  */
    128   1.1  christos 
    129   1.6  christos #define SHN_UNDEF	0		/* Undefined section */
    130   1.1  christos #define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
    131  1.10  christos #define SHN_COMMON	0xFFF2		/* Associated symbol is in common */
    132   1.1  christos #define SHN_XINDEX	0xFFFF		/* Section index is held elsewhere */
    133  1.10  christos #define SHN_HIRESERVE	0xFFFF		/* End of reserved indices */
    134   1.6  christos 
    135   1.1  christos 
    136   1.1  christos /* 32-bit ELF program header.  */
    137   1.1  christos 
    138   1.1  christos typedef struct {
    139   1.1  christos   unsigned char	p_type[4];		/* Identifies program segment type */
    140   1.1  christos   unsigned char	p_offset[4];		/* Segment file offset */
    141   1.1  christos   unsigned char	p_vaddr[4];		/* Segment virtual address */
    142   1.1  christos   unsigned char	p_paddr[4];		/* Segment physical address */
    143   1.1  christos   unsigned char	p_filesz[4];		/* Segment size in file */
    144   1.1  christos   unsigned char	p_memsz[4];		/* Segment size in memory */
    145   1.1  christos   unsigned char	p_flags[4];		/* Segment flags */
    146   1.1  christos   unsigned char	p_align[4];		/* Segment alignment, file & memory */
    147   1.1  christos } Elf32_External_Phdr;
    148   1.1  christos 
    149   1.1  christos /* 64-bit ELF program header.  */
    150   1.1  christos 
    151   1.1  christos typedef struct {
    152   1.1  christos   unsigned char	p_type[4];		/* Identifies program segment type */
    153   1.1  christos   unsigned char	p_flags[4];		/* Segment flags */
    154   1.1  christos   unsigned char	p_offset[8];		/* Segment file offset */
    155   1.1  christos   unsigned char	p_vaddr[8];		/* Segment virtual address */
    156   1.1  christos   unsigned char	p_paddr[8];		/* Segment physical address */
    157   1.1  christos   unsigned char	p_filesz[8];		/* Segment size in file */
    158   1.1  christos   unsigned char	p_memsz[8];		/* Segment size in memory */
    159   1.1  christos   unsigned char	p_align[8];		/* Segment alignment, file & memory */
    160   1.1  christos } Elf64_External_Phdr;
    161   1.1  christos 
    162   1.1  christos /* 32-bit ELF section header */
    163   1.1  christos 
    164   1.1  christos typedef struct {
    165   1.1  christos   unsigned char	sh_name[4];		/* Section name, index in string tbl */
    166   1.1  christos   unsigned char	sh_type[4];		/* Type of section */
    167   1.1  christos   unsigned char	sh_flags[4];		/* Miscellaneous section attributes */
    168   1.1  christos   unsigned char	sh_addr[4];		/* Section virtual addr at execution */
    169   1.1  christos   unsigned char	sh_offset[4];		/* Section file offset */
    170   1.1  christos   unsigned char	sh_size[4];		/* Size of section in bytes */
    171   1.1  christos   unsigned char	sh_link[4];		/* Index of another section */
    172   1.1  christos   unsigned char	sh_info[4];		/* Additional section information */
    173   1.1  christos   unsigned char	sh_addralign[4];	/* Section alignment */
    174   1.1  christos   unsigned char	sh_entsize[4];		/* Entry size if section holds table */
    175   1.1  christos } Elf32_External_Shdr;
    176   1.1  christos 
    177   1.1  christos /* 64-bit ELF section header.  */
    178   1.1  christos 
    179   1.1  christos typedef struct {
    180   1.1  christos   unsigned char	sh_name[4];		/* Section name, index in string tbl */
    181   1.1  christos   unsigned char	sh_type[4];		/* Type of section */
    182   1.1  christos   unsigned char	sh_flags[8];		/* Miscellaneous section attributes */
    183   1.1  christos   unsigned char	sh_addr[8];		/* Section virtual addr at execution */
    184   1.1  christos   unsigned char	sh_offset[8];		/* Section file offset */
    185   1.1  christos   unsigned char	sh_size[8];		/* Size of section in bytes */
    186   1.1  christos   unsigned char	sh_link[4];		/* Index of another section */
    187   1.1  christos   unsigned char	sh_info[4];		/* Additional section information */
    188   1.1  christos   unsigned char	sh_addralign[8];	/* Section alignment */
    189   1.1  christos   unsigned char	sh_entsize[8];		/* Entry size if section holds table */
    190   1.1  christos } Elf64_External_Shdr;
    191   1.1  christos 
    192   1.1  christos /* Values for sh_type field.  */
    193   1.1  christos 
    194   1.6  christos #define SHT_NULL	0		/* Section header table entry unused */
    195   1.1  christos #define SHT_PROGBITS	1		/* Program data */
    196   1.6  christos #define SHT_SYMTAB	2		/* Link editing symbol table */
    197   1.1  christos #define SHT_STRTAB	3		/* A string table */
    198   1.6  christos #define SHT_RELA	4		/* Relocation entries with addends */
    199   1.6  christos #define SHT_REL		9		/* Relocation entries, no addends */
    200   1.6  christos #define SHT_GROUP	17		/* Section contains a section group */
    201   1.6  christos #define SHT_SYMTAB_SHNDX 18		/* Extended section indeces */
    202   1.6  christos 
    203   1.6  christos /* Values for sh_flags field.  */
    204   1.6  christos 
    205   1.6  christos #define SHF_INFO_LINK	0x00000040	/* `sh_info' contains SHT index */
    206   1.6  christos #define SHF_EXECINSTR	0x00000004	/* Executable section.  */
    207   1.6  christos #define SHF_EXCLUDE	0x80000000	/* Link editor is to exclude this
    208   1.6  christos 					   section from executable and
    209   1.6  christos 					   shared library that it builds
    210   1.6  christos 					   when those objects are not to be
    211   1.6  christos 					   further relocated.  */
    212   1.6  christos /* Symbol table entry.  */
    213   1.6  christos 
    214   1.6  christos typedef struct
    215   1.6  christos {
    216   1.6  christos   unsigned char st_name[4];                /* Symbol name (string tbl index) */
    217   1.6  christos   unsigned char st_value[4];               /* Symbol value */
    218   1.6  christos   unsigned char st_size[4];                /* Symbol size */
    219   1.6  christos   unsigned char st_info;                /* Symbol type and binding */
    220   1.6  christos   unsigned char st_other;               /* Symbol visibility */
    221   1.6  christos   unsigned char st_shndx[2];               /* Section index */
    222   1.6  christos } Elf32_External_Sym;
    223   1.6  christos 
    224   1.6  christos typedef struct
    225   1.6  christos {
    226   1.6  christos   unsigned char st_name[4];                /* Symbol name (string tbl index) */
    227   1.6  christos   unsigned char st_info;                /* Symbol type and binding */
    228   1.6  christos   unsigned char st_other;               /* Symbol visibility */
    229   1.6  christos   unsigned char st_shndx[2];               /* Section index */
    230   1.6  christos   unsigned char st_value[8];               /* Symbol value */
    231   1.6  christos   unsigned char st_size[8];                /* Symbol size */
    232   1.6  christos } Elf64_External_Sym;
    233   1.6  christos 
    234   1.6  christos #define ELF_ST_BIND(val)              (((unsigned char) (val)) >> 4)
    235   1.6  christos #define ELF_ST_TYPE(val)              ((val) & 0xf)
    236   1.6  christos #define ELF_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
    237   1.6  christos 
    238   1.6  christos #define STT_NOTYPE	0	/* Symbol type is unspecified */
    239   1.6  christos #define STT_OBJECT	1	/* Symbol is a data object */
    240   1.6  christos #define STT_FUNC	2	/* Symbol is a code object */
    241   1.6  christos #define STT_TLS		6	/* Thread local data object */
    242   1.6  christos #define STT_GNU_IFUNC	10	/* Symbol is an indirect code object */
    243   1.6  christos 
    244   1.6  christos #define STB_LOCAL	0	/* Local symbol */
    245   1.6  christos #define STB_GLOBAL	1	/* Global symbol */
    246   1.6  christos #define STB_WEAK	2	/* Weak global */
    247   1.6  christos 
    248   1.6  christos #define STV_DEFAULT	0	/* Visibility is specified by binding type */
    249   1.6  christos #define STV_HIDDEN	2	/* Can only be seen inside currect component */
    250   1.1  christos 
    251   1.1  christos /* Functions to fetch and store different ELF types, depending on the
    252   1.1  christos    endianness and size.  */
    253   1.1  christos 
    254   1.1  christos struct elf_type_functions
    255   1.1  christos {
    256   1.1  christos   unsigned short (*fetch_Elf_Half) (const unsigned char *);
    257   1.1  christos   unsigned int (*fetch_Elf_Word) (const unsigned char *);
    258   1.1  christos   ulong_type (*fetch_Elf_Addr) (const unsigned char *);
    259   1.1  christos   void (*set_Elf_Half) (unsigned char *, unsigned short);
    260   1.1  christos   void (*set_Elf_Word) (unsigned char *, unsigned int);
    261   1.1  christos   void (*set_Elf_Addr) (unsigned char *, ulong_type);
    262   1.1  christos };
    263   1.1  christos 
    264   1.1  christos static const struct elf_type_functions elf_big_32_functions =
    265   1.1  christos {
    266   1.1  christos   simple_object_fetch_big_16,
    267   1.1  christos   simple_object_fetch_big_32,
    268   1.1  christos   simple_object_fetch_big_32_ulong,
    269   1.1  christos   simple_object_set_big_16,
    270   1.1  christos   simple_object_set_big_32,
    271   1.1  christos   simple_object_set_big_32_ulong
    272   1.1  christos };
    273   1.1  christos 
    274   1.1  christos static const struct elf_type_functions elf_little_32_functions =
    275   1.1  christos {
    276   1.1  christos   simple_object_fetch_little_16,
    277   1.1  christos   simple_object_fetch_little_32,
    278   1.1  christos   simple_object_fetch_little_32_ulong,
    279   1.1  christos   simple_object_set_little_16,
    280   1.1  christos   simple_object_set_little_32,
    281   1.1  christos   simple_object_set_little_32_ulong
    282   1.1  christos };
    283   1.1  christos 
    284   1.1  christos #ifdef UNSIGNED_64BIT_TYPE
    285   1.1  christos 
    286   1.1  christos static const struct elf_type_functions elf_big_64_functions =
    287   1.1  christos {
    288   1.1  christos   simple_object_fetch_big_16,
    289   1.1  christos   simple_object_fetch_big_32,
    290   1.1  christos   simple_object_fetch_big_64,
    291   1.1  christos   simple_object_set_big_16,
    292   1.1  christos   simple_object_set_big_32,
    293   1.1  christos   simple_object_set_big_64
    294   1.1  christos };
    295   1.1  christos 
    296   1.1  christos static const struct elf_type_functions elf_little_64_functions =
    297   1.1  christos {
    298   1.1  christos   simple_object_fetch_little_16,
    299   1.1  christos   simple_object_fetch_little_32,
    300   1.1  christos   simple_object_fetch_little_64,
    301   1.1  christos   simple_object_set_little_16,
    302   1.1  christos   simple_object_set_little_32,
    303   1.1  christos   simple_object_set_little_64
    304   1.1  christos };
    305   1.1  christos 
    306   1.1  christos #endif
    307   1.1  christos 
    308   1.1  christos /* Hideous macro to fetch the value of a field from an external ELF
    309   1.1  christos    struct of some sort.  TYPEFUNCS is the set of type functions.
    310   1.1  christos    BUFFER points to the external data.  STRUCTTYPE is the appropriate
    311   1.1  christos    struct type.  FIELD is a field within the struct.  TYPE is the type
    312   1.1  christos    of the field in the struct: Elf_Half, Elf_Word, or Elf_Addr.  */
    313   1.1  christos 
    314   1.1  christos #define ELF_FETCH_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE) \
    315   1.1  christos   ((TYPEFUNCS)->fetch_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD)))
    316   1.1  christos 
    317   1.1  christos /* Even more hideous macro to fetch the value of FIELD from BUFFER.
    318   1.1  christos    SIZE is 32 or 64.  STRUCTTYPE is the name of the struct from
    319   1.1  christos    elf/external.h: Ehdr, Shdr, etc.  FIELD is the name of a field in
    320   1.1  christos    the struct.  TYPE is the type of the field in the struct: Elf_Half,
    321   1.1  christos    Elf_Word, or Elf_Addr.  */
    322   1.1  christos 
    323   1.1  christos #define ELF_FETCH_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER,	\
    324   1.1  christos 			      FIELD, TYPE)				\
    325   1.1  christos   ELF_FETCH_STRUCT_FIELD (TYPEFUNCS,					\
    326   1.1  christos 			  Elf ## SIZE ## _External_ ## STRUCTTYPE,	\
    327   1.1  christos 			  FIELD, BUFFER, TYPE)
    328   1.1  christos 
    329   1.1  christos /* Like ELF_FETCH_SIZED_FIELD but taking an ELFCLASS value.  */
    330   1.1  christos 
    331   1.1  christos #define ELF_FETCH_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER,		\
    332   1.1  christos 			FIELD, TYPE)					\
    333   1.1  christos   ((CLASS) == ELFCLASS32						\
    334   1.1  christos     ? ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD,	\
    335   1.1  christos 			     TYPE)					\
    336   1.1  christos     : ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD,	\
    337   1.1  christos 			     TYPE))
    338   1.1  christos 
    339   1.1  christos /* Hideous macro to set the value of a field in an external ELF
    340   1.1  christos    structure to VAL.  TYPEFUNCS is the set of type functions.  BUFFER
    341   1.1  christos    points to the external data.  STRUCTTYPE is the appropriate
    342   1.1  christos    structure type.  FIELD is a field within the struct.  TYPE is the
    343   1.1  christos    type of the field in the struct: Elf_Half, Elf_Word, or
    344   1.1  christos    Elf_Addr.  */
    345   1.1  christos 
    346   1.1  christos #define ELF_SET_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE, VAL) \
    347   1.1  christos   (TYPEFUNCS)->set_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD), (VAL))
    348   1.1  christos 
    349   1.1  christos /* Even more hideous macro to set the value of FIELD in BUFFER to VAL.
    350   1.1  christos    SIZE is 32 or 64.  STRUCTTYPE is the name of the struct from
    351   1.1  christos    elf/external.h: Ehdr, Shdr, etc.  FIELD is the name of a field in
    352   1.1  christos    the struct.  TYPE is the type of the field in the struct: Elf_Half,
    353   1.1  christos    Elf_Word, or Elf_Addr.  */
    354   1.1  christos 
    355   1.1  christos #define ELF_SET_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER, FIELD, \
    356   1.1  christos 			    TYPE, VAL)					\
    357   1.1  christos   ELF_SET_STRUCT_FIELD (TYPEFUNCS,					\
    358   1.1  christos 			Elf ## SIZE ## _External_ ## STRUCTTYPE,	\
    359   1.1  christos 			FIELD, BUFFER, TYPE, VAL)
    360   1.1  christos 
    361   1.1  christos /* Like ELF_SET_SIZED_FIELD but taking an ELFCLASS value.  */
    362   1.1  christos 
    363   1.1  christos #define ELF_SET_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER, FIELD,	\
    364   1.1  christos 		      TYPE, VAL)					\
    365   1.1  christos   ((CLASS) == ELFCLASS32						\
    366   1.1  christos     ? ELF_SET_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD,	\
    367   1.1  christos 			   TYPE, VAL)					\
    368   1.1  christos     : ELF_SET_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD,	\
    369   1.1  christos 			   TYPE, VAL))
    370   1.1  christos 
    371   1.1  christos /* Private data for an simple_object_read.  */
    372   1.1  christos 
    373   1.1  christos struct simple_object_elf_read
    374   1.1  christos {
    375   1.1  christos   /* Type functions.  */
    376   1.1  christos   const struct elf_type_functions* type_functions;
    377   1.1  christos   /* Elf data.  */
    378   1.1  christos   unsigned char ei_data;
    379   1.1  christos   /* Elf class.  */
    380   1.1  christos   unsigned char ei_class;
    381   1.1  christos   /* ELF OS ABI.  */
    382   1.1  christos   unsigned char ei_osabi;
    383   1.1  christos   /* Elf machine number.  */
    384   1.1  christos   unsigned short machine;
    385   1.1  christos   /* Processor specific flags.  */
    386   1.1  christos   unsigned int flags;
    387   1.1  christos   /* File offset of section headers.  */
    388   1.1  christos   ulong_type shoff;
    389   1.1  christos   /* Number of sections.  */
    390   1.1  christos   unsigned int shnum;
    391   1.1  christos   /* Index of string table section header.  */
    392   1.1  christos   unsigned int shstrndx;
    393   1.1  christos };
    394   1.1  christos 
    395   1.1  christos /* Private data for an simple_object_attributes.  */
    396   1.1  christos 
    397   1.1  christos struct simple_object_elf_attributes
    398   1.1  christos {
    399   1.1  christos   /* Type functions.  */
    400   1.1  christos   const struct elf_type_functions* type_functions;
    401   1.1  christos   /* Elf data.  */
    402   1.1  christos   unsigned char ei_data;
    403   1.1  christos   /* Elf class.  */
    404   1.1  christos   unsigned char ei_class;
    405   1.1  christos   /* ELF OS ABI.  */
    406   1.1  christos   unsigned char ei_osabi;
    407   1.1  christos   /* Elf machine number.  */
    408   1.1  christos   unsigned short machine;
    409   1.1  christos   /* Processor specific flags.  */
    410   1.1  christos   unsigned int flags;
    411   1.1  christos };
    412   1.1  christos 
    413   1.6  christos /* Private data for an simple_object_write.  */
    414   1.6  christos 
    415   1.6  christos struct simple_object_elf_write
    416   1.6  christos {
    417   1.6  christos   struct simple_object_elf_attributes attrs;
    418   1.6  christos   unsigned char *shdrs;
    419   1.6  christos };
    420   1.6  christos 
    421   1.1  christos /* See if we have an ELF file.  */
    422   1.1  christos 
    423   1.1  christos static void *
    424   1.1  christos simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
    425   1.1  christos 			 int descriptor, off_t offset,
    426   1.1  christos 			 const char *segment_name ATTRIBUTE_UNUSED,
    427   1.1  christos 			 const char **errmsg, int *err)
    428   1.1  christos {
    429   1.1  christos   unsigned char ei_data;
    430   1.1  christos   unsigned char ei_class;
    431   1.1  christos   const struct elf_type_functions *type_functions;
    432   1.1  christos   unsigned char ehdr[sizeof (Elf64_External_Ehdr)];
    433   1.1  christos   struct simple_object_elf_read *eor;
    434   1.1  christos 
    435   1.1  christos   if (header[EI_MAG0] != ELFMAG0
    436   1.1  christos       || header[EI_MAG1] != ELFMAG1
    437   1.1  christos       || header[EI_MAG2] != ELFMAG2
    438   1.1  christos       || header[EI_MAG3] != ELFMAG3
    439   1.1  christos       || header[EI_VERSION] != EV_CURRENT)
    440   1.1  christos     {
    441   1.1  christos       *errmsg = NULL;
    442   1.1  christos       *err = 0;
    443   1.1  christos       return NULL;
    444   1.1  christos     }
    445   1.1  christos 
    446   1.1  christos   ei_data = header[EI_DATA];
    447   1.1  christos   if (ei_data != ELFDATA2LSB && ei_data != ELFDATA2MSB)
    448   1.1  christos     {
    449   1.1  christos       *errmsg = "unknown ELF endianness";
    450   1.1  christos       *err = 0;
    451   1.1  christos       return NULL;
    452   1.1  christos     }
    453   1.1  christos 
    454   1.1  christos   ei_class = header[EI_CLASS];
    455   1.1  christos   switch (ei_class)
    456   1.1  christos     {
    457   1.1  christos     case ELFCLASS32:
    458   1.1  christos       type_functions = (ei_data == ELFDATA2LSB
    459   1.1  christos 			? &elf_little_32_functions
    460   1.1  christos 			: &elf_big_32_functions);
    461   1.1  christos       break;
    462   1.1  christos 
    463   1.1  christos     case ELFCLASS64:
    464   1.1  christos #ifndef UNSIGNED_64BIT_TYPE
    465   1.1  christos       *errmsg = "64-bit ELF objects not supported";
    466   1.1  christos       *err = 0;
    467   1.1  christos       return NULL;
    468   1.1  christos #else
    469   1.1  christos       type_functions = (ei_data == ELFDATA2LSB
    470   1.1  christos 			? &elf_little_64_functions
    471   1.1  christos 			: &elf_big_64_functions);
    472   1.1  christos       break;
    473   1.1  christos #endif
    474   1.1  christos 
    475   1.1  christos     default:
    476   1.1  christos       *errmsg = "unrecognized ELF size";
    477   1.1  christos       *err = 0;
    478   1.1  christos       return NULL;
    479   1.1  christos     }
    480   1.1  christos 
    481   1.1  christos   if (!simple_object_internal_read (descriptor, offset, ehdr, sizeof ehdr,
    482   1.1  christos 				    errmsg, err))
    483   1.1  christos     return NULL;
    484   1.1  christos 
    485   1.1  christos   eor = XNEW (struct simple_object_elf_read);
    486   1.1  christos   eor->type_functions = type_functions;
    487   1.1  christos   eor->ei_data = ei_data;
    488   1.1  christos   eor->ei_class = ei_class;
    489   1.1  christos   eor->ei_osabi = header[EI_OSABI];
    490   1.1  christos   eor->machine = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
    491   1.1  christos 				  e_machine, Elf_Half);
    492   1.1  christos   eor->flags = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
    493   1.1  christos 				e_flags, Elf_Word);
    494   1.1  christos   eor->shoff = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
    495   1.1  christos 				e_shoff, Elf_Addr);
    496   1.1  christos   eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
    497   1.1  christos 				e_shnum, Elf_Half);
    498   1.1  christos   eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr,
    499   1.1  christos 				   e_shstrndx, Elf_Half);
    500   1.1  christos 
    501   1.1  christos   if ((eor->shnum == 0 || eor->shstrndx == SHN_XINDEX)
    502   1.1  christos       && eor->shoff != 0)
    503   1.1  christos     {
    504   1.1  christos       unsigned char shdr[sizeof (Elf64_External_Shdr)];
    505   1.1  christos 
    506   1.1  christos       /* Object file has more than 0xffff sections.  */
    507   1.1  christos 
    508   1.1  christos       if (!simple_object_internal_read (descriptor, offset + eor->shoff, shdr,
    509   1.1  christos 					(ei_class == ELFCLASS32
    510   1.1  christos 					 ? sizeof (Elf32_External_Shdr)
    511   1.1  christos 					 : sizeof (Elf64_External_Shdr)),
    512   1.1  christos 					errmsg, err))
    513   1.1  christos 	{
    514   1.1  christos 	  XDELETE (eor);
    515   1.1  christos 	  return NULL;
    516   1.1  christos 	}
    517   1.1  christos 
    518   1.1  christos       if (eor->shnum == 0)
    519   1.1  christos 	eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    520   1.1  christos 				      shdr, sh_size, Elf_Addr);
    521   1.1  christos 
    522   1.1  christos       if (eor->shstrndx == SHN_XINDEX)
    523   1.1  christos 	{
    524   1.1  christos 	  eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    525   1.1  christos 					   shdr, sh_link, Elf_Word);
    526   1.1  christos 
    527   1.1  christos 	  /* Versions of the GNU binutils between 2.12 and 2.18 did
    528   1.1  christos 	     not handle objects with more than SHN_LORESERVE sections
    529   1.1  christos 	     correctly.  All large section indexes were offset by
    530   1.1  christos 	     0x100.  There is more information at
    531   1.8  christos 	     https://sourceware.org/PR5900 .
    532   1.1  christos 	     Fortunately these object files are easy to detect, as the
    533   1.1  christos 	     GNU binutils always put the section header string table
    534   1.1  christos 	     near the end of the list of sections.  Thus if the
    535   1.1  christos 	     section header string table index is larger than the
    536   1.1  christos 	     number of sections, then we know we have to subtract
    537   1.1  christos 	     0x100 to get the real section index.  */
    538   1.1  christos 	  if (eor->shstrndx >= eor->shnum
    539   1.1  christos 	      && eor->shstrndx >= SHN_LORESERVE + 0x100)
    540   1.1  christos 	    eor->shstrndx -= 0x100;
    541   1.1  christos 	}
    542   1.1  christos     }
    543   1.1  christos 
    544   1.1  christos   if (eor->shstrndx >= eor->shnum)
    545   1.1  christos     {
    546   1.1  christos       *errmsg = "invalid ELF shstrndx >= shnum";
    547   1.1  christos       *err = 0;
    548   1.1  christos       XDELETE (eor);
    549   1.1  christos       return NULL;
    550   1.1  christos     }
    551   1.7  christos 
    552   1.7  christos   if (eor->shstrndx == 0)
    553   1.7  christos     {
    554   1.7  christos       *errmsg = "invalid ELF shstrndx == 0";
    555   1.7  christos       *err = 0;
    556   1.7  christos       XDELETE (eor);
    557   1.7  christos       return NULL;
    558   1.7  christos     }
    559   1.7  christos 
    560   1.1  christos   return (void *) eor;
    561   1.1  christos }
    562   1.1  christos 
    563   1.1  christos /* Find all sections in an ELF file.  */
    564   1.1  christos 
    565   1.1  christos static const char *
    566   1.1  christos simple_object_elf_find_sections (simple_object_read *sobj,
    567   1.1  christos 				 int (*pfn) (void *, const char *,
    568   1.1  christos 					     off_t offset, off_t length),
    569   1.1  christos 				 void *data,
    570   1.1  christos 				 int *err)
    571   1.1  christos {
    572  1.10  christos   struct simple_object_elf_read *eor
    573  1.10  christos     = (struct simple_object_elf_read *) sobj->data;
    574   1.1  christos   const struct elf_type_functions *type_functions = eor->type_functions;
    575   1.1  christos   unsigned char ei_class = eor->ei_class;
    576   1.1  christos   size_t shdr_size;
    577   1.1  christos   unsigned int shnum;
    578   1.1  christos   unsigned char *shdrs;
    579   1.1  christos   const char *errmsg;
    580   1.1  christos   unsigned char *shstrhdr;
    581   1.1  christos   size_t name_size;
    582   1.1  christos   off_t shstroff;
    583   1.1  christos   unsigned char *names;
    584   1.1  christos   unsigned int i;
    585   1.1  christos 
    586   1.1  christos   shdr_size = (ei_class == ELFCLASS32
    587   1.1  christos 	       ? sizeof (Elf32_External_Shdr)
    588   1.1  christos 	       : sizeof (Elf64_External_Shdr));
    589   1.1  christos 
    590   1.1  christos   /* Read the section headers.  We skip section 0, which is not a
    591   1.1  christos      useful section.  */
    592   1.1  christos 
    593   1.1  christos   shnum = eor->shnum;
    594   1.1  christos   shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
    595   1.1  christos 
    596   1.1  christos   if (!simple_object_internal_read (sobj->descriptor,
    597   1.1  christos 				    sobj->offset + eor->shoff + shdr_size,
    598   1.1  christos 				    shdrs,
    599   1.1  christos 				    shdr_size * (shnum - 1),
    600   1.1  christos 				    &errmsg, err))
    601   1.1  christos     {
    602   1.1  christos       XDELETEVEC (shdrs);
    603   1.1  christos       return errmsg;
    604   1.1  christos     }
    605   1.1  christos 
    606   1.1  christos   /* Read the section names.  */
    607   1.1  christos 
    608   1.1  christos   shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size;
    609   1.1  christos   name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    610   1.1  christos 			       shstrhdr, sh_size, Elf_Addr);
    611   1.1  christos   shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    612   1.1  christos 			      shstrhdr, sh_offset, Elf_Addr);
    613   1.1  christos   names = XNEWVEC (unsigned char, name_size);
    614   1.1  christos   if (!simple_object_internal_read (sobj->descriptor,
    615   1.1  christos 				    sobj->offset + shstroff,
    616   1.1  christos 				    names, name_size, &errmsg, err))
    617   1.1  christos     {
    618   1.1  christos       XDELETEVEC (names);
    619   1.1  christos       XDELETEVEC (shdrs);
    620   1.1  christos       return errmsg;
    621   1.1  christos     }
    622   1.1  christos 
    623   1.1  christos   for (i = 1; i < shnum; ++i)
    624   1.1  christos     {
    625   1.1  christos       unsigned char *shdr;
    626   1.1  christos       unsigned int sh_name;
    627   1.1  christos       const char *name;
    628   1.1  christos       off_t offset;
    629   1.1  christos       off_t length;
    630   1.1  christos 
    631   1.1  christos       shdr = shdrs + (i - 1) * shdr_size;
    632   1.1  christos       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    633   1.1  christos 				 shdr, sh_name, Elf_Word);
    634   1.1  christos       if (sh_name >= name_size)
    635   1.1  christos 	{
    636   1.1  christos 	  *err = 0;
    637   1.1  christos 	  XDELETEVEC (names);
    638   1.1  christos 	  XDELETEVEC (shdrs);
    639   1.1  christos 	  return "ELF section name out of range";
    640   1.1  christos 	}
    641   1.1  christos 
    642   1.1  christos       name = (const char *) names + sh_name;
    643   1.1  christos       offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    644   1.1  christos 				shdr, sh_offset, Elf_Addr);
    645   1.1  christos       length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
    646   1.1  christos 				shdr, sh_size, Elf_Addr);
    647   1.1  christos 
    648   1.1  christos       if (!(*pfn) (data, name, offset, length))
    649   1.1  christos 	break;
    650   1.1  christos     }
    651   1.1  christos 
    652   1.1  christos   XDELETEVEC (names);
    653   1.1  christos   XDELETEVEC (shdrs);
    654   1.1  christos 
    655   1.1  christos   return NULL;
    656   1.1  christos }
    657   1.1  christos 
    658   1.1  christos /* Fetch the attributes for an simple_object_read.  */
    659   1.1  christos 
    660   1.1  christos static void *
    661   1.1  christos simple_object_elf_fetch_attributes (simple_object_read *sobj,
    662   1.1  christos 				    const char **errmsg ATTRIBUTE_UNUSED,
    663   1.1  christos 				    int *err ATTRIBUTE_UNUSED)
    664   1.1  christos {
    665  1.10  christos   struct simple_object_elf_read *eor
    666  1.10  christos     = (struct simple_object_elf_read *) sobj->data;
    667   1.1  christos   struct simple_object_elf_attributes *ret;
    668   1.1  christos 
    669   1.1  christos   ret = XNEW (struct simple_object_elf_attributes);
    670   1.1  christos   ret->type_functions = eor->type_functions;
    671   1.1  christos   ret->ei_data = eor->ei_data;
    672   1.1  christos   ret->ei_class = eor->ei_class;
    673   1.1  christos   ret->ei_osabi = eor->ei_osabi;
    674   1.1  christos   ret->machine = eor->machine;
    675   1.1  christos   ret->flags = eor->flags;
    676   1.1  christos   return ret;
    677   1.1  christos }
    678   1.1  christos 
    679   1.1  christos /* Release the privata data for an simple_object_read.  */
    680   1.1  christos 
    681   1.1  christos static void
    682   1.1  christos simple_object_elf_release_read (void *data)
    683   1.1  christos {
    684   1.1  christos   XDELETE (data);
    685   1.1  christos }
    686   1.1  christos 
    687   1.1  christos /* Compare two attributes structures.  */
    688   1.1  christos 
    689   1.1  christos static const char *
    690   1.1  christos simple_object_elf_attributes_merge (void *todata, void *fromdata, int *err)
    691   1.1  christos {
    692  1.10  christos   struct simple_object_elf_attributes *to
    693  1.10  christos     = (struct simple_object_elf_attributes *) todata;
    694  1.10  christos   struct simple_object_elf_attributes *from
    695  1.10  christos     = (struct simple_object_elf_attributes *) fromdata;
    696   1.1  christos 
    697   1.1  christos   if (to->ei_data != from->ei_data || to->ei_class != from->ei_class)
    698   1.1  christos     {
    699   1.1  christos       *err = 0;
    700   1.1  christos       return "ELF object format mismatch";
    701   1.1  christos     }
    702   1.1  christos 
    703   1.1  christos   if (to->machine != from->machine)
    704   1.1  christos     {
    705   1.1  christos       int ok;
    706   1.1  christos 
    707   1.1  christos       /* EM_SPARC and EM_SPARC32PLUS are compatible and force an
    708   1.1  christos 	 output of EM_SPARC32PLUS.  */
    709   1.1  christos       ok = 0;
    710   1.1  christos       switch (to->machine)
    711   1.1  christos 	{
    712   1.1  christos 	case EM_SPARC:
    713   1.1  christos 	  if (from->machine == EM_SPARC32PLUS)
    714   1.1  christos 	    {
    715   1.1  christos 	      to->machine = from->machine;
    716   1.1  christos 	      ok = 1;
    717   1.1  christos 	    }
    718   1.1  christos 	  break;
    719   1.1  christos 
    720   1.1  christos 	case EM_SPARC32PLUS:
    721   1.1  christos 	  if (from->machine == EM_SPARC)
    722   1.1  christos 	    ok = 1;
    723   1.1  christos 	  break;
    724   1.1  christos 
    725   1.1  christos 	default:
    726   1.1  christos 	  break;
    727   1.1  christos 	}
    728   1.1  christos 
    729   1.1  christos       if (!ok)
    730   1.1  christos 	{
    731   1.1  christos 	  *err = 0;
    732   1.1  christos 	  return "ELF machine number mismatch";
    733   1.1  christos 	}
    734   1.1  christos     }
    735   1.1  christos 
    736   1.1  christos   return NULL;
    737   1.1  christos }
    738   1.1  christos 
    739   1.1  christos /* Release the private data for an attributes structure.  */
    740   1.1  christos 
    741   1.1  christos static void
    742   1.1  christos simple_object_elf_release_attributes (void *data)
    743   1.1  christos {
    744   1.1  christos   XDELETE (data);
    745   1.1  christos }
    746   1.1  christos 
    747   1.1  christos /* Prepare to write out a file.  */
    748   1.1  christos 
    749   1.1  christos static void *
    750   1.1  christos simple_object_elf_start_write (void *attributes_data,
    751   1.1  christos 			       const char **errmsg ATTRIBUTE_UNUSED,
    752   1.1  christos 			       int *err ATTRIBUTE_UNUSED)
    753   1.1  christos {
    754  1.10  christos   struct simple_object_elf_attributes *attrs
    755  1.10  christos     = (struct simple_object_elf_attributes *) attributes_data;
    756   1.6  christos   struct simple_object_elf_write *ret;
    757   1.1  christos 
    758   1.1  christos   /* We're just going to record the attributes, but we need to make a
    759   1.1  christos      copy because the user may delete them.  */
    760   1.6  christos   ret = XNEW (struct simple_object_elf_write);
    761   1.6  christos   ret->attrs = *attrs;
    762   1.6  christos   ret->shdrs = NULL;
    763   1.1  christos   return ret;
    764   1.1  christos }
    765   1.1  christos 
    766   1.1  christos /* Write out an ELF ehdr.  */
    767   1.1  christos 
    768   1.1  christos static int
    769   1.1  christos simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
    770   1.1  christos 			      const char **errmsg, int *err)
    771   1.1  christos {
    772  1.10  christos   struct simple_object_elf_attributes *attrs
    773  1.10  christos     = (struct simple_object_elf_attributes *) sobj->data;
    774   1.1  christos   const struct elf_type_functions* fns;
    775   1.1  christos   unsigned char cl;
    776   1.1  christos   size_t ehdr_size;
    777   1.1  christos   unsigned char buf[sizeof (Elf64_External_Ehdr)];
    778   1.1  christos   simple_object_write_section *section;
    779   1.1  christos   unsigned int shnum;
    780   1.3  christos   unsigned int shstrndx;
    781   1.1  christos 
    782   1.1  christos   fns = attrs->type_functions;
    783   1.1  christos   cl = attrs->ei_class;
    784   1.1  christos 
    785   1.1  christos   shnum = 0;
    786   1.1  christos   for (section = sobj->sections; section != NULL; section = section->next)
    787   1.1  christos     ++shnum;
    788   1.1  christos   if (shnum > 0)
    789   1.1  christos     {
    790   1.1  christos       /* Add a section header for the dummy section and one for
    791   1.1  christos 	 .shstrtab.  */
    792   1.1  christos       shnum += 2;
    793   1.1  christos     }
    794   1.1  christos 
    795   1.1  christos   ehdr_size = (cl == ELFCLASS32
    796   1.1  christos 	       ? sizeof (Elf32_External_Ehdr)
    797   1.1  christos 	       : sizeof (Elf64_External_Ehdr));
    798   1.1  christos   memset (buf, 0, sizeof (Elf64_External_Ehdr));
    799   1.1  christos 
    800   1.1  christos   buf[EI_MAG0] = ELFMAG0;
    801   1.1  christos   buf[EI_MAG1] = ELFMAG1;
    802   1.1  christos   buf[EI_MAG2] = ELFMAG2;
    803   1.1  christos   buf[EI_MAG3] = ELFMAG3;
    804   1.1  christos   buf[EI_CLASS] = cl;
    805   1.1  christos   buf[EI_DATA] = attrs->ei_data;
    806   1.1  christos   buf[EI_VERSION] = EV_CURRENT;
    807   1.1  christos   buf[EI_OSABI] = attrs->ei_osabi;
    808   1.1  christos 
    809   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_type, Elf_Half, ET_REL);
    810   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_machine, Elf_Half, attrs->machine);
    811   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_version, Elf_Word, EV_CURRENT);
    812   1.1  christos   /* e_entry left as zero.  */
    813   1.1  christos   /* e_phoff left as zero.  */
    814   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shoff, Elf_Addr, ehdr_size);
    815   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_flags, Elf_Word, attrs->flags);
    816   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_ehsize, Elf_Half, ehdr_size);
    817   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_phentsize, Elf_Half,
    818   1.1  christos 		 (cl == ELFCLASS32
    819   1.1  christos 		  ? sizeof (Elf32_External_Phdr)
    820   1.1  christos 		  : sizeof (Elf64_External_Phdr)));
    821   1.1  christos   /* e_phnum left as zero.  */
    822   1.1  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half,
    823   1.1  christos 		 (cl == ELFCLASS32
    824   1.1  christos 		  ? sizeof (Elf32_External_Shdr)
    825   1.1  christos 		  : sizeof (Elf64_External_Shdr)));
    826   1.3  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half,
    827   1.3  christos 		 shnum >= SHN_LORESERVE ? 0 : shnum);
    828   1.3  christos   if (shnum == 0)
    829   1.3  christos     shstrndx = 0;
    830   1.3  christos   else
    831   1.3  christos     {
    832   1.3  christos       shstrndx = shnum - 1;
    833   1.3  christos       if (shstrndx >= SHN_LORESERVE)
    834   1.3  christos 	shstrndx = SHN_XINDEX;
    835   1.3  christos     }
    836   1.3  christos   ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx);
    837   1.1  christos 
    838   1.1  christos   return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
    839   1.1  christos 				       errmsg, err);
    840   1.1  christos }
    841   1.1  christos 
    842   1.1  christos /* Write out an ELF shdr.  */
    843   1.1  christos 
    844   1.1  christos static int
    845   1.1  christos simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
    846   1.1  christos 			      off_t offset, unsigned int sh_name,
    847   1.1  christos 			      unsigned int sh_type, unsigned int sh_flags,
    848   1.6  christos 			      off_t sh_addr,
    849   1.1  christos 			      unsigned int sh_offset, unsigned int sh_size,
    850   1.6  christos 			      unsigned int sh_link, unsigned int sh_info,
    851   1.6  christos 			      size_t sh_addralign,
    852   1.6  christos 			      size_t sh_entsize,
    853   1.3  christos 			      const char **errmsg, int *err)
    854   1.1  christos {
    855  1.10  christos   struct simple_object_elf_attributes *attrs
    856  1.10  christos     = (struct simple_object_elf_attributes *) sobj->data;
    857   1.1  christos   const struct elf_type_functions* fns;
    858   1.1  christos   unsigned char cl;
    859   1.1  christos   size_t shdr_size;
    860   1.1  christos   unsigned char buf[sizeof (Elf64_External_Shdr)];
    861   1.1  christos 
    862   1.1  christos   fns = attrs->type_functions;
    863   1.1  christos   cl = attrs->ei_class;
    864   1.1  christos 
    865   1.1  christos   shdr_size = (cl == ELFCLASS32
    866   1.1  christos 	       ? sizeof (Elf32_External_Shdr)
    867   1.1  christos 	       : sizeof (Elf64_External_Shdr));
    868   1.1  christos   memset (buf, 0, sizeof (Elf64_External_Shdr));
    869   1.1  christos 
    870   1.1  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name);
    871   1.1  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type);
    872   1.1  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
    873   1.6  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addr, Elf_Addr, sh_addr);
    874   1.1  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
    875   1.1  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
    876   1.3  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link);
    877   1.6  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_info, Elf_Word, sh_info);
    878   1.1  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
    879   1.6  christos   ELF_SET_FIELD (fns, cl, Shdr, buf, sh_entsize, Elf_Addr, sh_entsize);
    880   1.1  christos 
    881   1.1  christos   return simple_object_internal_write (descriptor, offset, buf, shdr_size,
    882   1.1  christos 				       errmsg, err);
    883   1.1  christos }
    884   1.1  christos 
    885   1.1  christos /* Write out a complete ELF file.
    886   1.1  christos    Ehdr
    887   1.1  christos    initial dummy Shdr
    888   1.1  christos    user-created Shdrs
    889   1.1  christos    .shstrtab Shdr
    890   1.1  christos    user-created section data
    891   1.1  christos    .shstrtab data  */
    892   1.1  christos 
    893   1.1  christos static const char *
    894   1.1  christos simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
    895   1.1  christos 				 int *err)
    896   1.1  christos {
    897  1.10  christos   struct simple_object_elf_write *eow
    898  1.10  christos     = (struct simple_object_elf_write *) sobj->data;
    899   1.6  christos   struct simple_object_elf_attributes *attrs = &eow->attrs;
    900   1.1  christos   unsigned char cl;
    901   1.1  christos   size_t ehdr_size;
    902   1.1  christos   size_t shdr_size;
    903   1.1  christos   const char *errmsg;
    904   1.1  christos   simple_object_write_section *section;
    905   1.1  christos   unsigned int shnum;
    906   1.1  christos   size_t shdr_offset;
    907   1.1  christos   size_t sh_offset;
    908   1.3  christos   unsigned int first_sh_size;
    909   1.3  christos   unsigned int first_sh_link;
    910   1.1  christos   size_t sh_name;
    911   1.1  christos   unsigned char zero;
    912   1.6  christos   unsigned secnum;
    913   1.1  christos 
    914   1.1  christos   if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err))
    915   1.1  christos     return errmsg;
    916   1.1  christos 
    917   1.1  christos   cl = attrs->ei_class;
    918   1.1  christos   if (cl == ELFCLASS32)
    919   1.1  christos     {
    920   1.1  christos       ehdr_size = sizeof (Elf32_External_Ehdr);
    921   1.1  christos       shdr_size = sizeof (Elf32_External_Shdr);
    922   1.1  christos     }
    923   1.1  christos   else
    924   1.1  christos     {
    925   1.1  christos       ehdr_size = sizeof (Elf64_External_Ehdr);
    926   1.1  christos       shdr_size = sizeof (Elf64_External_Shdr);
    927   1.1  christos     }
    928   1.1  christos 
    929   1.1  christos   shnum = 0;
    930   1.1  christos   for (section = sobj->sections; section != NULL; section = section->next)
    931   1.1  christos     ++shnum;
    932   1.1  christos   if (shnum == 0)
    933   1.1  christos     return NULL;
    934   1.1  christos 
    935   1.1  christos   /* Add initial dummy Shdr and .shstrtab.  */
    936   1.1  christos   shnum += 2;
    937   1.1  christos 
    938   1.1  christos   shdr_offset = ehdr_size;
    939   1.1  christos   sh_offset = shdr_offset + shnum * shdr_size;
    940   1.1  christos 
    941   1.3  christos   if (shnum < SHN_LORESERVE)
    942   1.3  christos     first_sh_size = 0;
    943   1.3  christos   else
    944   1.3  christos     first_sh_size = shnum;
    945   1.3  christos   if (shnum - 1 < SHN_LORESERVE)
    946   1.3  christos     first_sh_link = 0;
    947   1.3  christos   else
    948   1.3  christos     first_sh_link = shnum - 1;
    949   1.1  christos   if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
    950   1.6  christos 				     0, 0, 0, 0, 0, first_sh_size, first_sh_link,
    951   1.6  christos 				     0, 0, 0, &errmsg, err))
    952   1.1  christos     return errmsg;
    953   1.1  christos 
    954   1.1  christos   shdr_offset += shdr_size;
    955   1.1  christos 
    956   1.1  christos   sh_name = 1;
    957   1.6  christos   secnum = 0;
    958   1.1  christos   for (section = sobj->sections; section != NULL; section = section->next)
    959   1.1  christos     {
    960   1.1  christos       size_t mask;
    961   1.1  christos       size_t new_sh_offset;
    962   1.1  christos       size_t sh_size;
    963   1.1  christos       struct simple_object_write_section_buffer *buffer;
    964   1.6  christos       unsigned int sh_type = SHT_PROGBITS;
    965   1.6  christos       unsigned int sh_flags = 0;
    966   1.6  christos       off_t sh_addr = 0;
    967   1.6  christos       unsigned int sh_link = 0;
    968   1.6  christos       unsigned int sh_info = 0;
    969   1.6  christos       size_t sh_addralign = 1U << section->align;
    970   1.6  christos       size_t sh_entsize = 0;
    971   1.6  christos       if (eow->shdrs)
    972   1.6  christos 	{
    973   1.6  christos 	  sh_type = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    974   1.6  christos 				     eow->shdrs + secnum * shdr_size,
    975   1.6  christos 				     sh_type, Elf_Word);
    976   1.6  christos 	  sh_flags = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    977   1.6  christos 				      eow->shdrs + secnum * shdr_size,
    978   1.6  christos 				      sh_flags, Elf_Addr);
    979   1.6  christos 	  sh_addr = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    980   1.6  christos 				     eow->shdrs + secnum * shdr_size,
    981   1.6  christos 				     sh_addr, Elf_Addr);
    982   1.6  christos 	  sh_link = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    983   1.6  christos 				     eow->shdrs + secnum * shdr_size,
    984   1.6  christos 				     sh_link, Elf_Word);
    985   1.6  christos 	  sh_info = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    986   1.6  christos 				     eow->shdrs + secnum * shdr_size,
    987   1.6  christos 				     sh_info, Elf_Word);
    988   1.6  christos 	  sh_addralign = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    989   1.6  christos 					  eow->shdrs + secnum * shdr_size,
    990   1.6  christos 					  sh_addralign, Elf_Addr);
    991   1.6  christos 	  sh_entsize = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
    992   1.6  christos 					eow->shdrs + secnum * shdr_size,
    993   1.6  christos 					sh_entsize, Elf_Addr);
    994   1.6  christos 	  secnum++;
    995   1.6  christos 	}
    996   1.1  christos 
    997   1.6  christos       mask = sh_addralign - 1;
    998   1.1  christos       new_sh_offset = sh_offset + mask;
    999   1.1  christos       new_sh_offset &= ~ mask;
   1000   1.1  christos       while (new_sh_offset > sh_offset)
   1001   1.1  christos 	{
   1002   1.1  christos 	  unsigned char zeroes[16];
   1003   1.1  christos 	  size_t write;
   1004   1.1  christos 
   1005   1.1  christos 	  memset (zeroes, 0, sizeof zeroes);
   1006   1.1  christos 	  write = new_sh_offset - sh_offset;
   1007   1.1  christos 	  if (write > sizeof zeroes)
   1008   1.1  christos 	    write = sizeof zeroes;
   1009   1.1  christos 	  if (!simple_object_internal_write (descriptor, sh_offset, zeroes,
   1010   1.1  christos 					     write, &errmsg, err))
   1011   1.1  christos 	    return errmsg;
   1012   1.1  christos 	  sh_offset += write;
   1013   1.1  christos 	}
   1014   1.1  christos 
   1015   1.1  christos       sh_size = 0;
   1016   1.1  christos       for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
   1017   1.1  christos 	{
   1018   1.1  christos 	  if (!simple_object_internal_write (descriptor, sh_offset + sh_size,
   1019   1.1  christos 					     ((const unsigned char *)
   1020   1.1  christos 					      buffer->buffer),
   1021   1.1  christos 					     buffer->size, &errmsg, err))
   1022   1.1  christos 	    return errmsg;
   1023   1.1  christos 	  sh_size += buffer->size;
   1024   1.1  christos 	}
   1025   1.1  christos 
   1026   1.1  christos       if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
   1027   1.6  christos 					 sh_name, sh_type, sh_flags,
   1028   1.6  christos 					 sh_addr, sh_offset,
   1029   1.6  christos 					 sh_size, sh_link, sh_info,
   1030   1.6  christos 					 sh_addralign, sh_entsize,
   1031   1.1  christos 					 &errmsg, err))
   1032   1.1  christos 	return errmsg;
   1033   1.1  christos 
   1034   1.1  christos       shdr_offset += shdr_size;
   1035   1.1  christos       sh_name += strlen (section->name) + 1;
   1036   1.1  christos       sh_offset += sh_size;
   1037   1.1  christos     }
   1038   1.1  christos 
   1039   1.1  christos   if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
   1040   1.6  christos 				     sh_name, SHT_STRTAB, 0, 0, sh_offset,
   1041   1.6  christos 				     sh_name + strlen (".shstrtab") + 1, 0, 0,
   1042   1.6  christos 				     1, 0, &errmsg, err))
   1043   1.1  christos     return errmsg;
   1044   1.1  christos 
   1045   1.1  christos   /* .shstrtab has a leading zero byte.  */
   1046   1.1  christos   zero = 0;
   1047   1.1  christos   if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1,
   1048   1.1  christos 				     &errmsg, err))
   1049   1.1  christos     return errmsg;
   1050   1.1  christos   ++sh_offset;
   1051   1.1  christos 
   1052   1.1  christos   for (section = sobj->sections; section != NULL; section = section->next)
   1053   1.1  christos     {
   1054   1.1  christos       size_t len;
   1055   1.1  christos 
   1056   1.1  christos       len = strlen (section->name) + 1;
   1057   1.1  christos       if (!simple_object_internal_write (descriptor, sh_offset,
   1058   1.1  christos 					 (const unsigned char *) section->name,
   1059   1.1  christos 					 len, &errmsg, err))
   1060   1.1  christos 	return errmsg;
   1061   1.1  christos       sh_offset += len;
   1062   1.1  christos     }
   1063   1.1  christos 
   1064   1.1  christos   if (!simple_object_internal_write (descriptor, sh_offset,
   1065   1.1  christos 				     (const unsigned char *) ".shstrtab",
   1066   1.1  christos 				     strlen (".shstrtab") + 1, &errmsg, err))
   1067   1.1  christos     return errmsg;
   1068   1.1  christos 
   1069   1.1  christos   return NULL;
   1070   1.1  christos }
   1071   1.1  christos 
   1072   1.1  christos /* Release the private data for an simple_object_write structure.  */
   1073   1.1  christos 
   1074   1.1  christos static void
   1075   1.1  christos simple_object_elf_release_write (void *data)
   1076   1.1  christos {
   1077   1.6  christos   struct simple_object_elf_write *eow = (struct simple_object_elf_write *) data;
   1078   1.6  christos   if (eow->shdrs)
   1079   1.6  christos     XDELETE (eow->shdrs);
   1080   1.1  christos   XDELETE (data);
   1081   1.1  christos }
   1082   1.1  christos 
   1083   1.6  christos /* Copy all sections in an ELF file.  */
   1084   1.6  christos 
   1085   1.6  christos static const char *
   1086   1.6  christos simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
   1087   1.6  christos 					   simple_object_write *dobj,
   1088   1.6  christos 					   char *(*pfn) (const char *),
   1089   1.6  christos 					   int *err)
   1090   1.6  christos {
   1091  1.10  christos   struct simple_object_elf_read *eor
   1092  1.10  christos     = (struct simple_object_elf_read *) sobj->data;
   1093   1.6  christos   const struct elf_type_functions *type_functions = eor->type_functions;
   1094  1.10  christos   struct simple_object_elf_write *eow
   1095  1.10  christos     = (struct simple_object_elf_write *) dobj->data;
   1096   1.6  christos   unsigned char ei_class = eor->ei_class;
   1097   1.6  christos   size_t shdr_size;
   1098   1.6  christos   unsigned int shnum;
   1099   1.6  christos   unsigned char *shdrs;
   1100   1.6  christos   const char *errmsg;
   1101   1.6  christos   unsigned char *shstrhdr;
   1102   1.6  christos   size_t name_size;
   1103   1.6  christos   off_t shstroff;
   1104   1.6  christos   unsigned char *names;
   1105   1.6  christos   unsigned int i;
   1106   1.6  christos   int changed;
   1107   1.6  christos   int *pfnret;
   1108   1.6  christos   const char **pfnname;
   1109  1.10  christos   unsigned new_i, new_count;
   1110   1.6  christos   unsigned *sh_map;
   1111   1.6  christos   unsigned first_shndx = 0;
   1112   1.6  christos   unsigned int *symtab_indices_shndx;
   1113  1.10  christos   int pass_symtab_indices_shndx;
   1114  1.10  christos   unsigned int first_symtab_indices_shndx;
   1115  1.10  christos   unsigned char **symtab_indices_shndx_buf;
   1116   1.6  christos 
   1117   1.6  christos   shdr_size = (ei_class == ELFCLASS32
   1118   1.6  christos 	       ? sizeof (Elf32_External_Shdr)
   1119   1.6  christos 	       : sizeof (Elf64_External_Shdr));
   1120   1.6  christos 
   1121   1.6  christos   /* Read the section headers.  We skip section 0, which is not a
   1122   1.6  christos      useful section.  */
   1123   1.6  christos 
   1124   1.6  christos   shnum = eor->shnum;
   1125   1.6  christos   shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
   1126   1.6  christos 
   1127   1.6  christos   if (!simple_object_internal_read (sobj->descriptor,
   1128   1.6  christos 				    sobj->offset + eor->shoff + shdr_size,
   1129   1.6  christos 				    shdrs,
   1130   1.6  christos 				    shdr_size * (shnum - 1),
   1131   1.6  christos 				    &errmsg, err))
   1132   1.6  christos     {
   1133   1.6  christos       XDELETEVEC (shdrs);
   1134   1.6  christos       return errmsg;
   1135   1.6  christos     }
   1136   1.6  christos 
   1137   1.6  christos   /* Read the section names.  */
   1138   1.6  christos 
   1139   1.6  christos   shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size;
   1140   1.6  christos   name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1141   1.6  christos 			       shstrhdr, sh_size, Elf_Addr);
   1142   1.6  christos   shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1143   1.6  christos 			      shstrhdr, sh_offset, Elf_Addr);
   1144   1.6  christos   names = XNEWVEC (unsigned char, name_size);
   1145   1.6  christos   if (!simple_object_internal_read (sobj->descriptor,
   1146   1.6  christos 				    sobj->offset + shstroff,
   1147   1.6  christos 				    names, name_size, &errmsg, err))
   1148   1.6  christos     {
   1149   1.6  christos       XDELETEVEC (names);
   1150   1.6  christos       XDELETEVEC (shdrs);
   1151   1.6  christos       return errmsg;
   1152   1.6  christos     }
   1153   1.6  christos 
   1154   1.6  christos   pfnret = XNEWVEC (int, shnum);
   1155   1.6  christos   pfnname = XNEWVEC (const char *, shnum);
   1156   1.6  christos 
   1157   1.6  christos   /* Map of symtab to index section.  */
   1158   1.6  christos   symtab_indices_shndx = XCNEWVEC (unsigned int, shnum - 1);
   1159   1.6  christos 
   1160   1.6  christos   /* First perform the callbacks to know which sections to preserve and
   1161   1.6  christos      what name to use for those.  */
   1162   1.6  christos   for (i = 1; i < shnum; ++i)
   1163   1.6  christos     {
   1164   1.6  christos       unsigned char *shdr;
   1165   1.6  christos       unsigned int sh_name, sh_type;
   1166   1.6  christos       const char *name;
   1167   1.6  christos       char *ret;
   1168   1.6  christos 
   1169   1.6  christos       shdr = shdrs + (i - 1) * shdr_size;
   1170   1.6  christos       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1171   1.6  christos 				 shdr, sh_name, Elf_Word);
   1172   1.6  christos       if (sh_name >= name_size)
   1173   1.6  christos 	{
   1174   1.6  christos 	  *err = 0;
   1175   1.6  christos 	  XDELETEVEC (names);
   1176   1.6  christos 	  XDELETEVEC (shdrs);
   1177   1.6  christos 	  return "ELF section name out of range";
   1178   1.6  christos 	}
   1179   1.6  christos 
   1180   1.6  christos       name = (const char *) names + sh_name;
   1181   1.6  christos 
   1182   1.6  christos       ret = (*pfn) (name);
   1183   1.6  christos       pfnret[i - 1] = ret == NULL ? -1 : 0;
   1184   1.6  christos       pfnname[i - 1] = ret == NULL ? name : ret;
   1185  1.10  christos       if (first_shndx == 0 && pfnret[i - 1] == 0)
   1186   1.6  christos 	first_shndx = i;
   1187   1.6  christos 
   1188   1.6  christos       /* Remember the indexes of existing SHT_SYMTAB_SHNDX sections.  */
   1189   1.6  christos       sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1190   1.6  christos 				 shdr, sh_type, Elf_Word);
   1191   1.6  christos       if (sh_type == SHT_SYMTAB_SHNDX)
   1192   1.6  christos 	{
   1193   1.6  christos 	  unsigned int sh_link;
   1194   1.6  christos 	  sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1195   1.6  christos 				     shdr, sh_link, Elf_Word);
   1196  1.10  christos 	  symtab_indices_shndx[sh_link - 1] = i;
   1197  1.10  christos 	  /* Discard the extended index sections, after copying it will not
   1198  1.10  christos 	     be needed, unless we need more than SHN_LORESERVE - 1 sections
   1199  1.10  christos 	     in the output.  This way we don't need to update it and deal with
   1200  1.10  christos 	     the ordering constraints of processing the existing symtab and
   1201  1.10  christos 	     changing the index.  */
   1202   1.6  christos 	  pfnret[i - 1] = -1;
   1203   1.6  christos 	}
   1204   1.6  christos     }
   1205   1.6  christos 
   1206   1.6  christos   /* Mark sections as preserved that are required by to be preserved
   1207   1.6  christos      sections.  */
   1208   1.6  christos   do
   1209   1.6  christos     {
   1210   1.6  christos       changed = 0;
   1211   1.6  christos       for (i = 1; i < shnum; ++i)
   1212   1.6  christos 	{
   1213   1.6  christos 	  unsigned char *shdr;
   1214   1.6  christos 	  unsigned int sh_type, sh_info, sh_link;
   1215   1.6  christos 	  off_t offset;
   1216   1.6  christos 	  off_t length;
   1217   1.6  christos 
   1218   1.6  christos 	  shdr = shdrs + (i - 1) * shdr_size;
   1219   1.6  christos 	  sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1220   1.6  christos 				     shdr, sh_type, Elf_Word);
   1221   1.6  christos 	  sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1222   1.6  christos 				     shdr, sh_info, Elf_Word);
   1223   1.6  christos 	  sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1224   1.6  christos 				     shdr, sh_link, Elf_Word);
   1225   1.6  christos 	  if (sh_type == SHT_GROUP)
   1226   1.6  christos 	    {
   1227   1.6  christos 	      /* Mark groups containing copied sections.  */
   1228   1.6  christos 	      unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class,
   1229   1.6  christos 						  Shdr, shdr, sh_entsize,
   1230   1.6  christos 						  Elf_Addr);
   1231   1.6  christos 	      unsigned char *ent, *buf;
   1232   1.6  christos 	      int keep = 0;
   1233   1.6  christos 	      offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1234   1.6  christos 					shdr, sh_offset, Elf_Addr);
   1235   1.6  christos 	      length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1236   1.6  christos 					shdr, sh_size, Elf_Addr);
   1237   1.6  christos 	      buf = XNEWVEC (unsigned char, length);
   1238   1.6  christos 	      if (!simple_object_internal_read (sobj->descriptor,
   1239   1.6  christos 						sobj->offset + offset, buf,
   1240   1.6  christos 						(size_t) length, &errmsg, err))
   1241   1.6  christos 		{
   1242   1.6  christos 		  XDELETEVEC (buf);
   1243   1.6  christos 		  XDELETEVEC (names);
   1244   1.6  christos 		  XDELETEVEC (shdrs);
   1245   1.6  christos 		  return errmsg;
   1246   1.6  christos 		}
   1247   1.6  christos 	      for (ent = buf + entsize; ent < buf + length; ent += entsize)
   1248   1.6  christos 		{
   1249   1.6  christos 		  unsigned sec = type_functions->fetch_Elf_Word (ent);
   1250   1.6  christos 		  if (pfnret[sec - 1] == 0)
   1251   1.6  christos 		    keep = 1;
   1252   1.6  christos 		}
   1253   1.6  christos 	      if (keep)
   1254   1.6  christos 		{
   1255   1.6  christos 		  changed |= (pfnret[sh_link - 1] == -1
   1256   1.6  christos 			      || pfnret[i - 1] == -1);
   1257   1.6  christos 		  pfnret[sh_link - 1] = 0;
   1258   1.6  christos 		  pfnret[i - 1] = 0;
   1259   1.6  christos 		}
   1260   1.6  christos 	    }
   1261   1.6  christos 	  if (sh_type == SHT_RELA
   1262   1.6  christos 	      || sh_type == SHT_REL)
   1263   1.6  christos 	    {
   1264   1.6  christos 	      /* Mark relocation sections and symtab of copied sections.  */
   1265   1.6  christos 	      if (pfnret[sh_info - 1] == 0)
   1266   1.6  christos 		{
   1267   1.6  christos 		  changed |= (pfnret[sh_link - 1] == -1
   1268   1.6  christos 			      || pfnret[i - 1] == -1);
   1269   1.6  christos 		  pfnret[sh_link - 1] = 0;
   1270   1.6  christos 		  pfnret[i - 1] = 0;
   1271   1.6  christos 		}
   1272   1.6  christos 	    }
   1273   1.6  christos 	  if (sh_type == SHT_SYMTAB)
   1274   1.6  christos 	    {
   1275   1.6  christos 	      /* Mark strings sections of copied symtabs.  */
   1276   1.6  christos 	      if (pfnret[i - 1] == 0)
   1277   1.6  christos 		{
   1278   1.6  christos 		  changed |= pfnret[sh_link - 1] == -1;
   1279   1.6  christos 		  pfnret[sh_link - 1] = 0;
   1280   1.6  christos 		}
   1281   1.6  christos 	    }
   1282   1.6  christos 	}
   1283   1.6  christos     }
   1284   1.6  christos   while (changed);
   1285   1.6  christos 
   1286   1.6  christos   /* Compute a mapping of old -> new section numbers.  */
   1287   1.6  christos   sh_map = XNEWVEC (unsigned, shnum);
   1288   1.6  christos   sh_map[0] = 0;
   1289   1.6  christos   new_i = 1;
   1290   1.6  christos   for (i = 1; i < shnum; ++i)
   1291   1.6  christos     {
   1292   1.6  christos       if (pfnret[i - 1] == -1)
   1293   1.6  christos 	sh_map[i] = 0;
   1294   1.6  christos       else
   1295   1.6  christos 	sh_map[i] = new_i++;
   1296   1.6  christos     }
   1297  1.10  christos   first_symtab_indices_shndx = new_i;
   1298  1.10  christos   symtab_indices_shndx_buf = NULL;
   1299   1.6  christos   if (new_i - 1 >= SHN_LORESERVE)
   1300  1.10  christos     for (i = 1; i < shnum; ++i)
   1301  1.10  christos       if (pfnret[i - 1] == 0 && symtab_indices_shndx[i - 1] != 0)
   1302  1.10  christos 	{
   1303  1.10  christos 	  pfnret[symtab_indices_shndx[i - 1] - 1] = 0;
   1304  1.10  christos 	  sh_map[symtab_indices_shndx[i - 1]] = new_i++;
   1305  1.10  christos 	}
   1306  1.10  christos   new_count = new_i;
   1307  1.10  christos   if (new_count != first_symtab_indices_shndx)
   1308  1.10  christos     symtab_indices_shndx_buf
   1309  1.10  christos       = XNEWVEC (unsigned char *, new_count - first_symtab_indices_shndx);
   1310  1.10  christos   eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_count - 1));
   1311   1.6  christos 
   1312   1.6  christos   /* Then perform the actual copying.  */
   1313   1.6  christos   new_i = 0;
   1314  1.10  christos   pass_symtab_indices_shndx = 0;
   1315  1.10  christos   for (i = 1; i <= shnum; ++i)
   1316   1.6  christos     {
   1317   1.6  christos       unsigned char *shdr;
   1318   1.6  christos       unsigned int sh_name, sh_type;
   1319   1.6  christos       const char *name;
   1320   1.6  christos       off_t offset;
   1321   1.6  christos       off_t length;
   1322   1.6  christos       simple_object_write_section *dest;
   1323   1.6  christos       off_t flags;
   1324   1.6  christos       unsigned char *buf;
   1325   1.6  christos 
   1326  1.10  christos       if (i == shnum)
   1327  1.10  christos 	{
   1328  1.10  christos 	  if (new_count - 1 < SHN_LORESERVE || pass_symtab_indices_shndx)
   1329  1.10  christos 	    break;
   1330  1.10  christos 	  i = 0;
   1331  1.10  christos 	  pass_symtab_indices_shndx = 1;
   1332  1.10  christos 	  continue;
   1333  1.10  christos 	}
   1334  1.10  christos 
   1335   1.6  christos       if (pfnret[i - 1])
   1336   1.6  christos 	continue;
   1337   1.6  christos 
   1338  1.10  christos       shdr = shdrs + (i - 1) * shdr_size;
   1339  1.10  christos       sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1340  1.10  christos 				 shdr, sh_type, Elf_Word);
   1341  1.10  christos       if (sh_type == SHT_SYMTAB_SHNDX)
   1342  1.10  christos 	{
   1343  1.10  christos 	  if (!pass_symtab_indices_shndx)
   1344  1.10  christos 	    continue;
   1345  1.10  christos 	}
   1346  1.10  christos       else if (pass_symtab_indices_shndx)
   1347  1.10  christos 	continue;
   1348  1.10  christos 
   1349   1.6  christos       new_i++;
   1350   1.6  christos       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1351   1.6  christos 				 shdr, sh_name, Elf_Word);
   1352   1.6  christos       if (sh_name >= name_size)
   1353   1.6  christos 	{
   1354   1.6  christos 	  *err = 0;
   1355   1.6  christos 	  XDELETEVEC (names);
   1356   1.6  christos 	  XDELETEVEC (shdrs);
   1357   1.6  christos 	  XDELETEVEC (symtab_indices_shndx);
   1358  1.10  christos 	  XDELETEVEC (symtab_indices_shndx_buf);
   1359   1.6  christos 	  return "ELF section name out of range";
   1360   1.6  christos 	}
   1361   1.6  christos 
   1362   1.6  christos       name = pfnname[i - 1];
   1363   1.6  christos       offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1364   1.6  christos 				shdr, sh_offset, Elf_Addr);
   1365   1.6  christos       length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1366   1.6  christos 				shdr, sh_size, Elf_Addr);
   1367   1.6  christos 
   1368  1.10  christos       dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err);
   1369   1.6  christos       if (dest == NULL)
   1370   1.6  christos 	{
   1371   1.6  christos 	  XDELETEVEC (names);
   1372   1.6  christos 	  XDELETEVEC (shdrs);
   1373   1.6  christos 	  XDELETEVEC (symtab_indices_shndx);
   1374  1.10  christos 	  XDELETEVEC (symtab_indices_shndx_buf);
   1375   1.6  christos 	  return errmsg;
   1376   1.6  christos 	}
   1377   1.6  christos 
   1378   1.6  christos       /* Record the SHDR of the source.  */
   1379   1.6  christos       memcpy (eow->shdrs + (new_i - 1) * shdr_size, shdr, shdr_size);
   1380   1.6  christos       shdr = eow->shdrs + (new_i - 1) * shdr_size;
   1381   1.6  christos 
   1382   1.6  christos       /* Copy the data.
   1383   1.6  christos 	 ???  This is quite wasteful and ideally would be delayed until
   1384   1.6  christos 	 write_to_file ().  Thus it questions the interfacing
   1385   1.6  christos 	 which eventually should contain destination creation plus
   1386   1.6  christos 	 writing.  */
   1387   1.6  christos       buf = XNEWVEC (unsigned char, length);
   1388   1.6  christos       if (!simple_object_internal_read (sobj->descriptor,
   1389   1.6  christos 					sobj->offset + offset, buf,
   1390   1.6  christos 					(size_t) length, &errmsg, err))
   1391   1.6  christos 	{
   1392   1.6  christos 	  XDELETEVEC (buf);
   1393   1.6  christos 	  XDELETEVEC (names);
   1394   1.6  christos 	  XDELETEVEC (shdrs);
   1395   1.6  christos 	  XDELETEVEC (symtab_indices_shndx);
   1396  1.10  christos 	  XDELETEVEC (symtab_indices_shndx_buf);
   1397   1.6  christos 	  return errmsg;
   1398   1.6  christos 	}
   1399   1.6  christos 
   1400   1.7  christos       /* If we are processing .symtab purge any symbols
   1401   1.7  christos 	 in discarded sections.  */
   1402   1.6  christos       if (sh_type == SHT_SYMTAB)
   1403   1.6  christos 	{
   1404   1.6  christos 	  unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1405   1.6  christos 					      shdr, sh_entsize, Elf_Addr);
   1406   1.7  christos 	  size_t prevailing_name_idx = 0;
   1407   1.6  christos 	  unsigned char *ent;
   1408   1.6  christos 	  unsigned *shndx_table = NULL;
   1409   1.6  christos 	  /* Read the section index table if present.  */
   1410   1.6  christos 	  if (symtab_indices_shndx[i - 1] != 0)
   1411   1.6  christos 	    {
   1412  1.10  christos 	      unsigned char *sidxhdr
   1413  1.10  christos 		= shdrs + (symtab_indices_shndx[i - 1] - 1) * shdr_size;
   1414   1.6  christos 	      off_t sidxoff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1415   1.6  christos 					       sidxhdr, sh_offset, Elf_Addr);
   1416   1.6  christos 	      size_t sidxsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1417   1.6  christos 					       sidxhdr, sh_size, Elf_Addr);
   1418   1.8  christos 	      unsigned int shndx_type
   1419   1.8  christos 		= ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1420   1.8  christos 				   sidxhdr, sh_type, Elf_Word);
   1421   1.8  christos 	      if (shndx_type != SHT_SYMTAB_SHNDX)
   1422   1.8  christos 		return "Wrong section type of a SYMTAB SECTION INDICES section";
   1423  1.10  christos 	      shndx_table = (unsigned *) XNEWVEC (char, sidxsz);
   1424  1.10  christos 	      if (!simple_object_internal_read (sobj->descriptor,
   1425  1.10  christos 						sobj->offset + sidxoff,
   1426  1.10  christos 						(unsigned char *) shndx_table,
   1427  1.10  christos 						sidxsz, &errmsg, err))
   1428  1.10  christos 		{
   1429  1.10  christos 		  XDELETEVEC (buf);
   1430  1.10  christos 		  XDELETEVEC (names);
   1431  1.10  christos 		  XDELETEVEC (shdrs);
   1432  1.10  christos 		  XDELETEVEC (symtab_indices_shndx);
   1433  1.10  christos 		  XDELETEVEC (shndx_table);
   1434  1.10  christos 		  XDELETEVEC (symtab_indices_shndx_buf);
   1435  1.10  christos 		  return errmsg;
   1436  1.10  christos 		}
   1437   1.6  christos 	    }
   1438   1.7  christos 
   1439   1.7  christos 	  /* Find a WEAK HIDDEN symbol which name we will use for removed
   1440   1.7  christos 	     symbols.  We know there's a prevailing weak hidden symbol
   1441   1.7  christos 	     at the start of the .debug_info section.  */
   1442   1.7  christos 	  for (ent = buf; ent < buf + length; ent += entsize)
   1443   1.7  christos 	    {
   1444   1.7  christos 	      unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
   1445   1.7  christos 						   Sym, ent,
   1446   1.7  christos 						   st_shndx, Elf_Half);
   1447   1.7  christos 	      unsigned char *st_info;
   1448   1.7  christos 	      unsigned char *st_other;
   1449   1.7  christos 	      if (ei_class == ELFCLASS32)
   1450   1.7  christos 		{
   1451  1.10  christos 		  st_info = &((Elf32_External_Sym *) ent)->st_info;
   1452  1.10  christos 		  st_other = &((Elf32_External_Sym *) ent)->st_other;
   1453   1.7  christos 		}
   1454   1.7  christos 	      else
   1455   1.7  christos 		{
   1456  1.10  christos 		  st_info = &((Elf64_External_Sym *) ent)->st_info;
   1457  1.10  christos 		  st_other = &((Elf64_External_Sym *) ent)->st_other;
   1458   1.7  christos 		}
   1459   1.7  christos 	      if (st_shndx == SHN_XINDEX)
   1460  1.10  christos 		{
   1461  1.10  christos 		  unsigned char *ndx_ptr
   1462  1.10  christos 		    = (unsigned char *) (shndx_table + (ent - buf) / entsize);
   1463  1.10  christos 		  st_shndx = type_functions->fetch_Elf_Word (ndx_ptr);
   1464  1.10  christos 		}
   1465   1.7  christos 
   1466   1.7  christos 	      if (st_shndx != SHN_COMMON
   1467   1.7  christos 		  && !(st_shndx != SHN_UNDEF
   1468   1.7  christos 		       && st_shndx < shnum
   1469   1.7  christos 		       && pfnret[st_shndx - 1] == -1)
   1470   1.7  christos 		  && ELF_ST_BIND (*st_info) == STB_WEAK
   1471   1.7  christos 		  && *st_other == STV_HIDDEN)
   1472   1.7  christos 		{
   1473   1.7  christos 		  prevailing_name_idx = ELF_FETCH_FIELD (type_functions,
   1474   1.7  christos 							 ei_class, Sym, ent,
   1475   1.7  christos 							 st_name, Elf_Word);
   1476   1.7  christos 		  break;
   1477   1.7  christos 		}
   1478   1.7  christos 	    }
   1479   1.7  christos 
   1480   1.6  christos 	  for (ent = buf; ent < buf + length; ent += entsize)
   1481   1.6  christos 	    {
   1482   1.6  christos 	      unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
   1483   1.6  christos 						   Sym, ent,
   1484   1.6  christos 						   st_shndx, Elf_Half);
   1485   1.6  christos 	      unsigned raw_st_shndx = st_shndx;
   1486   1.6  christos 	      unsigned char *st_info;
   1487   1.6  christos 	      unsigned char *st_other;
   1488   1.6  christos 	      int discard = 0;
   1489  1.10  christos 	      unsigned char *ndx_ptr = NULL;
   1490   1.6  christos 	      if (ei_class == ELFCLASS32)
   1491   1.6  christos 		{
   1492  1.10  christos 		  st_info = &((Elf32_External_Sym *) ent)->st_info;
   1493  1.10  christos 		  st_other = &((Elf32_External_Sym *) ent)->st_other;
   1494   1.6  christos 		}
   1495   1.6  christos 	      else
   1496   1.6  christos 		{
   1497  1.10  christos 		  st_info = &((Elf64_External_Sym *) ent)->st_info;
   1498  1.10  christos 		  st_other = &((Elf64_External_Sym *) ent)->st_other;
   1499   1.6  christos 		}
   1500  1.10  christos 	      if (shndx_table)
   1501  1.10  christos 		ndx_ptr
   1502  1.10  christos 		  = (unsigned char *) (shndx_table + (ent - buf) / entsize);
   1503  1.10  christos 
   1504   1.6  christos 	      if (st_shndx == SHN_XINDEX)
   1505  1.10  christos 		{
   1506  1.10  christos 		  st_shndx = type_functions->fetch_Elf_Word (ndx_ptr);
   1507  1.10  christos 		  type_functions->set_Elf_Word (ndx_ptr, SHN_UNDEF);
   1508  1.10  christos 		}
   1509   1.7  christos 	      /* Eliminate all COMMONs - this includes __gnu_lto_slim
   1510   1.7  christos 		 which otherwise cause endless LTO plugin invocation.
   1511   1.7  christos 		 FIXME: remove the condition once we remove emission
   1512   1.7  christos 		 of __gnu_lto_slim symbol.  */
   1513   1.6  christos 	      if (st_shndx == SHN_COMMON)
   1514   1.6  christos 		discard = 1;
   1515   1.6  christos 	      /* We also need to remove symbols refering to sections
   1516   1.6  christos 		 we'll eventually remove as with fat LTO objects
   1517   1.6  christos 		 we otherwise get duplicate symbols at final link
   1518   1.6  christos 		 (with GNU ld, gold is fine and ignores symbols in
   1519   1.6  christos 		 sections marked as EXCLUDE).  ld/20513  */
   1520   1.6  christos 	      else if (st_shndx != SHN_UNDEF
   1521   1.6  christos 		       && st_shndx < shnum
   1522   1.6  christos 		       && pfnret[st_shndx - 1] == -1)
   1523   1.6  christos 		discard = 1;
   1524   1.8  christos 	      /* We also need to remove global UNDEFs which can
   1525   1.8  christos 		 cause link fails later.  */
   1526   1.8  christos 	      else if (st_shndx == SHN_UNDEF
   1527   1.8  christos 		       && ELF_ST_BIND (*st_info) == STB_GLOBAL)
   1528   1.8  christos 		discard = 1;
   1529   1.6  christos 
   1530   1.6  christos 	      if (discard)
   1531   1.6  christos 		{
   1532   1.6  christos 		  /* Make discarded symbols undefined and unnamed
   1533   1.6  christos 		     in case it is local.  */
   1534   1.6  christos 		  int bind = ELF_ST_BIND (*st_info);
   1535   1.6  christos 		  int other = STV_DEFAULT;
   1536   1.6  christos 		  if (bind == STB_LOCAL)
   1537   1.6  christos 		    {
   1538   1.6  christos 		      /* Make discarded local symbols unnamed and
   1539   1.6  christos 			 defined in the first prevailing section.  */
   1540   1.6  christos 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
   1541   1.6  christos 				     ent, st_name, Elf_Word, 0);
   1542  1.10  christos 		      st_shndx = sh_map[first_shndx];
   1543  1.10  christos 		      if (st_shndx >= SHN_LORESERVE)
   1544  1.10  christos 			{
   1545  1.10  christos 			  type_functions->set_Elf_Word (ndx_ptr, st_shndx);
   1546  1.10  christos 			  st_shndx = SHN_XINDEX;
   1547  1.10  christos 			}
   1548   1.6  christos 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
   1549  1.10  christos 				     ent, st_shndx, Elf_Half, st_shndx);
   1550   1.6  christos 		    }
   1551   1.6  christos 		  else
   1552   1.6  christos 		    {
   1553   1.6  christos 		      /* Make discarded global symbols hidden weak
   1554   1.7  christos 			 undefined and sharing a name of a prevailing
   1555   1.7  christos 			 symbol.  */
   1556   1.6  christos 		      bind = STB_WEAK;
   1557   1.6  christos 		      other = STV_HIDDEN;
   1558   1.7  christos 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
   1559   1.7  christos 				     ent, st_name, Elf_Word,
   1560   1.7  christos 				     prevailing_name_idx);
   1561   1.6  christos 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
   1562   1.6  christos 				     ent, st_shndx, Elf_Half, SHN_UNDEF);
   1563   1.6  christos 		    }
   1564   1.6  christos 		  *st_other = other;
   1565   1.6  christos 		  *st_info = ELF_ST_INFO (bind, STT_NOTYPE);
   1566   1.6  christos 		  ELF_SET_FIELD (type_functions, ei_class, Sym,
   1567   1.6  christos 				 ent, st_value, Elf_Addr, 0);
   1568   1.6  christos 		  ELF_SET_FIELD (type_functions, ei_class, Sym,
   1569   1.6  christos 				 ent, st_size, Elf_Word, 0);
   1570   1.6  christos 		}
   1571   1.6  christos 	      else if (raw_st_shndx < SHN_LORESERVE
   1572   1.6  christos 		       || raw_st_shndx == SHN_XINDEX)
   1573  1.10  christos 		{
   1574  1.10  christos 		  /* Remap the section reference.  */
   1575  1.10  christos 		  st_shndx = sh_map[st_shndx];
   1576  1.10  christos 		  if (st_shndx >= SHN_LORESERVE)
   1577  1.10  christos 		    {
   1578  1.10  christos 		      type_functions->set_Elf_Word (ndx_ptr, st_shndx);
   1579  1.10  christos 		      st_shndx = SHN_XINDEX;
   1580  1.10  christos 		    }
   1581  1.10  christos 		  ELF_SET_FIELD (type_functions, ei_class, Sym,
   1582  1.10  christos 				 ent, st_shndx, Elf_Half, st_shndx);
   1583  1.10  christos 		}
   1584   1.6  christos 	    }
   1585  1.10  christos 	  if (symtab_indices_shndx_buf)
   1586  1.10  christos 	    symtab_indices_shndx_buf[sh_map[symtab_indices_shndx[i - 1]]
   1587  1.10  christos 				     - first_symtab_indices_shndx]
   1588  1.10  christos 	      = (unsigned char *) shndx_table;
   1589  1.10  christos 	  else
   1590  1.10  christos 	    XDELETEVEC (shndx_table);
   1591   1.6  christos 	}
   1592   1.6  christos       else if (sh_type == SHT_GROUP)
   1593   1.6  christos 	{
   1594   1.6  christos 	  /* Remap section indices in groups and remove removed members.  */
   1595   1.6  christos 	  unsigned char *ent, *dst;
   1596   1.6  christos 	  for (dst = ent = buf + 4; ent < buf + length; ent += 4)
   1597   1.6  christos 	    {
   1598   1.6  christos 	      unsigned shndx = type_functions->fetch_Elf_Word (ent);
   1599   1.6  christos 	      if (pfnret[shndx - 1] == -1)
   1600   1.6  christos 		;
   1601   1.6  christos 	      else
   1602   1.6  christos 		{
   1603   1.6  christos 		  type_functions->set_Elf_Word (dst, sh_map[shndx]);
   1604   1.6  christos 		  dst += 4;
   1605   1.6  christos 		}
   1606   1.6  christos 	    }
   1607   1.6  christos 	  /* Adjust the length.  */
   1608   1.6  christos 	  length = dst - buf;
   1609   1.6  christos 	}
   1610  1.10  christos       else if (sh_type == SHT_SYMTAB_SHNDX)
   1611  1.10  christos 	{
   1612  1.10  christos 	  XDELETEVEC (buf);
   1613  1.10  christos 	  buf = symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx];
   1614  1.10  christos 	  symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx] = NULL;
   1615  1.10  christos 	}
   1616   1.6  christos 
   1617  1.10  christos       errmsg = simple_object_write_add_data (dobj, dest, buf, length, 1, err);
   1618   1.6  christos       XDELETEVEC (buf);
   1619   1.6  christos       if (errmsg)
   1620   1.6  christos 	{
   1621   1.6  christos 	  XDELETEVEC (names);
   1622   1.6  christos 	  XDELETEVEC (shdrs);
   1623   1.6  christos 	  XDELETEVEC (symtab_indices_shndx);
   1624  1.10  christos 	  XDELETEVEC (symtab_indices_shndx_buf);
   1625   1.6  christos 	  return errmsg;
   1626   1.6  christos 	}
   1627   1.6  christos 
   1628   1.6  christos       flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1629   1.6  christos 			       shdr, sh_flags, Elf_Addr);
   1630   1.6  christos       /* Remap the section references.  */
   1631   1.6  christos       {
   1632   1.6  christos 	unsigned int sh_info, sh_link;
   1633   1.6  christos 	if (flags & SHF_INFO_LINK || sh_type == SHT_REL || sh_type == SHT_RELA)
   1634   1.6  christos 	  {
   1635   1.6  christos 	    sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1636   1.6  christos 				       shdr, sh_info, Elf_Word);
   1637   1.8  christos 	    sh_info = sh_map[sh_info];
   1638   1.6  christos 	    ELF_SET_FIELD (type_functions, ei_class, Shdr,
   1639   1.6  christos 			   shdr, sh_info, Elf_Word, sh_info);
   1640   1.6  christos 	  }
   1641   1.6  christos 	sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
   1642   1.6  christos 				   shdr, sh_link, Elf_Word);
   1643   1.8  christos 	sh_link = sh_map[sh_link];
   1644   1.6  christos 	ELF_SET_FIELD (type_functions, ei_class, Shdr,
   1645   1.6  christos 		       shdr, sh_link, Elf_Word, sh_link);
   1646   1.6  christos       }
   1647   1.6  christos       /* The debugobj doesn't contain any code, thus no trampolines.
   1648   1.6  christos 	 Even when the original object needs trampolines, debugobj
   1649   1.6  christos 	 doesn't.  */
   1650   1.6  christos       if (strcmp (name, ".note.GNU-stack") == 0)
   1651   1.6  christos 	flags &= ~SHF_EXECINSTR;
   1652   1.6  christos       /* Clear SHF_EXCLUDE on to be preserved sections.  */
   1653   1.6  christos       flags &= ~SHF_EXCLUDE;
   1654   1.6  christos       ELF_SET_FIELD (type_functions, ei_class, Shdr,
   1655   1.6  christos 		     shdr, sh_flags, Elf_Addr, flags);
   1656   1.6  christos     }
   1657   1.6  christos 
   1658   1.6  christos   XDELETEVEC (names);
   1659   1.6  christos   XDELETEVEC (shdrs);
   1660   1.6  christos   XDELETEVEC (pfnret);
   1661   1.6  christos   XDELETEVEC (pfnname);
   1662   1.6  christos   XDELETEVEC (symtab_indices_shndx);
   1663   1.6  christos   XDELETEVEC (sh_map);
   1664  1.10  christos   XDELETEVEC (symtab_indices_shndx_buf);
   1665   1.6  christos 
   1666   1.6  christos   return NULL;
   1667   1.6  christos }
   1668   1.6  christos 
   1669   1.6  christos 
   1670   1.1  christos /* The ELF functions.  */
   1671   1.1  christos 
   1672   1.1  christos const struct simple_object_functions simple_object_elf_functions =
   1673   1.1  christos {
   1674   1.1  christos   simple_object_elf_match,
   1675   1.1  christos   simple_object_elf_find_sections,
   1676   1.1  christos   simple_object_elf_fetch_attributes,
   1677   1.1  christos   simple_object_elf_release_read,
   1678   1.1  christos   simple_object_elf_attributes_merge,
   1679   1.1  christos   simple_object_elf_release_attributes,
   1680   1.1  christos   simple_object_elf_start_write,
   1681   1.1  christos   simple_object_elf_write_to_file,
   1682   1.6  christos   simple_object_elf_release_write,
   1683   1.6  christos   simple_object_elf_copy_lto_debug_sections
   1684   1.1  christos };
   1685