Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5197 serge 1
/* Support for the generic parts of PE/PEI, for BFD.
2
   Copyright 1995-2013 Free Software Foundation, Inc.
3
   Written by Cygnus Solutions.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
 
23
/* Most of this hacked by  Steve Chamberlain,
24
			sac@cygnus.com
25
 
26
   PE/PEI rearrangement (and code added): Donn Terry
27
                                       Softway Systems, Inc.  */
28
 
29
/* Hey look, some documentation [and in a place you expect to find it]!
30
 
31
   The main reference for the pei format is "Microsoft Portable Executable
32
   and Common Object File Format Specification 4.1".  Get it if you need to
33
   do some serious hacking on this code.
34
 
35
   Another reference:
36
   "Peering Inside the PE: A Tour of the Win32 Portable Executable
37
   File Format", MSJ 1994, Volume 9.
38
 
39
   The *sole* difference between the pe format and the pei format is that the
40
   latter has an MSDOS 2.0 .exe header on the front that prints the message
41
   "This app must be run under Windows." (or some such).
42
   (FIXME: Whether that statement is *really* true or not is unknown.
43
   Are there more subtle differences between pe and pei formats?
44
   For now assume there aren't.  If you find one, then for God sakes
45
   document it here!)
46
 
47
   The Microsoft docs use the word "image" instead of "executable" because
48
   the former can also refer to a DLL (shared library).  Confusion can arise
49
   because the `i' in `pei' also refers to "image".  The `pe' format can
50
   also create images (i.e. executables), it's just that to run on a win32
51
   system you need to use the pei format.
52
 
53
   FIXME: Please add more docs here so the next poor fool that has to hack
54
   on this code has a chance of getting something accomplished without
55
   wasting too much time.  */
56
 
57
#include "libpei.h"
58
 
59
static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
60
#ifndef coff_bfd_print_private_bfd_data
61
     NULL;
62
#else
63
     coff_bfd_print_private_bfd_data;
64
#undef coff_bfd_print_private_bfd_data
65
#endif
66
 
67
static bfd_boolean                      pe_print_private_bfd_data (bfd *, void *);
68
#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
69
 
70
static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
71
#ifndef coff_bfd_copy_private_bfd_data
72
     NULL;
73
#else
74
     coff_bfd_copy_private_bfd_data;
75
#undef coff_bfd_copy_private_bfd_data
76
#endif
77
 
78
static bfd_boolean                     pe_bfd_copy_private_bfd_data (bfd *, bfd *);
79
#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
80
 
81
#define coff_mkobject      pe_mkobject
82
#define coff_mkobject_hook pe_mkobject_hook
83
 
84
#ifdef COFF_IMAGE_WITH_PE
85
/* This structure contains static variables used by the ILF code.  */
86
typedef asection * asection_ptr;
87
 
88
typedef struct
89
{
90
  bfd *			abfd;
91
  bfd_byte *		data;
92
  struct bfd_in_memory * bim;
93
  unsigned short        magic;
94
 
95
  arelent *		reltab;
96
  unsigned int 		relcount;
97
 
98
  coff_symbol_type * 	sym_cache;
99
  coff_symbol_type * 	sym_ptr;
100
  unsigned int       	sym_index;
101
 
102
  unsigned int * 	sym_table;
103
  unsigned int * 	table_ptr;
104
 
105
  combined_entry_type * native_syms;
106
  combined_entry_type * native_ptr;
107
 
108
  coff_symbol_type **	sym_ptr_table;
109
  coff_symbol_type **	sym_ptr_ptr;
110
 
111
  unsigned int		sec_index;
112
 
113
  char *                string_table;
114
  char *                string_ptr;
115
  char *		end_string_ptr;
116
 
117
  SYMENT *              esym_table;
118
  SYMENT *              esym_ptr;
119
 
120
  struct internal_reloc * int_reltab;
121
}
122
pe_ILF_vars;
123
#endif /* COFF_IMAGE_WITH_PE */
124
 
125
const bfd_target *coff_real_object_p
126
  (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
127
 
128
#ifndef NO_COFF_RELOCS
129
static void
130
coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
131
{
132
  RELOC *reloc_src = (RELOC *) src;
133
  struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
134
 
135
  reloc_dst->r_vaddr  = H_GET_32 (abfd, reloc_src->r_vaddr);
136
  reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
137
  reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
138
#ifdef SWAP_IN_RELOC_OFFSET
139
  reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
140
#endif
141
}
142
 
143
static unsigned int
144
coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
145
{
146
  struct internal_reloc *reloc_src = (struct internal_reloc *) src;
147
  struct external_reloc *reloc_dst = (struct external_reloc *) dst;
148
 
149
  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
150
  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
151
  H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
152
 
153
#ifdef SWAP_OUT_RELOC_OFFSET
154
  SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
155
#endif
156
#ifdef SWAP_OUT_RELOC_EXTRA
157
  SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
158
#endif
159
  return RELSZ;
160
}
161
#endif /* not NO_COFF_RELOCS */
162
 
163
#ifdef COFF_IMAGE_WITH_PE
164
#undef FILHDR
165
#define FILHDR struct external_PEI_IMAGE_hdr
166
#endif
167
 
168
static void
169
coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
170
{
171
  FILHDR *filehdr_src = (FILHDR *) src;
172
  struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
173
 
174
  filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
175
  filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
176
  filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
177
  filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
178
  filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
179
  filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr);
180
 
181
  /* Other people's tools sometimes generate headers with an nsyms but
182
     a zero symptr.  */
183
  if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
184
    {
185
      filehdr_dst->f_nsyms = 0;
186
      filehdr_dst->f_flags |= F_LSYMS;
187
    }
188
 
189
  filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr);
190
}
191
 
