Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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