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