192
#ifdef COFF_IMAGE_WITH_PE
193
# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
194
#elif defined COFF_WITH_pex64
195
# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
196
#elif defined COFF_WITH_pep
197
# define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
198
#else
199
# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
200
#endif
201
 
202
static void
203
coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
204
{
205
  SCNHDR *scnhdr_ext = (SCNHDR *) ext;
206
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
207
 
208
  memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
209
 
210
  scnhdr_int->s_vaddr   = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
211
  scnhdr_int->s_paddr   = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
212
  scnhdr_int->s_size    = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
213
  scnhdr_int->s_scnptr  = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
214
  scnhdr_int->s_relptr  = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
215
  scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
216
  scnhdr_int->s_flags   = H_GET_32 (abfd, scnhdr_ext->s_flags);
217
 
218
  /* MS handles overflow of line numbers by carrying into the reloc
219
     field (it appears).  Since it's supposed to be zero for PE
220
     *IMAGE* format, that's safe.  This is still a bit iffy.  */
221
#ifdef COFF_IMAGE_WITH_PE
222
  scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
223
			 + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
224
  scnhdr_int->s_nreloc = 0;
225
#else
226
  scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
227
  scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
228
#endif
229
 
230
  if (scnhdr_int->s_vaddr != 0)
231
    {
232
      scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
233
      /* Do not cut upper 32-bits for 64-bit vma.  */
234
#ifndef COFF_WITH_pex64
235
      scnhdr_int->s_vaddr &= 0xffffffff;
236
#endif
237
    }
238
 
239
#ifndef COFF_NO_HACK_SCNHDR_SIZE
240
  /* If this section holds uninitialized data and is from an object file
241
     or from an executable image that has not initialized the field,
242
     or if the image is an executable file and the physical size is padded,
243
     use the virtual size (stored in s_paddr) instead.  */
244
  if (scnhdr_int->s_paddr > 0
245
      && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
246
	   && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
247
          || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
248
  /* This code used to set scnhdr_int->s_paddr to 0.  However,
249
     coff_set_alignment_hook stores s_paddr in virt_size, which
250
     only works if it correctly holds the virtual size of the
251
     section.  */
252
    scnhdr_int->s_size = scnhdr_int->s_paddr;
253
#endif
254
}
255
 
256
static bfd_boolean
257
pe_mkobject (bfd * abfd)
258
{
259
  pe_data_type *pe;
260
  bfd_size_type amt = sizeof (pe_data_type);
261
 
262
  abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
263
 
264
  if (abfd->tdata.pe_obj_data == 0)
265
    return FALSE;
266
 
267
  pe = pe_data (abfd);
268
 
269
  pe->coff.pe = 1;
270
 
271
  /* in_reloc_p is architecture dependent.  */
272
  pe->in_reloc_p = in_reloc_p;
273
 
274
  return TRUE;
275
}
276
 
277
/* Create the COFF backend specific information.  */
278
 
279
static void *
280
pe_mkobject_hook (bfd * abfd,
281
		  void * filehdr,
282
		  void * aouthdr ATTRIBUTE_UNUSED)
283
{
284
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
285
  pe_data_type *pe;
286
 
287
  if (! pe_mkobject (abfd))
288
    return NULL;
289
 
290
  pe = pe_data (abfd);
291
  pe->coff.sym_filepos = internal_f->f_symptr;
292
  /* These members communicate important constants about the symbol
293
     table to GDB's symbol-reading code.  These `constants'
294
     unfortunately vary among coff implementations...  */
295
  pe->coff.local_n_btmask = N_BTMASK;
296
  pe->coff.local_n_btshft = N_BTSHFT;
297
  pe->coff.local_n_tmask = N_TMASK;
298
  pe->coff.local_n_tshift = N_TSHIFT;
299
  pe->coff.local_symesz = SYMESZ;
300
  pe->coff.local_auxesz = AUXESZ;
301
  pe->coff.local_linesz = LINESZ;
302
 
303
  pe->coff.timestamp = internal_f->f_timdat;
304
 
305
  obj_raw_syment_count (abfd) =
306
    obj_conv_table_size (abfd) =
307
      internal_f->f_nsyms;
308
 
309
  pe->real_flags = internal_f->f_flags;
310
 
311
  if ((internal_f->f_flags & F_DLL) != 0)
312
    pe->dll = 1;
313
 
314
  if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
315
    abfd->flags |= HAS_DEBUG;
316
 
317
#ifdef COFF_IMAGE_WITH_PE
318
  if (aouthdr)
319
    pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe;
320
#endif
321
 
322
#ifdef ARM
323
  if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
324
    coff_data (abfd) ->flags = 0;
325
#endif
326
 
327
  return (void *) pe;
328
}
329
 
330
static bfd_boolean
331
pe_print_private_bfd_data (bfd *abfd, void * vfile)
332
{
333
  FILE *file = (FILE *) vfile;
334
 
335
  if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
336
    return FALSE;
337
 
338
  if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
339
    return TRUE;
340
 
341
  fputc ('\n', file);
342
 
343
  return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
344
}
345
 
346
/* Copy any private info we understand from the input bfd
347
   to the output bfd.  */
348
 
349
static bfd_boolean
350
pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
351
{
352
  /* PR binutils/716: Copy the large address aware flag.
353
     XXX: Should we be copying other flags or other fields in the pe_data()
354
     structure ?  */
355
  if (pe_data (obfd) != NULL
356
      && pe_data (ibfd) != NULL
357
      && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
358
    pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
359
 
360
  if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
361
    return FALSE;
362
 
363
  if (pe_saved_coff_bfd_copy_private_bfd_data)
364
    return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
365
 
366
  return TRUE;
367
}
368
 
369
#define coff_bfd_copy_private_section_data \
370
  _bfd_XX_bfd_copy_private_section_data
371
 
372
#define coff_get_symbol_info _bfd_XX_get_symbol_info
373
 
374
#ifdef COFF_IMAGE_WITH_PE
375
 
376
/* Code to handle Microsoft's Image Library Format.
377
   Also known as LINK6 format.
378
   Documentation about this format can be found at:
379
 
380
   http://msdn.microsoft.com/library/specs/pecoff_section8.htm  */
381
 
382
/* The following constants specify the sizes of the various data
383
   structures that we have to create in order to build a bfd describing
384
   an ILF object file.  The final "+ 1" in the definitions of SIZEOF_IDATA6
385
   and SIZEOF_IDATA7 below is to allow for the possibility that we might
386
   need a padding byte in order to ensure 16 bit alignment for the section's
387
   contents.
388
 
389
   The value for SIZEOF_ILF_STRINGS is computed as follows:
390
 
391
      There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
392
      per symbol for their names (longest section name is .idata$x).
393
 
394
      There will be two symbols for the imported value, one the symbol name
395
      and one with _imp__ prefixed.  Allowing for the terminating nul's this
396
      is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
397
 
398
      The strings in the string table must start STRING__SIZE_SIZE bytes into
399
      the table in order to for the string lookup code in coffgen/coffcode to
400
      work.  */
401
#define NUM_ILF_RELOCS		8
402
#define NUM_ILF_SECTIONS        6
403
#define NUM_ILF_SYMS 		(2 + NUM_ILF_SECTIONS)
404
 
405
#define SIZEOF_ILF_SYMS		 (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
406
#define SIZEOF_ILF_SYM_TABLE	 (NUM_ILF_SYMS * sizeof (* vars.sym_table))
407
#define SIZEOF_ILF_NATIVE_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.native_syms))
408
#define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
409
#define SIZEOF_ILF_EXT_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.esym_table))
410
#define SIZEOF_ILF_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.reltab))
411
#define SIZEOF_ILF_INT_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
412
#define SIZEOF_ILF_STRINGS	 (strlen (symbol_name) * 2 + 8 \
413
					+ 21 + strlen (source_dll) \
414
					+ NUM_ILF_SECTIONS * 9 \
415
					+ STRING_SIZE_SIZE)
416
#define SIZEOF_IDATA2		(5 * 4)
417
 
418
/* For PEx64 idata4 & 5 have thumb size of 8 bytes.  */
419
#ifdef COFF_WITH_pex64
420
#define SIZEOF_IDATA4		(2 * 4)
421
#define SIZEOF_IDATA5		(2 * 4)
422
#else
423
#define SIZEOF_IDATA4		(1 * 4)
424
#define SIZEOF_IDATA5		(1 * 4)
425
#endif
426
 
427
#define SIZEOF_IDATA6		(2 + strlen (symbol_name) + 1 + 1)
428
#define SIZEOF_IDATA7		(strlen (source_dll) + 1 + 1)
429
#define SIZEOF_ILF_SECTIONS     (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
430
 
431
#define ILF_DATA_SIZE				\
432
    + SIZEOF_ILF_SYMS				\
433
    + SIZEOF_ILF_SYM_TABLE			\
434
    + SIZEOF_ILF_NATIVE_SYMS			\
435
    + SIZEOF_ILF_SYM_PTR_TABLE			\
436
    + SIZEOF_ILF_EXT_SYMS			\
437
    + SIZEOF_ILF_RELOCS				\
438
    + SIZEOF_ILF_INT_RELOCS			\
439
    + SIZEOF_ILF_STRINGS			\
440
    + SIZEOF_IDATA2				\
441
    + SIZEOF_IDATA4				\
442
    + SIZEOF_IDATA5				\
443
    + SIZEOF_IDATA6				\
444
    + SIZEOF_IDATA7				\
445
    + SIZEOF_ILF_SECTIONS			\
446
    + MAX_TEXT_SECTION_SIZE
447
 
448
/* Create an empty relocation against the given symbol.  */
449
 
450
static void
451
pe_ILF_make_a_symbol_reloc (pe_ILF_vars *               vars,
452
			    bfd_vma                     address,
453
			    bfd_reloc_code_real_type    reloc,
454
			    struct bfd_symbol **  	sym,
455
			    unsigned int                sym_index)
456
{
457
  arelent * entry;
458
  struct internal_reloc * internal;
459
 
460
  entry = vars->reltab + vars->relcount;
461
  internal = vars->int_reltab + vars->relcount;
462
 
463
  entry->address     = address;
464
  entry->addend      = 0;
465
  entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
466
  entry->sym_ptr_ptr = sym;
467
 
468
  internal->r_vaddr  = address;
469
  internal->r_symndx = sym_index;
470
  internal->r_type   = entry->howto->type;
471
 
472
  vars->relcount ++;
473
 
474
  BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
475
}
476
 
477
/* Create an empty relocation against the given section.  */
478
 
479
static void
480
pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
481
		     bfd_vma                   address,
482
		     bfd_reloc_code_real_type  reloc,
483
		     asection_ptr              sec)
