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