simple-object-elf.c revision 1.11 1 1.1 christos /* simple-object-elf.c -- routines to manipulate ELF object files.
2 1.10 christos Copyright (C) 2010-2024 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.7 christos #define SHN_UNDEF 0 /* Undefined section */
130 1.1 christos #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
131 1.11 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.11 christos #define SHN_HIRESERVE 0xFFFF /* End of reserved indices */
134 1.7 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.7 christos #define SHT_NULL 0 /* Section header table entry unused */
195 1.1 christos #define SHT_PROGBITS 1 /* Program data */
196 1.7 christos #define SHT_SYMTAB 2 /* Link editing symbol table */
197 1.1 christos #define SHT_STRTAB 3 /* A string table */
198 1.7 christos #define SHT_RELA 4 /* Relocation entries with addends */
199 1.7 christos #define SHT_REL 9 /* Relocation entries, no addends */
200 1.7 christos #define SHT_GROUP 17 /* Section contains a section group */
201 1.7 christos #define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
202 1.7 christos
203 1.7 christos /* Values for sh_flags field. */
204 1.7 christos
205 1.7 christos #define SHF_INFO_LINK 0x00000040 /* `sh_info' contains SHT index */
206 1.7 christos #define SHF_EXECINSTR 0x00000004 /* Executable section. */
207 1.7 christos #define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude this
208 1.7 christos section from executable and
209 1.7 christos shared library that it builds
210 1.7 christos when those objects are not to be
211 1.7 christos further relocated. */
212 1.7 christos /* Symbol table entry. */
213 1.7 christos
214 1.7 christos typedef struct
215 1.7 christos {
216 1.7 christos unsigned char st_name[4]; /* Symbol name (string tbl index) */
217 1.7 christos unsigned char st_value[4]; /* Symbol value */
218 1.7 christos unsigned char st_size[4]; /* Symbol size */
219 1.7 christos unsigned char st_info; /* Symbol type and binding */
220 1.7 christos unsigned char st_other; /* Symbol visibility */
221 1.7 christos unsigned char st_shndx[2]; /* Section index */
222 1.7 christos } Elf32_External_Sym;
223 1.7 christos
224 1.7 christos typedef struct
225 1.7 christos {
226 1.7 christos unsigned char st_name[4]; /* Symbol name (string tbl index) */
227 1.7 christos unsigned char st_info; /* Symbol type and binding */
228 1.7 christos unsigned char st_other; /* Symbol visibility */
229 1.7 christos unsigned char st_shndx[2]; /* Section index */
230 1.7 christos unsigned char st_value[8]; /* Symbol value */
231 1.7 christos unsigned char st_size[8]; /* Symbol size */
232 1.7 christos } Elf64_External_Sym;
233 1.7 christos
234 1.7 christos #define ELF_ST_BIND(val) (((unsigned char) (val)) >> 4)
235 1.7 christos #define ELF_ST_TYPE(val) ((val) & 0xf)
236 1.7 christos #define ELF_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
237 1.7 christos
238 1.7 christos #define STT_NOTYPE 0 /* Symbol type is unspecified */
239 1.7 christos #define STT_OBJECT 1 /* Symbol is a data object */
240 1.7 christos #define STT_FUNC 2 /* Symbol is a code object */
241 1.7 christos #define STT_TLS 6 /* Thread local data object */
242 1.7 christos #define STT_GNU_IFUNC 10 /* Symbol is an indirect code object */
243 1.7 christos
244 1.7 christos #define STB_LOCAL 0 /* Local symbol */
245 1.7 christos #define STB_GLOBAL 1 /* Global symbol */
246 1.7 christos #define STB_WEAK 2 /* Weak global */
247 1.7 christos
248 1.7 christos #define STV_DEFAULT 0 /* Visibility is specified by binding type */
249 1.7 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.7 christos /* Private data for an simple_object_write. */
414 1.7 christos
415 1.7 christos struct simple_object_elf_write
416 1.7 christos {
417 1.7 christos struct simple_object_elf_attributes attrs;
418 1.7 christos unsigned char *shdrs;
419 1.7 christos };
420 1.7 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.9 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.8 christos
552 1.8 christos if (eor->shstrndx == 0)
553 1.8 christos {
554 1.8 christos *errmsg = "invalid ELF shstrndx == 0";
555 1.8 christos *err = 0;
556 1.8 christos XDELETE (eor);
557 1.8 christos return NULL;
558 1.8 christos }
559 1.8 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.11 christos struct simple_object_elf_read *eor
573 1.11 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.11 christos struct simple_object_elf_read *eor
666 1.11 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.11 christos struct simple_object_elf_attributes *to
693 1.11 christos = (struct simple_object_elf_attributes *) todata;
694 1.11 christos struct simple_object_elf_attributes *from
695 1.11 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.11 christos struct simple_object_elf_attributes *attrs
755 1.11 christos = (struct simple_object_elf_attributes *) attributes_data;
756 1.7 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.7 christos ret = XNEW (struct simple_object_elf_write);
761 1.7 christos ret->attrs = *attrs;
762 1.7 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.11 christos struct simple_object_elf_attributes *attrs
773 1.11 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.7 christos off_t sh_addr,
849 1.1 christos unsigned int sh_offset, unsigned int sh_size,
850 1.7 christos unsigned int sh_link, unsigned int sh_info,
851 1.7 christos size_t sh_addralign,
852 1.7 christos size_t sh_entsize,
853 1.3 christos const char **errmsg, int *err)
854 1.1 christos {
855 1.11 christos struct simple_object_elf_attributes *attrs
856 1.11 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.7 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.7 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.7 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.11 christos struct simple_object_elf_write *eow
898 1.11 christos = (struct simple_object_elf_write *) sobj->data;
899 1.7 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.7 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.7 christos 0, 0, 0, 0, 0, first_sh_size, first_sh_link,
951 1.7 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.7 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.7 christos unsigned int sh_type = SHT_PROGBITS;
965 1.7 christos unsigned int sh_flags = 0;
966 1.7 christos off_t sh_addr = 0;
967 1.7 christos unsigned int sh_link = 0;
968 1.7 christos unsigned int sh_info = 0;
969 1.7 christos size_t sh_addralign = 1U << section->align;
970 1.7 christos size_t sh_entsize = 0;
971 1.7 christos if (eow->shdrs)
972 1.7 christos {
973 1.7 christos sh_type = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
974 1.7 christos eow->shdrs + secnum * shdr_size,
975 1.7 christos sh_type, Elf_Word);
976 1.7 christos sh_flags = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
977 1.7 christos eow->shdrs + secnum * shdr_size,
978 1.7 christos sh_flags, Elf_Addr);
979 1.7 christos sh_addr = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
980 1.7 christos eow->shdrs + secnum * shdr_size,
981 1.7 christos sh_addr, Elf_Addr);
982 1.7 christos sh_link = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
983 1.7 christos eow->shdrs + secnum * shdr_size,
984 1.7 christos sh_link, Elf_Word);
985 1.7 christos sh_info = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
986 1.7 christos eow->shdrs + secnum * shdr_size,
987 1.7 christos sh_info, Elf_Word);
988 1.7 christos sh_addralign = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
989 1.7 christos eow->shdrs + secnum * shdr_size,
990 1.7 christos sh_addralign, Elf_Addr);
991 1.7 christos sh_entsize = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr,
992 1.7 christos eow->shdrs + secnum * shdr_size,
993 1.7 christos sh_entsize, Elf_Addr);
994 1.7 christos secnum++;
995 1.7 christos }
996 1.1 christos
997 1.7 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.7 christos sh_name, sh_type, sh_flags,
1028 1.7 christos sh_addr, sh_offset,
1029 1.7 christos sh_size, sh_link, sh_info,
1030 1.7 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.7 christos sh_name, SHT_STRTAB, 0, 0, sh_offset,
1041 1.7 christos sh_name + strlen (".shstrtab") + 1, 0, 0,
1042 1.7 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.7 christos struct simple_object_elf_write *eow = (struct simple_object_elf_write *) data;
1078 1.7 christos if (eow->shdrs)
1079 1.7 christos XDELETE (eow->shdrs);
1080 1.1 christos XDELETE (data);
1081 1.1 christos }
1082 1.1 christos
1083 1.7 christos /* Copy all sections in an ELF file. */
1084 1.7 christos
1085 1.7 christos static const char *
1086 1.7 christos simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
1087 1.7 christos simple_object_write *dobj,
1088 1.7 christos char *(*pfn) (const char *),
1089 1.7 christos int *err)
1090 1.7 christos {
1091 1.11 christos struct simple_object_elf_read *eor
1092 1.11 christos = (struct simple_object_elf_read *) sobj->data;
1093 1.7 christos const struct elf_type_functions *type_functions = eor->type_functions;
1094 1.11 christos struct simple_object_elf_write *eow
1095 1.11 christos = (struct simple_object_elf_write *) dobj->data;
1096 1.7 christos unsigned char ei_class = eor->ei_class;
1097 1.7 christos size_t shdr_size;
1098 1.7 christos unsigned int shnum;
1099 1.7 christos unsigned char *shdrs;
1100 1.7 christos const char *errmsg;
1101 1.7 christos unsigned char *shstrhdr;
1102 1.7 christos size_t name_size;
1103 1.7 christos off_t shstroff;
1104 1.7 christos unsigned char *names;
1105 1.7 christos unsigned int i;
1106 1.7 christos int changed;
1107 1.7 christos int *pfnret;
1108 1.7 christos const char **pfnname;
1109 1.11 christos unsigned new_i, new_count;
1110 1.7 christos unsigned *sh_map;
1111 1.7 christos unsigned first_shndx = 0;
1112 1.7 christos unsigned int *symtab_indices_shndx;
1113 1.11 christos int pass_symtab_indices_shndx;
1114 1.11 christos unsigned int first_symtab_indices_shndx;
1115 1.11 christos unsigned char **symtab_indices_shndx_buf;
1116 1.7 christos
1117 1.7 christos shdr_size = (ei_class == ELFCLASS32
1118 1.7 christos ? sizeof (Elf32_External_Shdr)
1119 1.7 christos : sizeof (Elf64_External_Shdr));
1120 1.7 christos
1121 1.7 christos /* Read the section headers. We skip section 0, which is not a
1122 1.7 christos useful section. */
1123 1.7 christos
1124 1.7 christos shnum = eor->shnum;
1125 1.7 christos shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
1126 1.7 christos
1127 1.7 christos if (!simple_object_internal_read (sobj->descriptor,
1128 1.7 christos sobj->offset + eor->shoff + shdr_size,
1129 1.7 christos shdrs,
1130 1.7 christos shdr_size * (shnum - 1),
1131 1.7 christos &errmsg, err))
1132 1.7 christos {
1133 1.7 christos XDELETEVEC (shdrs);
1134 1.7 christos return errmsg;
1135 1.7 christos }
1136 1.7 christos
1137 1.7 christos /* Read the section names. */
1138 1.7 christos
1139 1.7 christos shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size;
1140 1.7 christos name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1141 1.7 christos shstrhdr, sh_size, Elf_Addr);
1142 1.7 christos shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1143 1.7 christos shstrhdr, sh_offset, Elf_Addr);
1144 1.7 christos names = XNEWVEC (unsigned char, name_size);
1145 1.7 christos if (!simple_object_internal_read (sobj->descriptor,
1146 1.7 christos sobj->offset + shstroff,
1147 1.7 christos names, name_size, &errmsg, err))
1148 1.7 christos {
1149 1.7 christos XDELETEVEC (names);
1150 1.7 christos XDELETEVEC (shdrs);
1151 1.7 christos return errmsg;
1152 1.7 christos }
1153 1.7 christos
1154 1.7 christos pfnret = XNEWVEC (int, shnum);
1155 1.7 christos pfnname = XNEWVEC (const char *, shnum);
1156 1.7 christos
1157 1.7 christos /* Map of symtab to index section. */
1158 1.7 christos symtab_indices_shndx = XCNEWVEC (unsigned int, shnum - 1);
1159 1.7 christos
1160 1.7 christos /* First perform the callbacks to know which sections to preserve and
1161 1.7 christos what name to use for those. */
1162 1.7 christos for (i = 1; i < shnum; ++i)
1163 1.7 christos {
1164 1.7 christos unsigned char *shdr;
1165 1.7 christos unsigned int sh_name, sh_type;
1166 1.7 christos const char *name;
1167 1.7 christos char *ret;
1168 1.7 christos
1169 1.7 christos shdr = shdrs + (i - 1) * shdr_size;
1170 1.7 christos sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1171 1.7 christos shdr, sh_name, Elf_Word);
1172 1.7 christos if (sh_name >= name_size)
1173 1.7 christos {
1174 1.7 christos *err = 0;
1175 1.7 christos XDELETEVEC (names);
1176 1.7 christos XDELETEVEC (shdrs);
1177 1.7 christos return "ELF section name out of range";
1178 1.7 christos }
1179 1.7 christos
1180 1.7 christos name = (const char *) names + sh_name;
1181 1.7 christos
1182 1.7 christos ret = (*pfn) (name);
1183 1.7 christos pfnret[i - 1] = ret == NULL ? -1 : 0;
1184 1.7 christos pfnname[i - 1] = ret == NULL ? name : ret;
1185 1.11 christos if (first_shndx == 0 && pfnret[i - 1] == 0)
1186 1.7 christos first_shndx = i;
1187 1.7 christos
1188 1.7 christos /* Remember the indexes of existing SHT_SYMTAB_SHNDX sections. */
1189 1.7 christos sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1190 1.7 christos shdr, sh_type, Elf_Word);
1191 1.7 christos if (sh_type == SHT_SYMTAB_SHNDX)
1192 1.7 christos {
1193 1.7 christos unsigned int sh_link;
1194 1.7 christos sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1195 1.7 christos shdr, sh_link, Elf_Word);
1196 1.11 christos symtab_indices_shndx[sh_link - 1] = i;
1197 1.11 christos /* Discard the extended index sections, after copying it will not
1198 1.11 christos be needed, unless we need more than SHN_LORESERVE - 1 sections
1199 1.11 christos in the output. This way we don't need to update it and deal with
1200 1.11 christos the ordering constraints of processing the existing symtab and
1201 1.11 christos changing the index. */
1202 1.7 christos pfnret[i - 1] = -1;
1203 1.7 christos }
1204 1.7 christos }
1205 1.7 christos
1206 1.7 christos /* Mark sections as preserved that are required by to be preserved
1207 1.7 christos sections. */
1208 1.7 christos do
1209 1.7 christos {
1210 1.7 christos changed = 0;
1211 1.7 christos for (i = 1; i < shnum; ++i)
1212 1.7 christos {
1213 1.7 christos unsigned char *shdr;
1214 1.7 christos unsigned int sh_type, sh_info, sh_link;
1215 1.7 christos off_t offset;
1216 1.7 christos off_t length;
1217 1.7 christos
1218 1.7 christos shdr = shdrs + (i - 1) * shdr_size;
1219 1.7 christos sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1220 1.7 christos shdr, sh_type, Elf_Word);
1221 1.7 christos sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1222 1.7 christos shdr, sh_info, Elf_Word);
1223 1.7 christos sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1224 1.7 christos shdr, sh_link, Elf_Word);
1225 1.7 christos if (sh_type == SHT_GROUP)
1226 1.7 christos {
1227 1.7 christos /* Mark groups containing copied sections. */
1228 1.7 christos unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class,
1229 1.7 christos Shdr, shdr, sh_entsize,
1230 1.7 christos Elf_Addr);
1231 1.7 christos unsigned char *ent, *buf;
1232 1.7 christos int keep = 0;
1233 1.7 christos offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1234 1.7 christos shdr, sh_offset, Elf_Addr);
1235 1.7 christos length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1236 1.7 christos shdr, sh_size, Elf_Addr);
1237 1.7 christos buf = XNEWVEC (unsigned char, length);
1238 1.7 christos if (!simple_object_internal_read (sobj->descriptor,
1239 1.7 christos sobj->offset + offset, buf,
1240 1.7 christos (size_t) length, &errmsg, err))
1241 1.7 christos {
1242 1.7 christos XDELETEVEC (buf);
1243 1.7 christos XDELETEVEC (names);
1244 1.7 christos XDELETEVEC (shdrs);
1245 1.7 christos return errmsg;
1246 1.7 christos }
1247 1.7 christos for (ent = buf + entsize; ent < buf + length; ent += entsize)
1248 1.7 christos {
1249 1.7 christos unsigned sec = type_functions->fetch_Elf_Word (ent);
1250 1.7 christos if (pfnret[sec - 1] == 0)
1251 1.7 christos keep = 1;
1252 1.7 christos }
1253 1.7 christos if (keep)
1254 1.7 christos {
1255 1.7 christos changed |= (pfnret[sh_link - 1] == -1
1256 1.7 christos || pfnret[i - 1] == -1);
1257 1.7 christos pfnret[sh_link - 1] = 0;
1258 1.7 christos pfnret[i - 1] = 0;
1259 1.7 christos }
1260 1.7 christos }
1261 1.7 christos if (sh_type == SHT_RELA
1262 1.7 christos || sh_type == SHT_REL)
1263 1.7 christos {
1264 1.7 christos /* Mark relocation sections and symtab of copied sections. */
1265 1.7 christos if (pfnret[sh_info - 1] == 0)
1266 1.7 christos {
1267 1.7 christos changed |= (pfnret[sh_link - 1] == -1
1268 1.7 christos || pfnret[i - 1] == -1);
1269 1.7 christos pfnret[sh_link - 1] = 0;
1270 1.7 christos pfnret[i - 1] = 0;
1271 1.7 christos }
1272 1.7 christos }
1273 1.7 christos if (sh_type == SHT_SYMTAB)
1274 1.7 christos {
1275 1.7 christos /* Mark strings sections of copied symtabs. */
1276 1.7 christos if (pfnret[i - 1] == 0)
1277 1.7 christos {
1278 1.7 christos changed |= pfnret[sh_link - 1] == -1;
1279 1.7 christos pfnret[sh_link - 1] = 0;
1280 1.7 christos }
1281 1.7 christos }
1282 1.7 christos }
1283 1.7 christos }
1284 1.7 christos while (changed);
1285 1.7 christos
1286 1.7 christos /* Compute a mapping of old -> new section numbers. */
1287 1.7 christos sh_map = XNEWVEC (unsigned, shnum);
1288 1.7 christos sh_map[0] = 0;
1289 1.7 christos new_i = 1;
1290 1.7 christos for (i = 1; i < shnum; ++i)
1291 1.7 christos {
1292 1.7 christos if (pfnret[i - 1] == -1)
1293 1.7 christos sh_map[i] = 0;
1294 1.7 christos else
1295 1.7 christos sh_map[i] = new_i++;
1296 1.7 christos }
1297 1.11 christos first_symtab_indices_shndx = new_i;
1298 1.11 christos symtab_indices_shndx_buf = NULL;
1299 1.7 christos if (new_i - 1 >= SHN_LORESERVE)
1300 1.11 christos for (i = 1; i < shnum; ++i)
1301 1.11 christos if (pfnret[i - 1] == 0 && symtab_indices_shndx[i - 1] != 0)
1302 1.11 christos {
1303 1.11 christos pfnret[symtab_indices_shndx[i - 1] - 1] = 0;
1304 1.11 christos sh_map[symtab_indices_shndx[i - 1]] = new_i++;
1305 1.11 christos }
1306 1.11 christos new_count = new_i;
1307 1.11 christos if (new_count != first_symtab_indices_shndx)
1308 1.11 christos symtab_indices_shndx_buf
1309 1.11 christos = XNEWVEC (unsigned char *, new_count - first_symtab_indices_shndx);
1310 1.11 christos eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_count - 1));
1311 1.7 christos
1312 1.7 christos /* Then perform the actual copying. */
1313 1.7 christos new_i = 0;
1314 1.11 christos pass_symtab_indices_shndx = 0;
1315 1.11 christos for (i = 1; i <= shnum; ++i)
1316 1.7 christos {
1317 1.7 christos unsigned char *shdr;
1318 1.7 christos unsigned int sh_name, sh_type;
1319 1.7 christos const char *name;
1320 1.7 christos off_t offset;
1321 1.7 christos off_t length;
1322 1.7 christos simple_object_write_section *dest;
1323 1.7 christos off_t flags;
1324 1.7 christos unsigned char *buf;
1325 1.7 christos
1326 1.11 christos if (i == shnum)
1327 1.11 christos {
1328 1.11 christos if (new_count - 1 < SHN_LORESERVE || pass_symtab_indices_shndx)
1329 1.11 christos break;
1330 1.11 christos i = 0;
1331 1.11 christos pass_symtab_indices_shndx = 1;
1332 1.11 christos continue;
1333 1.11 christos }
1334 1.11 christos
1335 1.7 christos if (pfnret[i - 1])
1336 1.7 christos continue;
1337 1.7 christos
1338 1.11 christos shdr = shdrs + (i - 1) * shdr_size;
1339 1.11 christos sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1340 1.11 christos shdr, sh_type, Elf_Word);
1341 1.11 christos if (sh_type == SHT_SYMTAB_SHNDX)
1342 1.11 christos {
1343 1.11 christos if (!pass_symtab_indices_shndx)
1344 1.11 christos continue;
1345 1.11 christos }
1346 1.11 christos else if (pass_symtab_indices_shndx)
1347 1.11 christos continue;
1348 1.11 christos
1349 1.7 christos new_i++;
1350 1.7 christos sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1351 1.7 christos shdr, sh_name, Elf_Word);
1352 1.7 christos if (sh_name >= name_size)
1353 1.7 christos {
1354 1.7 christos *err = 0;
1355 1.7 christos XDELETEVEC (names);
1356 1.7 christos XDELETEVEC (shdrs);
1357 1.7 christos XDELETEVEC (symtab_indices_shndx);
1358 1.11 christos XDELETEVEC (symtab_indices_shndx_buf);
1359 1.7 christos return "ELF section name out of range";
1360 1.7 christos }
1361 1.7 christos
1362 1.7 christos name = pfnname[i - 1];
1363 1.7 christos offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1364 1.7 christos shdr, sh_offset, Elf_Addr);
1365 1.7 christos length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1366 1.7 christos shdr, sh_size, Elf_Addr);
1367 1.7 christos
1368 1.11 christos dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err);
1369 1.7 christos if (dest == NULL)
1370 1.7 christos {
1371 1.7 christos XDELETEVEC (names);
1372 1.7 christos XDELETEVEC (shdrs);
1373 1.7 christos XDELETEVEC (symtab_indices_shndx);
1374 1.11 christos XDELETEVEC (symtab_indices_shndx_buf);
1375 1.7 christos return errmsg;
1376 1.7 christos }
1377 1.7 christos
1378 1.7 christos /* Record the SHDR of the source. */
1379 1.7 christos memcpy (eow->shdrs + (new_i - 1) * shdr_size, shdr, shdr_size);
1380 1.7 christos shdr = eow->shdrs + (new_i - 1) * shdr_size;
1381 1.7 christos
1382 1.7 christos /* Copy the data.
1383 1.7 christos ??? This is quite wasteful and ideally would be delayed until
1384 1.7 christos write_to_file (). Thus it questions the interfacing
1385 1.7 christos which eventually should contain destination creation plus
1386 1.7 christos writing. */
1387 1.7 christos buf = XNEWVEC (unsigned char, length);
1388 1.7 christos if (!simple_object_internal_read (sobj->descriptor,
1389 1.7 christos sobj->offset + offset, buf,
1390 1.7 christos (size_t) length, &errmsg, err))
1391 1.7 christos {
1392 1.7 christos XDELETEVEC (buf);
1393 1.7 christos XDELETEVEC (names);
1394 1.7 christos XDELETEVEC (shdrs);
1395 1.7 christos XDELETEVEC (symtab_indices_shndx);
1396 1.11 christos XDELETEVEC (symtab_indices_shndx_buf);
1397 1.7 christos return errmsg;
1398 1.7 christos }
1399 1.7 christos
1400 1.8 christos /* If we are processing .symtab purge any symbols
1401 1.8 christos in discarded sections. */
1402 1.7 christos if (sh_type == SHT_SYMTAB)
1403 1.7 christos {
1404 1.7 christos unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1405 1.7 christos shdr, sh_entsize, Elf_Addr);
1406 1.8 christos size_t prevailing_name_idx = 0;
1407 1.7 christos unsigned char *ent;
1408 1.7 christos unsigned *shndx_table = NULL;
1409 1.7 christos /* Read the section index table if present. */
1410 1.7 christos if (symtab_indices_shndx[i - 1] != 0)
1411 1.7 christos {
1412 1.11 christos unsigned char *sidxhdr
1413 1.11 christos = shdrs + (symtab_indices_shndx[i - 1] - 1) * shdr_size;
1414 1.7 christos off_t sidxoff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1415 1.7 christos sidxhdr, sh_offset, Elf_Addr);
1416 1.7 christos size_t sidxsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1417 1.7 christos sidxhdr, sh_size, Elf_Addr);
1418 1.9 christos unsigned int shndx_type
1419 1.9 christos = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1420 1.9 christos sidxhdr, sh_type, Elf_Word);
1421 1.9 christos if (shndx_type != SHT_SYMTAB_SHNDX)
1422 1.9 christos return "Wrong section type of a SYMTAB SECTION INDICES section";
1423 1.11 christos shndx_table = (unsigned *) XNEWVEC (char, sidxsz);
1424 1.11 christos if (!simple_object_internal_read (sobj->descriptor,
1425 1.11 christos sobj->offset + sidxoff,
1426 1.11 christos (unsigned char *) shndx_table,
1427 1.11 christos sidxsz, &errmsg, err))
1428 1.11 christos {
1429 1.11 christos XDELETEVEC (buf);
1430 1.11 christos XDELETEVEC (names);
1431 1.11 christos XDELETEVEC (shdrs);
1432 1.11 christos XDELETEVEC (symtab_indices_shndx);
1433 1.11 christos XDELETEVEC (shndx_table);
1434 1.11 christos XDELETEVEC (symtab_indices_shndx_buf);
1435 1.11 christos return errmsg;
1436 1.11 christos }
1437 1.7 christos }
1438 1.8 christos
1439 1.8 christos /* Find a WEAK HIDDEN symbol which name we will use for removed
1440 1.8 christos symbols. We know there's a prevailing weak hidden symbol
1441 1.8 christos at the start of the .debug_info section. */
1442 1.8 christos for (ent = buf; ent < buf + length; ent += entsize)
1443 1.8 christos {
1444 1.8 christos unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
1445 1.8 christos Sym, ent,
1446 1.8 christos st_shndx, Elf_Half);
1447 1.8 christos unsigned char *st_info;
1448 1.8 christos unsigned char *st_other;
1449 1.8 christos if (ei_class == ELFCLASS32)
1450 1.8 christos {
1451 1.11 christos st_info = &((Elf32_External_Sym *) ent)->st_info;
1452 1.11 christos st_other = &((Elf32_External_Sym *) ent)->st_other;
1453 1.8 christos }
1454 1.8 christos else
1455 1.8 christos {
1456 1.11 christos st_info = &((Elf64_External_Sym *) ent)->st_info;
1457 1.11 christos st_other = &((Elf64_External_Sym *) ent)->st_other;
1458 1.8 christos }
1459 1.8 christos if (st_shndx == SHN_XINDEX)
1460 1.11 christos {
1461 1.11 christos unsigned char *ndx_ptr
1462 1.11 christos = (unsigned char *) (shndx_table + (ent - buf) / entsize);
1463 1.11 christos st_shndx = type_functions->fetch_Elf_Word (ndx_ptr);
1464 1.11 christos }
1465 1.8 christos
1466 1.8 christos if (st_shndx != SHN_COMMON
1467 1.8 christos && !(st_shndx != SHN_UNDEF
1468 1.8 christos && st_shndx < shnum
1469 1.8 christos && pfnret[st_shndx - 1] == -1)
1470 1.8 christos && ELF_ST_BIND (*st_info) == STB_WEAK
1471 1.8 christos && *st_other == STV_HIDDEN)
1472 1.8 christos {
1473 1.8 christos prevailing_name_idx = ELF_FETCH_FIELD (type_functions,
1474 1.8 christos ei_class, Sym, ent,
1475 1.8 christos st_name, Elf_Word);
1476 1.8 christos break;
1477 1.8 christos }
1478 1.8 christos }
1479 1.8 christos
1480 1.7 christos for (ent = buf; ent < buf + length; ent += entsize)
1481 1.7 christos {
1482 1.7 christos unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
1483 1.7 christos Sym, ent,
1484 1.7 christos st_shndx, Elf_Half);
1485 1.7 christos unsigned raw_st_shndx = st_shndx;
1486 1.7 christos unsigned char *st_info;
1487 1.7 christos unsigned char *st_other;
1488 1.7 christos int discard = 0;
1489 1.11 christos unsigned char *ndx_ptr = NULL;
1490 1.7 christos if (ei_class == ELFCLASS32)
1491 1.7 christos {
1492 1.11 christos st_info = &((Elf32_External_Sym *) ent)->st_info;
1493 1.11 christos st_other = &((Elf32_External_Sym *) ent)->st_other;
1494 1.7 christos }
1495 1.7 christos else
1496 1.7 christos {
1497 1.11 christos st_info = &((Elf64_External_Sym *) ent)->st_info;
1498 1.11 christos st_other = &((Elf64_External_Sym *) ent)->st_other;
1499 1.7 christos }
1500 1.11 christos if (shndx_table)
1501 1.11 christos ndx_ptr
1502 1.11 christos = (unsigned char *) (shndx_table + (ent - buf) / entsize);
1503 1.11 christos
1504 1.7 christos if (st_shndx == SHN_XINDEX)
1505 1.11 christos {
1506 1.11 christos st_shndx = type_functions->fetch_Elf_Word (ndx_ptr);
1507 1.11 christos type_functions->set_Elf_Word (ndx_ptr, SHN_UNDEF);
1508 1.11 christos }
1509 1.8 christos /* Eliminate all COMMONs - this includes __gnu_lto_slim
1510 1.8 christos which otherwise cause endless LTO plugin invocation.
1511 1.8 christos FIXME: remove the condition once we remove emission
1512 1.8 christos of __gnu_lto_slim symbol. */
1513 1.7 christos if (st_shndx == SHN_COMMON)
1514 1.7 christos discard = 1;
1515 1.7 christos /* We also need to remove symbols refering to sections
1516 1.7 christos we'll eventually remove as with fat LTO objects
1517 1.7 christos we otherwise get duplicate symbols at final link
1518 1.7 christos (with GNU ld, gold is fine and ignores symbols in
1519 1.7 christos sections marked as EXCLUDE). ld/20513 */
1520 1.7 christos else if (st_shndx != SHN_UNDEF
1521 1.7 christos && st_shndx < shnum
1522 1.7 christos && pfnret[st_shndx - 1] == -1)
1523 1.7 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.7 christos
1530 1.7 christos if (discard)
1531 1.7 christos {
1532 1.7 christos /* Make discarded symbols undefined and unnamed
1533 1.7 christos in case it is local. */
1534 1.7 christos int bind = ELF_ST_BIND (*st_info);
1535 1.7 christos int other = STV_DEFAULT;
1536 1.7 christos if (bind == STB_LOCAL)
1537 1.7 christos {
1538 1.7 christos /* Make discarded local symbols unnamed and
1539 1.7 christos defined in the first prevailing section. */
1540 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1541 1.7 christos ent, st_name, Elf_Word, 0);
1542 1.11 christos st_shndx = sh_map[first_shndx];
1543 1.11 christos if (st_shndx >= SHN_LORESERVE)
1544 1.11 christos {
1545 1.11 christos type_functions->set_Elf_Word (ndx_ptr, st_shndx);
1546 1.11 christos st_shndx = SHN_XINDEX;
1547 1.11 christos }
1548 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1549 1.11 christos ent, st_shndx, Elf_Half, st_shndx);
1550 1.7 christos }
1551 1.7 christos else
1552 1.7 christos {
1553 1.7 christos /* Make discarded global symbols hidden weak
1554 1.8 christos undefined and sharing a name of a prevailing
1555 1.8 christos symbol. */
1556 1.7 christos bind = STB_WEAK;
1557 1.7 christos other = STV_HIDDEN;
1558 1.8 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1559 1.8 christos ent, st_name, Elf_Word,
1560 1.8 christos prevailing_name_idx);
1561 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1562 1.7 christos ent, st_shndx, Elf_Half, SHN_UNDEF);
1563 1.7 christos }
1564 1.7 christos *st_other = other;
1565 1.7 christos *st_info = ELF_ST_INFO (bind, STT_NOTYPE);
1566 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1567 1.7 christos ent, st_value, Elf_Addr, 0);
1568 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1569 1.7 christos ent, st_size, Elf_Word, 0);
1570 1.7 christos }
1571 1.7 christos else if (raw_st_shndx < SHN_LORESERVE
1572 1.7 christos || raw_st_shndx == SHN_XINDEX)
1573 1.11 christos {
1574 1.11 christos /* Remap the section reference. */
1575 1.11 christos st_shndx = sh_map[st_shndx];
1576 1.11 christos if (st_shndx >= SHN_LORESERVE)
1577 1.11 christos {
1578 1.11 christos type_functions->set_Elf_Word (ndx_ptr, st_shndx);
1579 1.11 christos st_shndx = SHN_XINDEX;
1580 1.11 christos }
1581 1.11 christos ELF_SET_FIELD (type_functions, ei_class, Sym,
1582 1.11 christos ent, st_shndx, Elf_Half, st_shndx);
1583 1.11 christos }
1584 1.7 christos }
1585 1.11 christos if (symtab_indices_shndx_buf)
1586 1.11 christos symtab_indices_shndx_buf[sh_map[symtab_indices_shndx[i - 1]]
1587 1.11 christos - first_symtab_indices_shndx]
1588 1.11 christos = (unsigned char *) shndx_table;
1589 1.11 christos else
1590 1.11 christos XDELETEVEC (shndx_table);
1591 1.7 christos }
1592 1.7 christos else if (sh_type == SHT_GROUP)
1593 1.7 christos {
1594 1.7 christos /* Remap section indices in groups and remove removed members. */
1595 1.7 christos unsigned char *ent, *dst;
1596 1.7 christos for (dst = ent = buf + 4; ent < buf + length; ent += 4)
1597 1.7 christos {
1598 1.7 christos unsigned shndx = type_functions->fetch_Elf_Word (ent);
1599 1.7 christos if (pfnret[shndx - 1] == -1)
1600 1.7 christos ;
1601 1.7 christos else
1602 1.7 christos {
1603 1.7 christos type_functions->set_Elf_Word (dst, sh_map[shndx]);
1604 1.7 christos dst += 4;
1605 1.7 christos }
1606 1.7 christos }
1607 1.7 christos /* Adjust the length. */
1608 1.7 christos length = dst - buf;
1609 1.7 christos }
1610 1.11 christos else if (sh_type == SHT_SYMTAB_SHNDX)
1611 1.11 christos {
1612 1.11 christos XDELETEVEC (buf);
1613 1.11 christos buf = symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx];
1614 1.11 christos symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx] = NULL;
1615 1.11 christos }
1616 1.7 christos
1617 1.11 christos errmsg = simple_object_write_add_data (dobj, dest, buf, length, 1, err);
1618 1.7 christos XDELETEVEC (buf);
1619 1.7 christos if (errmsg)
1620 1.7 christos {
1621 1.7 christos XDELETEVEC (names);
1622 1.7 christos XDELETEVEC (shdrs);
1623 1.7 christos XDELETEVEC (symtab_indices_shndx);
1624 1.11 christos XDELETEVEC (symtab_indices_shndx_buf);
1625 1.7 christos return errmsg;
1626 1.7 christos }
1627 1.7 christos
1628 1.7 christos flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1629 1.7 christos shdr, sh_flags, Elf_Addr);
1630 1.7 christos /* Remap the section references. */
1631 1.7 christos {
1632 1.7 christos unsigned int sh_info, sh_link;
1633 1.7 christos if (flags & SHF_INFO_LINK || sh_type == SHT_REL || sh_type == SHT_RELA)
1634 1.7 christos {
1635 1.7 christos sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1636 1.7 christos shdr, sh_info, Elf_Word);
1637 1.9 christos sh_info = sh_map[sh_info];
1638 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Shdr,
1639 1.7 christos shdr, sh_info, Elf_Word, sh_info);
1640 1.7 christos }
1641 1.7 christos sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
1642 1.7 christos shdr, sh_link, Elf_Word);
1643 1.9 christos sh_link = sh_map[sh_link];
1644 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Shdr,
1645 1.7 christos shdr, sh_link, Elf_Word, sh_link);
1646 1.7 christos }
1647 1.7 christos /* The debugobj doesn't contain any code, thus no trampolines.
1648 1.7 christos Even when the original object needs trampolines, debugobj
1649 1.7 christos doesn't. */
1650 1.7 christos if (strcmp (name, ".note.GNU-stack") == 0)
1651 1.7 christos flags &= ~SHF_EXECINSTR;
1652 1.7 christos /* Clear SHF_EXCLUDE on to be preserved sections. */
1653 1.7 christos flags &= ~SHF_EXCLUDE;
1654 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Shdr,
1655 1.7 christos shdr, sh_flags, Elf_Addr, flags);
1656 1.7 christos }
1657 1.7 christos
1658 1.7 christos XDELETEVEC (names);
1659 1.7 christos XDELETEVEC (shdrs);
1660 1.7 christos XDELETEVEC (pfnret);
1661 1.7 christos XDELETEVEC (pfnname);
1662 1.7 christos XDELETEVEC (symtab_indices_shndx);
1663 1.7 christos XDELETEVEC (sh_map);
1664 1.11 christos XDELETEVEC (symtab_indices_shndx_buf);
1665 1.7 christos
1666 1.7 christos return NULL;
1667 1.7 christos }
1668 1.7 christos
1669 1.7 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.7 christos simple_object_elf_release_write,
1683 1.7 christos simple_object_elf_copy_lto_debug_sections
1684 1.1 christos };
1685