484
{
485
  pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
486
			      coff_section_data (vars->abfd, sec)->i);
487
}
488
 
489
/* Move the queued relocs into the given section.  */
490
 
491
static void
492
pe_ILF_save_relocs (pe_ILF_vars * vars,
493
		    asection_ptr  sec)
494
{
495
  /* Make sure that there is somewhere to store the internal relocs.  */
496
  if (coff_section_data (vars->abfd, sec) == NULL)
497
    /* We should probably return an error indication here.  */
498
    abort ();
499
 
500
  coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
501
  coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
502
 
503
  sec->relocation  = vars->reltab;
504
  sec->reloc_count = vars->relcount;
505
  sec->flags      |= SEC_RELOC;
506
 
507
  vars->reltab     += vars->relcount;
508
  vars->int_reltab += vars->relcount;
509
  vars->relcount   = 0;
510
 
511
  BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
512
}
513
 
514
/* Create a global symbol and add it to the relevant tables.  */
515
 
516
static void
517
pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
518
		      const char *   prefix,
519
		      const char *   symbol_name,
520
		      asection_ptr   section,
521
		      flagword       extra_flags)
522
{
523
  coff_symbol_type * sym;
524
  combined_entry_type * ent;
525
  SYMENT * esym;
526
  unsigned short sclass;
527
 
528
  if (extra_flags & BSF_LOCAL)
529
    sclass = C_STAT;
530
  else
531
    sclass = C_EXT;
532
 
533
#ifdef THUMBPEMAGIC
534
  if (vars->magic == THUMBPEMAGIC)
535
    {
536
      if (extra_flags & BSF_FUNCTION)
537
	sclass = C_THUMBEXTFUNC;
538
      else if (extra_flags & BSF_LOCAL)
539
	sclass = C_THUMBSTAT;
540
      else
541
	sclass = C_THUMBEXT;
542
    }
543
#endif
544
 
545
  BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
546
 
547
  sym = vars->sym_ptr;
548
  ent = vars->native_ptr;
549
  esym = vars->esym_ptr;
550
 
551
  /* Copy the symbol's name into the string table.  */
552
  sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
553
 
554
  if (section == NULL)
555
    section = bfd_und_section_ptr;
556
 
557
  /* Initialise the external symbol.  */
558
  H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
559
	    esym->e.e.e_offset);
