Subversion Repositories Kolibri OS

Rev

Rev 5191 | Details | Compare with Previous | 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;
6324 serge 701
  unsigned int shstrndx;
5191 serge 702
 
703
  fns = attrs->type_functions;
704
  cl = attrs->ei_class;
705
 
706
  shnum = 0;
707
  for (section = sobj->sections; section != NULL; section = section->next)
708
    ++shnum;
709
  if (shnum > 0)
710
    {
711
      /* Add a section header for the dummy section and one for
712
	 .shstrtab.  */
713
      shnum += 2;
714
    }
715
 
716
  ehdr_size = (cl == ELFCLASS32
717
	       ? sizeof (Elf32_External_Ehdr)
718
	       : sizeof (Elf64_External_Ehdr));
719
  memset (buf, 0, sizeof (Elf64_External_Ehdr));
720
 
721
  buf[EI_MAG0] = ELFMAG0;
722
  buf[EI_MAG1] = ELFMAG1;
723
  buf[EI_MAG2] = ELFMAG2;
724
  buf[EI_MAG3] = ELFMAG3;
725
  buf[EI_CLASS] = cl;
726
  buf[EI_DATA] = attrs->ei_data;
727
  buf[EI_VERSION] = EV_CURRENT;
728
  buf[EI_OSABI] = attrs->ei_osabi;
729
 
730
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_type, Elf_Half, ET_REL);
731
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_machine, Elf_Half, attrs->machine);
732
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_version, Elf_Word, EV_CURRENT);
733
  /* e_entry left as zero.  */
734
  /* e_phoff left as zero.  */
735
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shoff, Elf_Addr, ehdr_size);
736
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_flags, Elf_Word, attrs->flags);
737
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_ehsize, Elf_Half, ehdr_size);
738
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_phentsize, Elf_Half,
739
		 (cl == ELFCLASS32
740
		  ? sizeof (Elf32_External_Phdr)
741
		  : sizeof (Elf64_External_Phdr)));
742
  /* e_phnum left as zero.  */
743
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half,
744
		 (cl == ELFCLASS32
745
		  ? sizeof (Elf32_External_Shdr)
746
		  : sizeof (Elf64_External_Shdr)));
6324 serge 747
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half,
748
		 shnum >= SHN_LORESERVE ? 0 : shnum);
749
  if (shnum == 0)
750
    shstrndx = 0;
751
  else
752
    {
753
      shstrndx = shnum - 1;
754
      if (shstrndx >= SHN_LORESERVE)
755
	shstrndx = SHN_XINDEX;
756
    }
757
  ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx);
5191 serge 758
 
759
  return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
760
				       errmsg, err);
761
}
762
 
763
/* Write out an ELF shdr.  */
764
 
765
static int
766
simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
767
			      off_t offset, unsigned int sh_name,
768
			      unsigned int sh_type, unsigned int sh_flags,
769
			      unsigned int sh_offset, unsigned int sh_size,
6324 serge 770
			      unsigned int sh_link, unsigned int sh_addralign,
771
			      const char **errmsg, int *err)
5191 serge 772
{
773
  struct simple_object_elf_attributes *attrs =
774
    (struct simple_object_elf_attributes *) sobj->data;
775
  const struct elf_type_functions* fns;
776
  unsigned char cl;
777
  size_t shdr_size;
778
  unsigned char buf[sizeof (Elf64_External_Shdr)];
779
 
780
  fns = attrs->type_functions;
781
  cl = attrs->ei_class;
782
 
783
  shdr_size = (cl == ELFCLASS32
784
	       ? sizeof (Elf32_External_Shdr)
785
	       : sizeof (Elf64_External_Shdr));
786
  memset (buf, 0, sizeof (Elf64_External_Shdr));
787
 
788
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name);
789
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type);
790
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
791
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
792
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
6324 serge 793
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link);
5191 serge 794
  /* sh_info left as zero.  */
795
  ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
796
  /* sh_entsize left as zero.  */
797
 
798
  return simple_object_internal_write (descriptor, offset, buf, shdr_size,
799
				       errmsg, err);
800
}
801
 
802
/* Write out a complete ELF file.
803
   Ehdr
804
   initial dummy Shdr
805
   user-created Shdrs
806
   .shstrtab Shdr
807
   user-created section data
808
   .shstrtab data  */
809
 
810
static const char *
811
simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
812
				 int *err)
813
{
814
  struct simple_object_elf_attributes *attrs =
815
    (struct simple_object_elf_attributes *) sobj->data;
816
  unsigned char cl;
817
  size_t ehdr_size;
818
  size_t shdr_size;
819
  const char *errmsg;
820
  simple_object_write_section *section;
821
  unsigned int shnum;
822
  size_t shdr_offset;
823
  size_t sh_offset;
6324 serge 824
  unsigned int first_sh_size;
825
  unsigned int first_sh_link;
5191 serge 826
  size_t sh_name;
827
  unsigned char zero;
828
 
829
  if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err))
830
    return errmsg;
