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