560
  H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
561
  esym->e_sclass[0] = sclass;
562
 
563
  /* The following initialisations are unnecessary - the memory is
564
     zero initialised.  They are just kept here as reminders.  */
565
 
566
  /* Initialise the internal symbol structure.  */
567
  ent->u.syment.n_sclass          = sclass;
568
  ent->u.syment.n_scnum           = section->target_index;
569
  ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
570
 
571
  sym->symbol.the_bfd = vars->abfd;
572
  sym->symbol.name    = vars->string_ptr;
573
  sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
574
  sym->symbol.section = section;
575
  sym->native         = ent;
576
 
577
  * vars->table_ptr = vars->sym_index;
578
  * vars->sym_ptr_ptr = sym;
579
 
580
  /* Adjust pointers for the next symbol.  */
581
  vars->sym_index ++;
582
  vars->sym_ptr ++;
583
  vars->sym_ptr_ptr ++;
584
  vars->table_ptr ++;
585
  vars->native_ptr ++;
586
  vars->esym_ptr ++;
587
  vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
588
 
589
  BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
590
}
591
 
592
/* Create a section.  */
593
 
594
static asection_ptr
595
pe_ILF_make_a_section (pe_ILF_vars * vars,
596
		       const char *  name,
597
		       unsigned int  size,
598
		       flagword      extra_flags)
599
{
600
  asection_ptr sec;
601
  flagword     flags;
602
 
603
  sec = bfd_make_section_old_way (vars->abfd, name);
604
  if (sec == NULL)
605
    return NULL;
606
 
607
  flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
608
 
609
  bfd_set_section_flags (vars->abfd, sec, flags | extra_flags);
610
 
611
  (void) bfd_set_section_alignment (vars->abfd, sec, 2);
612
 
613
  /* Check that we will not run out of space.  */
614
  BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
615
 
616
  /* Set the section size and contents.  The actual
617
     contents are filled in by our parent.  */
618
  bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size);
619
  sec->contents = vars->data;
620
  sec->target_index = vars->sec_index ++;
621
 
622
  /* Advance data pointer in the vars structure.  */
623
  vars->data += size;
624
 
625
  /* Skip the padding byte if it was not needed.
626
     The logic here is that if the string length is odd,
627
     then the entire string length, including the null byte,
628
     is even and so the extra, padding byte, is not needed.  */
629
  if (size & 1)
630
    vars->data --;
631
 
632
  /* Create a coff_section_tdata structure for our use.  */
633
  sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
634
  vars->data += sizeof (struct coff_section_tdata);
635
 
636
  BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
637
 
638
  /* Create a symbol to refer to this section.  */
639
  pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
640
 
641
  /* Cache the index to the symbol in the coff_section_data structure.  */
642
  coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
643
 
644
  return sec;
645
}
646
 
647
/* This structure contains the code that goes into the .text section
648
   in order to perform a jump into the DLL lookup table.  The entries
649
   in the table are index by the magic number used to represent the
650
   machine type in the PE file.  The contents of the data[] arrays in
651
   these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
652
   The SIZE field says how many bytes in the DATA array are actually
653
   used.  The OFFSET field says where in the data array the address
654
   of the .idata$5 section should be placed.  */
655
#define MAX_TEXT_SECTION_SIZE 32
656
 
657
typedef struct
658
{
659
  unsigned short magic;
660
  unsigned char  data[MAX_TEXT_SECTION_SIZE];
661
  unsigned int   size;
662
  unsigned int   offset;
663
}
664
jump_table;
665
 