831
 
832
  cl = attrs->ei_class;
833
  if (cl == ELFCLASS32)
834
    {
835
      ehdr_size = sizeof (Elf32_External_Ehdr);
836
      shdr_size = sizeof (Elf32_External_Shdr);
837
    }
838
  else
839
    {
840
      ehdr_size = sizeof (Elf64_External_Ehdr);
841
      shdr_size = sizeof (Elf64_External_Shdr);
842
    }
843
 
844
  shnum = 0;
845
  for (section = sobj->sections; section != NULL; section = section->next)
846
    ++shnum;
847
  if (shnum == 0)
848
    return NULL;
849
 
850
  /* Add initial dummy Shdr and .shstrtab.  */
851
  shnum += 2;
852
 
853
  shdr_offset = ehdr_size;
854
  sh_offset = shdr_offset + shnum * shdr_size;
855
 
6324 serge 856
  if (shnum < SHN_LORESERVE)
857
    first_sh_size = 0;
858
  else
859
    first_sh_size = shnum;
860
  if (shnum - 1 < SHN_LORESERVE)
861
    first_sh_link = 0;
862
  else
863
    first_sh_link = shnum - 1;
5191 serge 864
  if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
6324 serge 865
				     0, 0, 0, 0, first_sh_size, first_sh_link,
866
				     0, &errmsg, err))
5191 serge 867
    return errmsg;
868
 
869
  shdr_offset += shdr_size;
870
 
871
  sh_name = 1;
872
  for (section = sobj->sections; section != NULL; section = section->next)
873
    {
874
      size_t mask;
875
      size_t new_sh_offset;
876
      size_t sh_size;
877
      struct simple_object_write_section_buffer *buffer;
878
 
879
      mask = (1U << section->align) - 1;
880
      new_sh_offset = sh_offset + mask;
881
      new_sh_offset &= ~ mask;
882
      while (new_sh_offset > sh_offset)
883
	{
884
	  unsigned char zeroes[16];
885
	  size_t write;
886
 
887
	  memset (zeroes, 0, sizeof zeroes);
888
	  write = new_sh_offset - sh_offset;
889
	  if (write > sizeof zeroes)
890
	    write = sizeof zeroes;
891
	  if (!simple_object_internal_write (descriptor, sh_offset, zeroes,
892
					     write, &errmsg, err))
893
	    return errmsg;
894
	  sh_offset += write;
895
	}
896
 
897
      sh_size = 0;
898
      for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
899
	{
900
	  if (!simple_object_internal_write (descriptor, sh_offset + sh_size,
901
					     ((const unsigned char *)
902
					      buffer->buffer),
903
					     buffer->size, &errmsg, err))
904
	    return errmsg;
905
	  sh_size += buffer->size;
906
	}
907
 
908
      if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
909
					 sh_name, SHT_PROGBITS, 0, sh_offset,
6324 serge 910
					 sh_size, 0, 1U << section->align,
5191 serge 911
					 &errmsg, err))
912
	return errmsg;
913
 
914
      shdr_offset += shdr_size;
915
      sh_name += strlen (section->name) + 1;
916
      sh_offset += sh_size;
917
    }
918
 
919
  if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
920
				     sh_name, SHT_STRTAB, 0, sh_offset,
6324 serge 921
				     sh_name + strlen (".shstrtab") + 1, 0,
5191 serge 922
				     1, &errmsg, err))
923
    return errmsg;
924
 
925
  /* .shstrtab has a leading zero byte.  */
926
  zero = 0;
927
  if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1,
928
				     &errmsg, err))
929
    return errmsg;
930
  ++sh_offset;
931
 
932
  for (section = sobj->sections; section != NULL; section = section->next)
933
    {
934
      size_t len;
935
 
936
      len = strlen (section->name) + 1;
937
      if (!simple_object_internal_write (descriptor, sh_offset,
938
					 (const unsigned char *) section->name,
939
					 len, &errmsg, err))
940
	return errmsg;
941
      sh_offset += len;
942
    }
943
 
944
  if (!simple_object_internal_write (descriptor, sh_offset,
945
				     (const unsigned char *) ".shstrtab",
946
				     strlen (".shstrtab") + 1, &errmsg, err))
947
    return errmsg;
948
 
949
  return NULL;
950
}
951
 
952
/* Release the private data for an simple_object_write structure.  */
953
 
954
static void
955
simple_object_elf_release_write (void *data)
956
{
957
  XDELETE (data);
958
}
959
 
960
/* The ELF functions.  */
961
 
962
const struct simple_object_functions simple_object_elf_functions =
963
{
964
  simple_object_elf_match,
965
  simple_object_elf_find_sections,
966
  simple_object_elf_fetch_attributes,
967
  simple_object_elf_release_read,
968
  simple_object_elf_attributes_merge,
969
  simple_object_elf_release_attributes,
970
  simple_object_elf_start_write,
971
  simple_object_elf_write_to_file,
972
  simple_object_elf_release_write
973
};