666
static jump_table jtab[] =
667
{
668
#ifdef I386MAGIC
669
  { I386MAGIC,
670
    { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
671
    8, 2
672
  },
673
#endif
674
 
675
#ifdef AMD64MAGIC
676
  { AMD64MAGIC,
677
    { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
678
    8, 2
679
  },
680
#endif
681
 
682
#ifdef  MC68MAGIC
683
  { MC68MAGIC,
684
    { /* XXX fill me in */ },
685
    0, 0
686
  },
687
#endif
688
 
689
#ifdef  MIPS_ARCH_MAGIC_WINCE
690
  { MIPS_ARCH_MAGIC_WINCE,
691
    { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
692
      0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
693
    16, 0
694
  },
695
#endif
696
 
697
#ifdef  SH_ARCH_MAGIC_WINCE
698
  { SH_ARCH_MAGIC_WINCE,
699
    { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
700
      0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
701
    12, 8
702
  },
703
#endif
704
 
705
#ifdef  ARMPEMAGIC
706
  { ARMPEMAGIC,
707
    { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
708
      0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
709
    12, 8
710
  },
711
#endif
712
 
713
#ifdef  THUMBPEMAGIC
714
  { THUMBPEMAGIC,
715
    { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
716
      0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
717
    16, 12
718
  },
719
#endif
720
  { 0, { 0 }, 0, 0 }
721
};
722
 
723
#ifndef NUM_ENTRIES
724
#define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
725
#endif
726
 
727
/* Build a full BFD from the information supplied in a ILF object.  */
728
 
729
static bfd_boolean
730
pe_ILF_build_a_bfd (bfd *           abfd,
731
		    unsigned int    magic,
732
		    char *          symbol_name,
733
		    char *          source_dll,
734
		    unsigned int    ordinal,
735
		    unsigned int    types)
736
{
737
  bfd_byte *               ptr;
738
  pe_ILF_vars              vars;
739
  struct internal_filehdr  internal_f;
740
  unsigned int             import_type;
741
  unsigned int             import_name_type;
742
  asection_ptr             id4, id5, id6 = NULL, text = NULL;
743
  coff_symbol_type **      imp_sym;
744
  unsigned int             imp_index;
745
 
746
  /* Decode and verify the types field of the ILF structure.  */
747
  import_type = types & 0x3;
748
  import_name_type = (types & 0x1c) >> 2;
749
 
750
  switch (import_type)
751
    {
752
    case IMPORT_CODE:
753
    case IMPORT_DATA:
754
      break;
755
 
756
    case IMPORT_CONST:
757
      /* XXX code yet to be written.  */
758
      _bfd_error_handler (_("%B: Unhandled import type; %x"),
759
			  abfd, import_type);
760
      return FALSE;
761
 
762
    default:
763
      _bfd_error_handler (_("%B: Unrecognised import type; %x"),
764
			  abfd, import_type);
765
      return FALSE;
766
    }
767
 
768
  switch (import_name_type)
769
    {
770
    case IMPORT_ORDINAL:
771
    case IMPORT_NAME:
772
    case IMPORT_NAME_NOPREFIX:
773
    case IMPORT_NAME_UNDECORATE:
774
      break;
775
 
776
    default:
777
      _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
778
			  abfd, import_name_type);
779
      return FALSE;
780
    }
781
 
782
  /* Initialise local variables.
783
 
784
     Note these are kept in a structure rather than being
785
     declared as statics since bfd frowns on global variables.
786
 
787
     We are going to construct the contents of the BFD in memory,
788
     so allocate all the space that we will need right now.  */
789
  vars.bim
790
    = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
791
  if (vars.bim == NULL)
792
    return FALSE;
793
 
794
  ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
795
  vars.bim->buffer = ptr;
796
  vars.bim->size   = ILF_DATA_SIZE;
797
  if (ptr == NULL)
798
    goto error_return;
799
 
800
  /* Initialise the pointers to regions of the memory and the
801
     other contents of the pe_ILF_vars structure as well.  */
802
  vars.sym_cache = (coff_symbol_type *) ptr;
803
  vars.sym_ptr   = (coff_symbol_type *) ptr;
804
  vars.sym_index = 0;
805
  ptr += SIZEOF_ILF_SYMS;
806
 
807
  vars.sym_table = (unsigned int *) ptr;
808
  vars.table_ptr = (unsigned int *) ptr;
809
  ptr += SIZEOF_ILF_SYM_TABLE;
810
 
811
  vars.native_syms = (combined_entry_type *) ptr;
812
  vars.native_ptr  = (combined_entry_type *) ptr;
813
  ptr += SIZEOF_ILF_NATIVE_SYMS;
814
 
815
  vars.sym_ptr_table = (coff_symbol_type **) ptr;
816
  vars.sym_ptr_ptr   = (coff_symbol_type **) ptr;
817
  ptr += SIZEOF_ILF_SYM_PTR_TABLE;
818
 
819
  vars.esym_table = (SYMENT *) ptr;
820
  vars.esym_ptr   = (SYMENT *) ptr;
821
  ptr += SIZEOF_ILF_EXT_SYMS;
822
 
823
  vars.reltab   = (arelent *) ptr;
824
  vars.relcount = 0;
825
  ptr += SIZEOF_ILF_RELOCS;
826
 
827
  vars.int_reltab  = (struct internal_reloc *) ptr;
828
  ptr += SIZEOF_ILF_INT_RELOCS;
829
 
830
  vars.string_table = (char *) ptr;
831
  vars.string_ptr   = (char *) ptr + STRING_SIZE_SIZE;
832
  ptr += SIZEOF_ILF_STRINGS;
833
  vars.end_string_ptr = (char *) ptr;
834
 
835
  /* The remaining space in bim->buffer is used
836
     by the pe_ILF_make_a_section() function.  */
837
  vars.data = ptr;
838
  vars.abfd = abfd;
839
  vars.sec_index = 0;
840
  vars.magic = magic;
841
 
842
  /* Create the initial .idata$ sections:
843
     [.idata$2:  Import Directory Table -- not needed]
844
     .idata$4:  Import Lookup Table
845
     .idata$5:  Import Address Table
846
 
847
     Note we do not create a .idata$3 section as this is
848
     created for us by the linker script.  */
849
  id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
850
  id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
851
  if (id4 == NULL || id5 == NULL)
852
    goto error_return;
853
 
854
  /* Fill in the contents of these sections.  */
855
  if (import_name_type == IMPORT_ORDINAL)
856
    {
857
      if (ordinal == 0)
858
	/* XXX - treat as IMPORT_NAME ??? */
859
	abort ();
860
 
861
#ifdef COFF_WITH_pex64
862
      ((unsigned int *) id4->contents)[0] = ordinal;
863
      ((unsigned int *) id4->contents)[1] = 0x80000000;
864
      ((unsigned int *) id5->contents)[0] = ordinal;
865
      ((unsigned int *) id5->contents)[1] = 0x80000000;
866
#else
867
      * (unsigned int *) id4->contents = ordinal | 0x80000000;
868
      * (unsigned int *) id5->contents = ordinal | 0x80000000;
869
#endif
870
    }
871
  else
872
    {
873
      char * symbol;
874
      unsigned int len;
875
 
876
      /* Create .idata$6 - the Hint Name Table.  */
877
      id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
878
      if (id6 == NULL)
879
	goto error_return;
880
 
881
      /* If necessary, trim the import symbol name.  */
882
      symbol = symbol_name;
883
 
884
      /* As used by MS compiler, '_', '@', and '?' are alternative
885
	 forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
886
	 '@' used for fastcall (in C),  '_' everywhere else.  Only one
887
	 of these is used for a symbol.  We strip this leading char for
888
	 IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
889
	 PE COFF 6.0 spec (section 8.3, Import Name Type).  */
890
 
891
      if (import_name_type != IMPORT_NAME)
892
	{
893
	  char c = symbol[0];
894
 
895
	  /* Check that we don't remove for targets with empty
896
	     USER_LABEL_PREFIX the leading underscore.  */
897
	  if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
898
	      || c == '@' || c == '?')
899
	    symbol++;
900
	}
901
 
902
      len = strlen (symbol);
903
      if (import_name_type == IMPORT_NAME_UNDECORATE)
904
	{
905
	  /* Truncate at the first '@'.  */
906
	  char *at = strchr (symbol, '@');
907
 
908
	  if (at != NULL)
909
	    len = at - symbol;
910
	}
911
 
912
      id6->contents[0] = ordinal & 0xff;
913
      id6->contents[1] = ordinal >> 8;
914
 
915
      memcpy ((char *) id6->contents + 2, symbol, len);
916
      id6->contents[len + 2] = '\0';
917
    }
918
 
919
  if (import_name_type != IMPORT_ORDINAL)
920
    {
921
      pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
922
      pe_ILF_save_relocs (&vars, id4);
923
 
924
      pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
925
      pe_ILF_save_relocs (&vars, id5);
926
    }
927
 
928
  /* Create extra sections depending upon the type of import we are dealing with.  */
929
  switch (import_type)
930
    {
931
      int i;
932
 
933
    case IMPORT_CODE:
934
      /* Create a .text section.
935
	 First we need to look up its contents in the jump table.  */
936
      for (i = NUM_ENTRIES (jtab); i--;)
937
	{
938
	  if (jtab[i].size == 0)
939
	    continue;
940
	  if (jtab[i].magic == magic)
941
	    break;
942
	}
943
      /* If we did not find a matching entry something is wrong.  */
944
      if (i < 0)
945
	abort ();
946
 
947
      /* Create the .text section.  */
948
      text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
949
      if (text == NULL)
950
	goto error_return;
951
 
952
      /* Copy in the jump code.  */
953
      memcpy (text->contents, jtab[i].data, jtab[i].size);
954
 
955
      /* Create an import symbol.  */
956
      pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
957
      imp_sym   = vars.sym_ptr_ptr - 1;
958
      imp_index = vars.sym_index - 1;
959
 
960
      /* Create a reloc for the data in the text section.  */
961
#ifdef MIPS_ARCH_MAGIC_WINCE
962
      if (magic == MIPS_ARCH_MAGIC_WINCE)
963
	{
964
	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
965
				      (struct bfd_symbol **) imp_sym,
966
				      imp_index);
967
	  pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
968
	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
969
				      (struct bfd_symbol **) imp_sym,
970
				      imp_index);
971
	}
972
      else
973
#endif
974
	pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
975
				    BFD_RELOC_32, (asymbol **) imp_sym,
976
				    imp_index);
977
 
978
      pe_ILF_save_relocs (& vars, text);
979
      break;
980
 
981
    case IMPORT_DATA:
982
      break;
983
 
984
    default:
985
      /* XXX code not yet written.  */
986
      abort ();
987
    }
988
 
989
  /* Initialise the bfd.  */
990
  memset (& internal_f, 0, sizeof (internal_f));
991
 
992
  internal_f.f_magic  = magic;
993
  internal_f.f_symptr = 0;
994
  internal_f.f_nsyms  = 0;
995
  internal_f.f_flags  = F_AR32WR | F_LNNO; /* XXX is this correct ?  */
996
 
997
  if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
998
      || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
999
    goto error_return;
1000
 
1001
  if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
1002
    goto error_return;
1003
 
1004
  coff_data (abfd)->pe = 1;
1005
#ifdef THUMBPEMAGIC
1006
  if (vars.magic == THUMBPEMAGIC)
1007
    /* Stop some linker warnings about thumb code not supporting interworking.  */
1008
    coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
1009
#endif
1010
 
1011
  /* Switch from file contents to memory contents.  */
1012
  bfd_cache_close (abfd);
1013
 
1014
  abfd->iostream = (void *) vars.bim;
1015
  abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
1016
  abfd->iovec = &_bfd_memory_iovec;
1017
  abfd->where = 0;
1018
  abfd->origin = 0;
1019
  obj_sym_filepos (abfd) = 0;
1020
 
1021
  /* Now create a symbol describing the imported value.  */
1022
  switch (import_type)
1023
    {
1024
    case IMPORT_CODE:
1025
      pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
1026
			    BSF_NOT_AT_END | BSF_FUNCTION);
1027
 
1028
      /* Create an import symbol for the DLL, without the
1029
       .dll suffix.  */
1030
      ptr = (bfd_byte *) strrchr (source_dll, '.');
1031
      if (ptr)
1032
	* ptr = 0;
1033
      pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
1034
      if (ptr)
1035
	* ptr = '.';
1036
      break;
1037
 
1038
    case IMPORT_DATA:
1039
      /* Nothing to do here.  */
1040
      break;
1041
 
1042
    default:
1043
      /* XXX code not yet written.  */
1044
      abort ();
1045
    }
1046
 
1047
  /* Point the bfd at the symbol table.  */
1048
  obj_symbols (abfd) = vars.sym_cache;
1049
  bfd_get_symcount (abfd) = vars.sym_index;
1050
 
1051
  obj_raw_syments (abfd) = vars.native_syms;
1052
  obj_raw_syment_count (abfd) = vars.sym_index;
1053
 
1054
  obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1055
  obj_coff_keep_syms (abfd) = TRUE;
1056
 
1057
  obj_convert (abfd) = vars.sym_table;
1058
  obj_conv_table_size (abfd) = vars.sym_index;
1059
 
1060
  obj_coff_strings (abfd) = vars.string_table;
1061
  obj_coff_keep_strings (abfd) = TRUE;
1062
 
1063
  abfd->flags |= HAS_SYMS;
1064
 
1065
  return TRUE;
1066
 
1067
 error_return:
1068
  if (vars.bim->buffer != NULL)
1069
    free (vars.bim->buffer);
1070
  free (vars.bim);
1071
  return FALSE;
1072
}
1073
 
1074
/* We have detected a Image Library Format archive element.
1075
   Decode the element and return the appropriate target.  */
1076
 
1077
static const bfd_target *
1078
pe_ILF_object_p (bfd * abfd)
1079
{
1080
  bfd_byte        buffer[16];
1081
  bfd_byte *      ptr;
1082
  char *          symbol_name;
1083
  char *          source_dll;
1084
  unsigned int    machine;
1085
  bfd_size_type   size;
1086
  unsigned int    ordinal;
1087
  unsigned int    types;
1088
  unsigned int    magic;
1089
 
1090
  /* Upon entry the first four buyes of the ILF header have
1091
      already been read.  Now read the rest of the header.  */
1092
  if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16)
1093
    return NULL;
1094
 
1095
  ptr = buffer;
1096
 
1097
  /*  We do not bother to check the version number.
1098
      version = H_GET_16 (abfd, ptr);  */
1099
  ptr += 2;
1100
 
1101
  machine = H_GET_16 (abfd, ptr);
1102
  ptr += 2;
1103
 
1104
  /* Check that the machine type is recognised.  */
1105
  magic = 0;
1106
 
1107
  switch (machine)
1108
    {
1109
    case IMAGE_FILE_MACHINE_UNKNOWN:
1110
    case IMAGE_FILE_MACHINE_ALPHA:
1111
    case IMAGE_FILE_MACHINE_ALPHA64:
1112
    case IMAGE_FILE_MACHINE_IA64:
1113
      break;
1114
 
1115
    case IMAGE_FILE_MACHINE_I386:
1116
#ifdef I386MAGIC
1117
      magic = I386MAGIC;
1118
#endif
1119
      break;
1120
 
1121
    case IMAGE_FILE_MACHINE_AMD64:
1122
#ifdef AMD64MAGIC
1123
      magic = AMD64MAGIC;
1124
#endif
1125
      break;
1126
 
1127
    case IMAGE_FILE_MACHINE_M68K:
1128
#ifdef MC68AGIC
1129
      magic = MC68MAGIC;
1130
#endif
1131
      break;
1132
 
1133
    case IMAGE_FILE_MACHINE_R3000:
1134
    case IMAGE_FILE_MACHINE_R4000:
1135
    case IMAGE_FILE_MACHINE_R10000:
1136
 
1137
    case IMAGE_FILE_MACHINE_MIPS16:
1138
    case IMAGE_FILE_MACHINE_MIPSFPU:
1139
    case IMAGE_FILE_MACHINE_MIPSFPU16:
1140
#ifdef MIPS_ARCH_MAGIC_WINCE
1141
      magic = MIPS_ARCH_MAGIC_WINCE;
1142
#endif
1143
      break;
1144
 
1145
    case IMAGE_FILE_MACHINE_SH3:
1146
    case IMAGE_FILE_MACHINE_SH4:
1147
#ifdef SH_ARCH_MAGIC_WINCE
1148
      magic = SH_ARCH_MAGIC_WINCE;
1149
#endif
1150
      break;
1151
 
1152
    case IMAGE_FILE_MACHINE_ARM:
1153
#ifdef ARMPEMAGIC
1154
      magic = ARMPEMAGIC;
1155
#endif
1156
      break;
1157
 
1158
    case IMAGE_FILE_MACHINE_THUMB:
1159
#ifdef THUMBPEMAGIC
1160
      {
1161
	extern const bfd_target TARGET_LITTLE_SYM;
1162
 
1163
	if (abfd->xvec == & TARGET_LITTLE_SYM)
1164
	  magic = THUMBPEMAGIC;
1165
      }
1166
#endif
1167
      break;
1168
 
1169
    case IMAGE_FILE_MACHINE_POWERPC:
1170
      /* We no longer support PowerPC.  */
1171
    default:
1172
      _bfd_error_handler
1173
	(_("%B: Unrecognised machine type (0x%x)"
1174
	   " in Import Library Format archive"),
1175
	 abfd, machine);
1176
      bfd_set_error (bfd_error_malformed_archive);
1177
 
1178
      return NULL;
1179
      break;
1180
    }
1181
 
1182
  if (magic == 0)
1183
    {
1184
      _bfd_error_handler
1185
	(_("%B: Recognised but unhandled machine type (0x%x)"
1186
	   " in Import Library Format archive"),
1187
	 abfd, machine);
1188
      bfd_set_error (bfd_error_wrong_format);
1189
 
1190
      return NULL;
1191
    }
1192
 
1193
  /* We do not bother to check the date.
1194
     date = H_GET_32 (abfd, ptr);  */
1195
  ptr += 4;
1196
 
1197
  size = H_GET_32 (abfd, ptr);
1198
  ptr += 4;
1199
 
1200
  if (size == 0)
1201
    {
1202
      _bfd_error_handler
1203
	(_("%B: size field is zero in Import Library Format header"), abfd);
1204
      bfd_set_error (bfd_error_malformed_archive);
1205
 
1206
      return NULL;
1207
    }
1208
 
1209
  ordinal = H_GET_16 (abfd, ptr);
1210
  ptr += 2;
1211
 
1212
  types = H_GET_16 (abfd, ptr);
1213
  /* ptr += 2; */
1214
 
1215
  /* Now read in the two strings that follow.  */
1216
  ptr = (bfd_byte *) bfd_alloc (abfd, size);
1217
  if (ptr == NULL)
1218
    return NULL;
1219
 
1220
  if (bfd_bread (ptr, size, abfd) != size)
1221
    {
1222
      bfd_release (abfd, ptr);
1223
      return NULL;
1224
    }
1225
 
1226
  symbol_name = (char *) ptr;
1227
  source_dll  = symbol_name + strlen (symbol_name) + 1;
1228
 
1229
  /* Verify that the strings are null terminated.  */
1230
  if (ptr[size - 1] != 0
1231
      || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
1232
    {
1233
      _bfd_error_handler
1234
	(_("%B: string not null terminated in ILF object file."), abfd);
1235
      bfd_set_error (bfd_error_malformed_archive);
1236
      bfd_release (abfd, ptr);
1237
      return NULL;
1238
    }
1239
 
1240
  /* Now construct the bfd.  */
1241
  if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
1242
			    source_dll, ordinal, types))
1243
    {
1244
      bfd_release (abfd, ptr);
1245
      return NULL;
1246
    }
1247
 
1248
  return abfd->xvec;
1249
}
1250
 
1251
static const bfd_target *
1252
pe_bfd_object_p (bfd * abfd)
1253
{
1254
  bfd_byte buffer[4];
1255
  struct external_PEI_DOS_hdr dos_hdr;
1256
  struct external_PEI_IMAGE_hdr image_hdr;
1257
  struct internal_filehdr internal_f;
1258
  struct internal_aouthdr internal_a;
1259
  file_ptr opt_hdr_size;
1260
  file_ptr offset;
1261
 
1262
  /* Detect if this a Microsoft Import Library Format element.  */
1263
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1264
      || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4)
1265
    {
1266
      if (bfd_get_error () != bfd_error_system_call)
1267
	bfd_set_error (bfd_error_wrong_format);
1268
      return NULL;
1269
    }
1270
 
1271
  if (H_GET_32 (abfd, buffer) == 0xffff0000)
1272
    return pe_ILF_object_p (abfd);
1273
 
1274
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1275
      || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
1276
	 != sizeof (dos_hdr))
1277
    {
1278
      if (bfd_get_error () != bfd_error_system_call)
1279
	bfd_set_error (bfd_error_wrong_format);
1280
      return NULL;
1281
    }
1282
 
1283
  /* There are really two magic numbers involved; the magic number
1284
     that says this is a NT executable (PEI) and the magic number that
1285
     determines the architecture.  The former is DOSMAGIC, stored in
1286
     the e_magic field.  The latter is stored in the f_magic field.
1287
     If the NT magic number isn't valid, the architecture magic number
1288
     could be mimicked by some other field (specifically, the number
1289
     of relocs in section 3).  Since this routine can only be called
1290
     correctly for a PEI file, check the e_magic number here, and, if
1291
     it doesn't match, clobber the f_magic number so that we don't get
1292
     a false match.  */
1293
  if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
1294
    {
1295
      bfd_set_error (bfd_error_wrong_format);
1296
      return NULL;
1297
    }
1298
 
1299
  offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
1300
  if (bfd_seek (abfd, offset, SEEK_SET) != 0
1301
      || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
1302
	  != sizeof (image_hdr)))
1303
    {
1304
      if (bfd_get_error () != bfd_error_system_call)
1305
	bfd_set_error (bfd_error_wrong_format);
1306
      return NULL;
1307
    }
1308
 
1309
  if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
1310
    {
1311
      bfd_set_error (bfd_error_wrong_format);
1312
      return NULL;
1313
    }
1314
 
1315
  /* Swap file header, so that we get the location for calling
1316
     real_object_p.  */
1317
  bfd_coff_swap_filehdr_in (abfd, (PTR)&image_hdr, &internal_f);
1318
 
1319
  if (! bfd_coff_bad_format_hook (abfd, &internal_f)
1320
      || internal_f.f_opthdr > bfd_coff_aoutsz (abfd))
1321
    {
1322
      bfd_set_error (bfd_error_wrong_format);
1323
      return NULL;
1324
    }
1325
 
1326
  /* Read the optional header, which has variable size.  */
1327
  opt_hdr_size = internal_f.f_opthdr;
1328
 
1329
  if (opt_hdr_size != 0)
1330
    {
1331
      PTR opthdr;
1332
 
1333
      opthdr = bfd_alloc (abfd, opt_hdr_size);
1334
      if (opthdr == NULL)
1335
	return NULL;
1336
      if (bfd_bread (opthdr, opt_hdr_size, abfd)
1337
	  != (bfd_size_type) opt_hdr_size)
1338
	return NULL;
1339
 
1340
      bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) & internal_a);
1341
    }
1342
 
1343
  return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
1344
                            (opt_hdr_size != 0
1345
                             ? &internal_a
1346
                             : (struct internal_aouthdr *) NULL));
1347
}
1348
 
1349
#define coff_object_p pe_bfd_object_p
1350
#endif /* COFF_IMAGE_WITH_PE */