OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [peicode.h] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Support for the generic parts of PE/PEI, for BFD.
2
   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
   2005, 2006, 2007, 2008  Free Software Foundation, Inc.
4
   Written by Cygnus Solutions.
5
 
6
   This file is part of BFD, the Binary File Descriptor library.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
 
24
/* Most of this hacked by  Steve Chamberlain,
25
                        sac@cygnus.com
26
 
27
   PE/PEI rearrangement (and code added): Donn Terry
28
                                       Softway Systems, Inc.  */
29
 
30
/* Hey look, some documentation [and in a place you expect to find it]!
31
 
32
   The main reference for the pei format is "Microsoft Portable Executable
33
   and Common Object File Format Specification 4.1".  Get it if you need to
34
   do some serious hacking on this code.
35
 
36
   Another reference:
37
   "Peering Inside the PE: A Tour of the Win32 Portable Executable
38
   File Format", MSJ 1994, Volume 9.
39
 
40
   The *sole* difference between the pe format and the pei format is that the
41
   latter has an MSDOS 2.0 .exe header on the front that prints the message
42
   "This app must be run under Windows." (or some such).
43
   (FIXME: Whether that statement is *really* true or not is unknown.
44
   Are there more subtle differences between pe and pei formats?
45
   For now assume there aren't.  If you find one, then for God sakes
46
   document it here!)
47
 
48
   The Microsoft docs use the word "image" instead of "executable" because
49
   the former can also refer to a DLL (shared library).  Confusion can arise
50
   because the `i' in `pei' also refers to "image".  The `pe' format can
51
   also create images (i.e. executables), it's just that to run on a win32
52
   system you need to use the pei format.
53
 
54
   FIXME: Please add more docs here so the next poor fool that has to hack
55
   on this code has a chance of getting something accomplished without
56
   wasting too much time.  */
57
 
58
#include "libpei.h"
59
 
60
static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
61
#ifndef coff_bfd_print_private_bfd_data
62
     NULL;
63
#else
64
     coff_bfd_print_private_bfd_data;
65
#undef coff_bfd_print_private_bfd_data
66
#endif
67
 
68
static bfd_boolean                      pe_print_private_bfd_data (bfd *, void *);
69
#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
70
 
71
static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
72
#ifndef coff_bfd_copy_private_bfd_data
73
     NULL;
74
#else
75
     coff_bfd_copy_private_bfd_data;
76
#undef coff_bfd_copy_private_bfd_data
77
#endif
78
 
79
static bfd_boolean                     pe_bfd_copy_private_bfd_data (bfd *, bfd *);
80
#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
81
 
82
#define coff_mkobject      pe_mkobject
83
#define coff_mkobject_hook pe_mkobject_hook
84
 
85
#ifdef COFF_IMAGE_WITH_PE
86
/* This structure contains static variables used by the ILF code.  */
87
typedef asection * asection_ptr;
88
 
89
typedef struct
90
{
91
  bfd *                 abfd;
92
  bfd_byte *            data;
93
  struct bfd_in_memory * bim;
94
  unsigned short        magic;
95
 
96
  arelent *             reltab;
97
  unsigned int          relcount;
98
 
99
  coff_symbol_type *    sym_cache;
100
  coff_symbol_type *    sym_ptr;
101
  unsigned int          sym_index;
102
 
103
  unsigned int *        sym_table;
104
  unsigned int *        table_ptr;
105
 
106
  combined_entry_type * native_syms;
107
  combined_entry_type * native_ptr;
108
 
109
  coff_symbol_type **   sym_ptr_table;
110
  coff_symbol_type **   sym_ptr_ptr;
111
 
112
  unsigned int          sec_index;
113
 
114
  char *                string_table;
115
  char *                string_ptr;
116
  char *                end_string_ptr;
117
 
118
  SYMENT *              esym_table;
119
  SYMENT *              esym_ptr;
120
 
121
  struct internal_reloc * int_reltab;
122
}
123
pe_ILF_vars;
124
#endif /* COFF_IMAGE_WITH_PE */
125
 
126
#ifndef NO_COFF_RELOCS
127
static void
128
coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
129
{
130
  RELOC *reloc_src = (RELOC *) src;
131
  struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
132
 
133
  reloc_dst->r_vaddr  = H_GET_32 (abfd, reloc_src->r_vaddr);
134
  reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
135
  reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
136
#ifdef SWAP_IN_RELOC_OFFSET
137
  reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
138
#endif
139
}
140
 
141
static unsigned int
142
coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
143
{
144
  struct internal_reloc *reloc_src = (struct internal_reloc *) src;
145
  struct external_reloc *reloc_dst = (struct external_reloc *) dst;
146
 
147
  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
148
  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
149
  H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
150
 
151
#ifdef SWAP_OUT_RELOC_OFFSET 
152
  SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
153
#endif
154
#ifdef SWAP_OUT_RELOC_EXTRA
155
  SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
156
#endif
157
  return RELSZ;
158
}
159
#endif /* not NO_COFF_RELOCS */
160
 
161
static void
162
coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
163
{
164
  FILHDR *filehdr_src = (FILHDR *) src;
165
  struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
166
 
167
  filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
168
  filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
169
  filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
170
  filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
171
  filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
172
  filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr);
173
 
174
  /* Other people's tools sometimes generate headers with an nsyms but
175
     a zero symptr.  */
176
  if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
177
    {
178
      filehdr_dst->f_nsyms = 0;
179
      filehdr_dst->f_flags |= F_LSYMS;
180
    }
181
 
182
  filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr);
183
}
184
 
185
#ifdef COFF_IMAGE_WITH_PE
186
# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
187
#elif defined COFF_WITH_pex64
188
# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
189
#elif defined COFF_WITH_pep
190
# define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
191
#else
192
# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
193
#endif
194
 
195
static void
196
coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
197
{
198
  SCNHDR *scnhdr_ext = (SCNHDR *) ext;
199
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
200
 
201
  memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
202
 
203
  scnhdr_int->s_vaddr   = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
204
  scnhdr_int->s_paddr   = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
205
  scnhdr_int->s_size    = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
206
  scnhdr_int->s_scnptr  = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
207
  scnhdr_int->s_relptr  = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
208
  scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
209
  scnhdr_int->s_flags   = H_GET_32 (abfd, scnhdr_ext->s_flags);
210
 
211
  /* MS handles overflow of line numbers by carrying into the reloc
212
     field (it appears).  Since it's supposed to be zero for PE
213
     *IMAGE* format, that's safe.  This is still a bit iffy.  */
214
#ifdef COFF_IMAGE_WITH_PE
215
  scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
216
                         + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
217
  scnhdr_int->s_nreloc = 0;
218
#else
219
  scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
220
  scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
221
#endif
222
 
223
  if (scnhdr_int->s_vaddr != 0)
224
    {
225
      scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
226
      /* Do not cut upper 32-bits for 64-bit vma.  */
227
#ifndef COFF_WITH_pex64
228
      scnhdr_int->s_vaddr &= 0xffffffff;
229
#endif
230
    }
231
 
232
#ifndef COFF_NO_HACK_SCNHDR_SIZE
233
  /* If this section holds uninitialized data and is from an object file
234
     or from an executable image that has not initialized the field,
235
     or if the image is an executable file and the physical size is padded,
236
     use the virtual size (stored in s_paddr) instead.  */
237
  if (scnhdr_int->s_paddr > 0
238
      && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
239
           && (! bfd_pe_executable_p (abfd) || scnhdr_int->s_size == 0))
240
          || (bfd_pe_executable_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
241
  /* This code used to set scnhdr_int->s_paddr to 0.  However,
242
     coff_set_alignment_hook stores s_paddr in virt_size, which
243
     only works if it correctly holds the virtual size of the
244
     section.  */
245
    scnhdr_int->s_size = scnhdr_int->s_paddr;
246
#endif
247
}
248
 
249
static bfd_boolean
250
pe_mkobject (bfd * abfd)
251
{
252
  pe_data_type *pe;
253
  bfd_size_type amt = sizeof (pe_data_type);
254
 
255
  abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
256
 
257
  if (abfd->tdata.pe_obj_data == 0)
258
    return FALSE;
259
 
260
  pe = pe_data (abfd);
261
 
262
  pe->coff.pe = 1;
263
 
264
  /* in_reloc_p is architecture dependent.  */
265
  pe->in_reloc_p = in_reloc_p;
266
 
267
#ifdef PEI_FORCE_MINIMUM_ALIGNMENT
268
  pe->force_minimum_alignment = 1;
269
#endif
270
#ifdef PEI_TARGET_SUBSYSTEM
271
  pe->target_subsystem = PEI_TARGET_SUBSYSTEM;
272
#endif
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 (* vars.bim)                       \
433
    + SIZEOF_ILF_SYMS                           \
434
    + SIZEOF_ILF_SYM_TABLE                      \
435
    + SIZEOF_ILF_NATIVE_SYMS                    \
436
    + SIZEOF_ILF_SYM_PTR_TABLE                  \
437
    + SIZEOF_ILF_EXT_SYMS                       \
438
    + SIZEOF_ILF_RELOCS                         \
439
    + SIZEOF_ILF_INT_RELOCS                     \
440
    + SIZEOF_ILF_STRINGS                        \
441
    + SIZEOF_IDATA2                             \
442
    + SIZEOF_IDATA4                             \
443
    + SIZEOF_IDATA5                             \
444
    + SIZEOF_IDATA6                             \
445
    + SIZEOF_IDATA7                             \
446
    + SIZEOF_ILF_SECTIONS                       \
447
    + MAX_TEXT_SECTION_SIZE
448
 
449
/* Create an empty relocation against the given symbol.  */
450
 
451
static void
452
pe_ILF_make_a_symbol_reloc (pe_ILF_vars *               vars,
453
                            bfd_vma                     address,
454
                            bfd_reloc_code_real_type    reloc,
455
                            struct bfd_symbol **        sym,
456
                            unsigned int                sym_index)
457
{
458
  arelent * entry;
459
  struct internal_reloc * internal;
460
 
461
  entry = vars->reltab + vars->relcount;
462
  internal = vars->int_reltab + vars->relcount;
463
 
464
  entry->address     = address;
465
  entry->addend      = 0;
466
  entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
467
  entry->sym_ptr_ptr = sym;
468
 
469
  internal->r_vaddr  = address;
470
  internal->r_symndx = sym_index;
471
  internal->r_type   = entry->howto->type;
472
 
473
  vars->relcount ++;
474
 
475
  BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
476
}
477
 
478
/* Create an empty relocation against the given section.  */
479
 
480
static void
481
pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
482
                     bfd_vma                   address,
483
                     bfd_reloc_code_real_type  reloc,
484
                     asection_ptr              sec)
485
{
486
  pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
487
                              coff_section_data (vars->abfd, sec)->i);
488
}
489
 
490
/* Move the queued relocs into the given section.  */
491
 
492
static void
493
pe_ILF_save_relocs (pe_ILF_vars * vars,
494
                    asection_ptr  sec)
495
{
496
  /* Make sure that there is somewhere to store the internal relocs.  */
497
  if (coff_section_data (vars->abfd, sec) == NULL)
498
    /* We should probably return an error indication here.  */
499
    abort ();
500
 
501
  coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
502
  coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
503
 
504
  sec->relocation  = vars->reltab;
505
  sec->reloc_count = vars->relcount;
506
  sec->flags      |= SEC_RELOC;
507
 
508
  vars->reltab     += vars->relcount;
509
  vars->int_reltab += vars->relcount;
510
  vars->relcount   = 0;
511
 
512
  BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
513
}
514
 
515
/* Create a global symbol and add it to the relevant tables.  */
516
 
517
static void
518
pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
519
                      const char *   prefix,
520
                      const char *   symbol_name,
521
                      asection_ptr   section,
522
                      flagword       extra_flags)
523
{
524
  coff_symbol_type * sym;
525
  combined_entry_type * ent;
526
  SYMENT * esym;
527
  unsigned short sclass;
528
 
529
  if (extra_flags & BSF_LOCAL)
530
    sclass = C_STAT;
531
  else
532
    sclass = C_EXT;
533
 
534
#ifdef THUMBPEMAGIC
535
  if (vars->magic == THUMBPEMAGIC)
536
    {
537
      if (extra_flags & BSF_FUNCTION)
538
        sclass = C_THUMBEXTFUNC;
539
      else if (extra_flags & BSF_LOCAL)
540
        sclass = C_THUMBSTAT;
541
      else
542
        sclass = C_THUMBEXT;
543
    }
544
#endif
545
 
546
  BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
547
 
548
  sym = vars->sym_ptr;
549
  ent = vars->native_ptr;
550
  esym = vars->esym_ptr;
551
 
552
  /* Copy the symbol's name into the string table.  */
553
  sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
554
 
555
  if (section == NULL)
556
    section = (asection_ptr) & bfd_und_section;
557
 
558
  /* Initialise the external symbol.  */
559
  H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
560
            esym->e.e.e_offset);
561
  H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
562
  esym->e_sclass[0] = sclass;
563
 
564
  /* The following initialisations are unnecessary - the memory is
565
     zero initialised.  They are just kept here as reminders.  */
566
 
567
  /* Initialise the internal symbol structure.  */
568
  ent->u.syment.n_sclass          = sclass;
569
  ent->u.syment.n_scnum           = section->target_index;
570
  ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
571
 
572
  sym->symbol.the_bfd = vars->abfd;
573
  sym->symbol.name    = vars->string_ptr;
574
  sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
575
  sym->symbol.section = section;
576
  sym->native         = ent;
577
 
578
  * vars->table_ptr = vars->sym_index;
579
  * vars->sym_ptr_ptr = sym;
580
 
581
  /* Adjust pointers for the next symbol.  */
582
  vars->sym_index ++;
583
  vars->sym_ptr ++;
584
  vars->sym_ptr_ptr ++;
585
  vars->table_ptr ++;
586
  vars->native_ptr ++;
587
  vars->esym_ptr ++;
588
  vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
589
 
590
  BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
591
}
592
 
593
/* Create a section.  */
594
 
595
static asection_ptr
596
pe_ILF_make_a_section (pe_ILF_vars * vars,
597
                       const char *  name,
598
                       unsigned int  size,
599
                       flagword      extra_flags)
600
{
601
  asection_ptr sec;
602
  flagword     flags;
603
 
604
  sec = bfd_make_section_old_way (vars->abfd, name);
605
  if (sec == NULL)
606
    return NULL;
607
 
608
  flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
609
 
610
  bfd_set_section_flags (vars->abfd, sec, flags | extra_flags);
611
 
612
  bfd_set_section_alignment (vars->abfd, sec, 2);
613
 
614
  /* Check that we will not run out of space.  */
615
  BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
616
 
617
  /* Set the section size and contents.  The actual
618
     contents are filled in by our parent.  */
619
  bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size);
620
  sec->contents = vars->data;
621
  sec->target_index = vars->sec_index ++;
622
 
623
  /* Advance data pointer in the vars structure.  */
624
  vars->data += size;
625
 
626
  /* Skip the padding byte if it was not needed.
627
     The logic here is that if the string length is odd,
628
     then the entire string length, including the null byte,
629
     is even and so the extra, padding byte, is not needed.  */
630
  if (size & 1)
631
    vars->data --;
632
 
633
  /* Create a coff_section_tdata structure for our use.  */
634
  sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
635
  vars->data += sizeof (struct coff_section_tdata);
636
 
637
  BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
638
 
639
  /* Create a symbol to refer to this section.  */
640
  pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
641
 
642
  /* Cache the index to the symbol in the coff_section_data structure.  */
643
  coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
644
 
645
  return sec;
646
}
647
 
648
/* This structure contains the code that goes into the .text section
649
   in order to perform a jump into the DLL lookup table.  The entries
650
   in the table are index by the magic number used to represent the
651
   machine type in the PE file.  The contents of the data[] arrays in
652
   these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
653
   The SIZE field says how many bytes in the DATA array are actually
654
   used.  The OFFSET field says where in the data array the address
655
   of the .idata$5 section should be placed.  */
656
#define MAX_TEXT_SECTION_SIZE 32
657
 
658
typedef struct
659
{
660
  unsigned short magic;
661
  unsigned char  data[MAX_TEXT_SECTION_SIZE];
662
  unsigned int   size;
663
  unsigned int   offset;
664
}
665
jump_table;
666
 
667
static jump_table jtab[] =
668
{
669
#ifdef I386MAGIC
670
  { I386MAGIC,
671
    { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
672
    8, 2
673
  },
674
#endif
675
 
676
#ifdef AMD64MAGIC
677
  { AMD64MAGIC,
678
    { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
679
    8, 2
680
  },
681
#endif
682
 
683
#ifdef  MC68MAGIC
684
  { MC68MAGIC,
685
    { /* XXX fill me in */ },
686
    0, 0
687
  },
688
#endif
689
 
690
#ifdef  MIPS_ARCH_MAGIC_WINCE
691
  { MIPS_ARCH_MAGIC_WINCE,
692
    { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
693
      0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
694
    16, 0
695
  },
696
#endif
697
 
698
#ifdef  SH_ARCH_MAGIC_WINCE
699
  { SH_ARCH_MAGIC_WINCE,
700
    { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
701
      0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
702
    12, 8
703
  },
704
#endif
705
 
706
#ifdef  ARMPEMAGIC
707
  { ARMPEMAGIC,
708
    { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
709
      0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
710
    12, 8
711
  },
712
#endif
713
 
714
#ifdef  THUMBPEMAGIC
715
  { THUMBPEMAGIC,
716
    { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
717
      0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
718
    16, 12
719
  },
720
#endif
721
  { 0, { 0 }, 0, 0 }
722
};
723
 
724
#ifndef NUM_ENTRIES
725
#define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
726
#endif
727
 
728
/* Build a full BFD from the information supplied in a ILF object.  */
729
 
730
static bfd_boolean
731
pe_ILF_build_a_bfd (bfd *           abfd,
732
                    unsigned int    magic,
733
                    char *          symbol_name,
734
                    char *          source_dll,
735
                    unsigned int    ordinal,
736
                    unsigned int    types)
737
{
738
  bfd_byte *               ptr;
739
  pe_ILF_vars              vars;
740
  struct internal_filehdr  internal_f;
741
  unsigned int             import_type;
742
  unsigned int             import_name_type;
743
  asection_ptr             id4, id5, id6 = NULL, text = NULL;
744
  coff_symbol_type **      imp_sym;
745
  unsigned int             imp_index;
746
 
747
  /* Decode and verify the types field of the ILF structure.  */
748
  import_type = types & 0x3;
749
  import_name_type = (types & 0x1c) >> 2;
750
 
751
  switch (import_type)
752
    {
753
    case IMPORT_CODE:
754
    case IMPORT_DATA:
755
      break;
756
 
757
    case IMPORT_CONST:
758
      /* XXX code yet to be written.  */
759
      _bfd_error_handler (_("%B: Unhandled import type; %x"),
760
                          abfd, import_type);
761
      return FALSE;
762
 
763
    default:
764
      _bfd_error_handler (_("%B: Unrecognised import type; %x"),
765
                          abfd, import_type);
766
      return FALSE;
767
    }
768
 
769
  switch (import_name_type)
770
    {
771
    case IMPORT_ORDINAL:
772
    case IMPORT_NAME:
773
    case IMPORT_NAME_NOPREFIX:
774
    case IMPORT_NAME_UNDECORATE:
775
      break;
776
 
777
    default:
778
      _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
779
                          abfd, import_name_type);
780
      return FALSE;
781
    }
782
 
783
  /* Initialise local variables.
784
 
785
     Note these are kept in a structure rather than being
786
     declared as statics since bfd frowns on global variables.
787
 
788
     We are going to construct the contents of the BFD in memory,
789
     so allocate all the space that we will need right now.  */
790
  ptr = bfd_zalloc (abfd, (bfd_size_type) ILF_DATA_SIZE);
791
  if (ptr == NULL)
792
    return FALSE;
793
 
794
  /* Create a bfd_in_memory structure.  */
795
  vars.bim = (struct bfd_in_memory *) ptr;
796
  vars.bim->buffer = ptr;
797
  vars.bim->size   = ILF_DATA_SIZE;
798
  ptr += sizeof (* vars.bim);
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$<n> 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
    return FALSE;
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
        return FALSE;
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
          if (c == '_' || c == '@' || c == '?')
895
            symbol++;
896
        }
897
 
898
      len = strlen (symbol);
899
      if (import_name_type == IMPORT_NAME_UNDECORATE)
900
        {
901
          /* Truncate at the first '@'.  */
902
          char *at = strchr (symbol, '@');
903
 
904
          if (at != NULL)
905
            len = at - symbol;
906
        }
907
 
908
      id6->contents[0] = ordinal & 0xff;
909
      id6->contents[1] = ordinal >> 8;
910
 
911
      memcpy ((char *) id6->contents + 2, symbol, len);
912
      id6->contents[len + 2] = '\0';
913
    }
914
 
915
  if (import_name_type != IMPORT_ORDINAL)
916
    {
917
      pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
918
      pe_ILF_save_relocs (&vars, id4);
919
 
920
      pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
921
      pe_ILF_save_relocs (&vars, id5);
922
    }
923
 
924
  /* Create extra sections depending upon the type of import we are dealing with.  */
925
  switch (import_type)
926
    {
927
      int i;
928
 
929
    case IMPORT_CODE:
930
      /* Create a .text section.
931
         First we need to look up its contents in the jump table.  */
932
      for (i = NUM_ENTRIES (jtab); i--;)
933
        {
934
          if (jtab[i].size == 0)
935
            continue;
936
          if (jtab[i].magic == magic)
937
            break;
938
        }
939
      /* If we did not find a matching entry something is wrong.  */
940
      if (i < 0)
941
        abort ();
942
 
943
      /* Create the .text section.  */
944
      text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
945
      if (text == NULL)
946
        return FALSE;
947
 
948
      /* Copy in the jump code.  */
949
      memcpy (text->contents, jtab[i].data, jtab[i].size);
950
 
951
      /* Create an import symbol.  */
952
      pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
953
      imp_sym   = vars.sym_ptr_ptr - 1;
954
      imp_index = vars.sym_index - 1;
955
 
956
      /* Create a reloc for the data in the text section.  */
957
#ifdef MIPS_ARCH_MAGIC_WINCE
958
      if (magic == MIPS_ARCH_MAGIC_WINCE)
959
        {
960
          pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
961
                                      (struct bfd_symbol **) imp_sym,
962
                                      imp_index);
963
          pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
964
          pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
965
                                      (struct bfd_symbol **) imp_sym,
966
                                      imp_index);
967
        }
968
      else
969
#endif
970
        pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
971
                                    BFD_RELOC_32, (asymbol **) imp_sym,
972
                                    imp_index);
973
 
974
      pe_ILF_save_relocs (& vars, text);
975
      break;
976
 
977
    case IMPORT_DATA:
978
      break;
979
 
980
    default:
981
      /* XXX code not yet written.  */
982
      abort ();
983
    }
984
 
985
  /* Initialise the bfd.  */
986
  memset (& internal_f, 0, sizeof (internal_f));
987
 
988
  internal_f.f_magic  = magic;
989
  internal_f.f_symptr = 0;
990
  internal_f.f_nsyms  = 0;
991
  internal_f.f_flags  = F_AR32WR | F_LNNO; /* XXX is this correct ?  */
992
 
993
  if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
994
      || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
995
    return FALSE;
996
 
997
  if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
998
    return FALSE;
999
 
1000
  coff_data (abfd)->pe = 1;
1001
#ifdef THUMBPEMAGIC
1002
  if (vars.magic == THUMBPEMAGIC)
1003
    /* Stop some linker warnings about thumb code not supporting interworking.  */
1004
    coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
1005
#endif
1006
 
1007
  /* Switch from file contents to memory contents.  */
1008
  bfd_cache_close (abfd);
1009
 
1010
  abfd->iostream = (void *) vars.bim;
1011
  abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
1012
  abfd->where = 0;
1013
  obj_sym_filepos (abfd) = 0;
1014
 
1015
  /* Now create a symbol describing the imported value.  */
1016
  switch (import_type)
1017
    {
1018
    case IMPORT_CODE:
1019
      pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
1020
                            BSF_NOT_AT_END | BSF_FUNCTION);
1021
 
1022
      /* Create an import symbol for the DLL, without the
1023
       .dll suffix.  */
1024
      ptr = (bfd_byte *) strrchr (source_dll, '.');
1025
      if (ptr)
1026
        * ptr = 0;
1027
      pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
1028
      if (ptr)
1029
        * ptr = '.';
1030
      break;
1031
 
1032
    case IMPORT_DATA:
1033
      /* Nothing to do here.  */
1034
      break;
1035
 
1036
    default:
1037
      /* XXX code not yet written.  */
1038
      abort ();
1039
    }
1040
 
1041
  /* Point the bfd at the symbol table.  */
1042
  obj_symbols (abfd) = vars.sym_cache;
1043
  bfd_get_symcount (abfd) = vars.sym_index;
1044
 
1045
  obj_raw_syments (abfd) = vars.native_syms;
1046
  obj_raw_syment_count (abfd) = vars.sym_index;
1047
 
1048
  obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1049
  obj_coff_keep_syms (abfd) = TRUE;
1050
 
1051
  obj_convert (abfd) = vars.sym_table;
1052
  obj_conv_table_size (abfd) = vars.sym_index;
1053
 
1054
  obj_coff_strings (abfd) = vars.string_table;
1055
  obj_coff_keep_strings (abfd) = TRUE;
1056
 
1057
  abfd->flags |= HAS_SYMS;
1058
 
1059
  return TRUE;
1060
}
1061
 
1062
/* We have detected a Image Library Format archive element.
1063
   Decode the element and return the appropriate target.  */
1064
 
1065
static const bfd_target *
1066
pe_ILF_object_p (bfd * abfd)
1067
{
1068
  bfd_byte        buffer[16];
1069
  bfd_byte *      ptr;
1070
  char *          symbol_name;
1071
  char *          source_dll;
1072
  unsigned int    machine;
1073
  bfd_size_type   size;
1074
  unsigned int    ordinal;
1075
  unsigned int    types;
1076
  unsigned int    magic;
1077
 
1078
  /* Upon entry the first four buyes of the ILF header have
1079
      already been read.  Now read the rest of the header.  */
1080
  if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16)
1081
    return NULL;
1082
 
1083
  ptr = buffer;
1084
 
1085
  /*  We do not bother to check the version number.
1086
      version = H_GET_16 (abfd, ptr);  */
1087
  ptr += 2;
1088
 
1089
  machine = H_GET_16 (abfd, ptr);
1090
  ptr += 2;
1091
 
1092
  /* Check that the machine type is recognised.  */
1093
  magic = 0;
1094
 
1095
  switch (machine)
1096
    {
1097
    case IMAGE_FILE_MACHINE_UNKNOWN:
1098
    case IMAGE_FILE_MACHINE_ALPHA:
1099
    case IMAGE_FILE_MACHINE_ALPHA64:
1100
    case IMAGE_FILE_MACHINE_IA64:
1101
      break;
1102
 
1103
    case IMAGE_FILE_MACHINE_I386:
1104
#ifdef I386MAGIC
1105
      magic = I386MAGIC;
1106
#endif
1107
      break;
1108
 
1109
    case IMAGE_FILE_MACHINE_AMD64:
1110
#ifdef AMD64MAGIC
1111
      magic = AMD64MAGIC;
1112
#endif
1113
      break;
1114
 
1115
    case IMAGE_FILE_MACHINE_M68K:
1116
#ifdef MC68AGIC
1117
      magic = MC68MAGIC;
1118
#endif
1119
      break;
1120
 
1121
    case IMAGE_FILE_MACHINE_R3000:
1122
    case IMAGE_FILE_MACHINE_R4000:
1123
    case IMAGE_FILE_MACHINE_R10000:
1124
 
1125
    case IMAGE_FILE_MACHINE_MIPS16:
1126
    case IMAGE_FILE_MACHINE_MIPSFPU:
1127
    case IMAGE_FILE_MACHINE_MIPSFPU16:
1128
#ifdef MIPS_ARCH_MAGIC_WINCE
1129
      magic = MIPS_ARCH_MAGIC_WINCE;
1130
#endif
1131
      break;
1132
 
1133
    case IMAGE_FILE_MACHINE_SH3:
1134
    case IMAGE_FILE_MACHINE_SH4:
1135
#ifdef SH_ARCH_MAGIC_WINCE
1136
      magic = SH_ARCH_MAGIC_WINCE;
1137
#endif
1138
      break;
1139
 
1140
    case IMAGE_FILE_MACHINE_ARM:
1141
#ifdef ARMPEMAGIC
1142
      magic = ARMPEMAGIC;
1143
#endif
1144
      break;
1145
 
1146
    case IMAGE_FILE_MACHINE_THUMB:
1147
#ifdef THUMBPEMAGIC
1148
      {
1149
        extern const bfd_target TARGET_LITTLE_SYM;
1150
 
1151
        if (abfd->xvec == & TARGET_LITTLE_SYM)
1152
          magic = THUMBPEMAGIC;
1153
      }
1154
#endif
1155
      break;
1156
 
1157
    case IMAGE_FILE_MACHINE_POWERPC:
1158
      /* We no longer support PowerPC.  */
1159
    default:
1160
      _bfd_error_handler
1161
        (_("%B: Unrecognised machine type (0x%x)"
1162
           " in Import Library Format archive"),
1163
         abfd, machine);
1164
      bfd_set_error (bfd_error_malformed_archive);
1165
 
1166
      return NULL;
1167
      break;
1168
    }
1169
 
1170
  if (magic == 0)
1171
    {
1172
      _bfd_error_handler
1173
        (_("%B: Recognised but unhandled machine type (0x%x)"
1174
           " in Import Library Format archive"),
1175
         abfd, machine);
1176
      bfd_set_error (bfd_error_wrong_format);
1177
 
1178
      return NULL;
1179
    }
1180
 
1181
  /* We do not bother to check the date.
1182
     date = H_GET_32 (abfd, ptr);  */
1183
  ptr += 4;
1184
 
1185
  size = H_GET_32 (abfd, ptr);
1186
  ptr += 4;
1187
 
1188
  if (size == 0)
1189
    {
1190
      _bfd_error_handler
1191
        (_("%B: size field is zero in Import Library Format header"), abfd);
1192
      bfd_set_error (bfd_error_malformed_archive);
1193
 
1194
      return NULL;
1195
    }
1196
 
1197
  ordinal = H_GET_16 (abfd, ptr);
1198
  ptr += 2;
1199
 
1200
  types = H_GET_16 (abfd, ptr);
1201
  /* ptr += 2; */
1202
 
1203
  /* Now read in the two strings that follow.  */
1204
  ptr = bfd_alloc (abfd, size);
1205
  if (ptr == NULL)
1206
    return NULL;
1207
 
1208
  if (bfd_bread (ptr, size, abfd) != size)
1209
    {
1210
      bfd_release (abfd, ptr);
1211
      return NULL;
1212
    }
1213
 
1214
  symbol_name = (char *) ptr;
1215
  source_dll  = symbol_name + strlen (symbol_name) + 1;
1216
 
1217
  /* Verify that the strings are null terminated.  */
1218
  if (ptr[size - 1] != 0
1219
      || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
1220
    {
1221
      _bfd_error_handler
1222
        (_("%B: string not null terminated in ILF object file."), abfd);
1223
      bfd_set_error (bfd_error_malformed_archive);
1224
      bfd_release (abfd, ptr);
1225
      return NULL;
1226
    }
1227
 
1228
  /* Now construct the bfd.  */
1229
  if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
1230
                            source_dll, ordinal, types))
1231
    {
1232
      bfd_release (abfd, ptr);
1233
      return NULL;
1234
    }
1235
 
1236
  return abfd->xvec;
1237
}
1238
 
1239
enum arch_type
1240
{
1241
  arch_type_unknown,
1242
  arch_type_i386,
1243
  arch_type_x86_64
1244
};
1245
 
1246
static enum arch_type
1247
pe_arch (const char *arch)
1248
{
1249
  if (strcmp (arch, "i386") == 0 || strcmp (arch, "ia32") == 0)
1250
    return arch_type_i386;
1251
 
1252
  if (strcmp (arch, "x86_64") == 0 || strcmp (arch, "x86-64") == 0)
1253
    return arch_type_x86_64;
1254
 
1255
  return arch_type_unknown;
1256
}
1257
 
1258
static const bfd_target *
1259
pe_bfd_object_p (bfd * abfd)
1260
{
1261
  bfd_byte buffer[4];
1262
  struct external_PEI_DOS_hdr dos_hdr;
1263
  struct external_PEI_IMAGE_hdr image_hdr;
1264
  file_ptr offset;
1265
  const bfd_target *target;
1266
  struct bfd_preserve preserve;
1267
 
1268
  /* Detect if this a Microsoft Import Library Format element.  */
1269
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1270
      || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4)
1271
    {
1272
      if (bfd_get_error () != bfd_error_system_call)
1273
        bfd_set_error (bfd_error_wrong_format);
1274
      return NULL;
1275
    }
1276
 
1277
  if (H_GET_32 (abfd, buffer) == 0xffff0000)
1278
    return pe_ILF_object_p (abfd);
1279
 
1280
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1281
      || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
1282
         != sizeof (dos_hdr))
1283
    {
1284
      if (bfd_get_error () != bfd_error_system_call)
1285
        bfd_set_error (bfd_error_wrong_format);
1286
      return NULL;
1287
    }
1288
 
1289
  /* There are really two magic numbers involved; the magic number
1290
     that says this is a NT executable (PEI) and the magic number that
1291
     determines the architecture.  The former is DOSMAGIC, stored in
1292
     the e_magic field.  The latter is stored in the f_magic field.
1293
     If the NT magic number isn't valid, the architecture magic number
1294
     could be mimicked by some other field (specifically, the number
1295
     of relocs in section 3).  Since this routine can only be called
1296
     correctly for a PEI file, check the e_magic number here, and, if
1297
     it doesn't match, clobber the f_magic number so that we don't get
1298
     a false match.  */
1299
  if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
1300
    {
1301
      bfd_set_error (bfd_error_wrong_format);
1302
      return NULL;
1303
    }
1304
 
1305
  offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
1306
  if (bfd_seek (abfd, offset, SEEK_SET) != 0
1307
      || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
1308
          != sizeof (image_hdr)))
1309
    {
1310
      if (bfd_get_error () != bfd_error_system_call)
1311
        bfd_set_error (bfd_error_wrong_format);
1312
      return NULL;
1313
    }
1314
 
1315
  if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
1316
    {
1317
      bfd_set_error (bfd_error_wrong_format);
1318
      return NULL;
1319
    }
1320
 
1321
  /* Here is the hack.  coff_object_p wants to read filhsz bytes to
1322
     pick up the COFF header for PE, see "struct external_PEI_filehdr"
1323
     in include/coff/pe.h.  We adjust so that that will work. */
1324
  if (bfd_seek (abfd, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0)
1325
    {
1326
      if (bfd_get_error () != bfd_error_system_call)
1327
        bfd_set_error (bfd_error_wrong_format);
1328
      return NULL;
1329
    }
1330
 
1331
  preserve.marker = NULL;
1332
  if (! bfd_preserve_save (abfd, &preserve))
1333
    return NULL;
1334
 
1335
  target = coff_object_p (abfd);
1336
  if (target)
1337
    {
1338
      pe_data_type *pe = pe_data (abfd);
1339
      struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1340
      bfd_boolean efi = i->Subsystem == IMAGE_SUBSYSTEM_EFI_APPLICATION
1341
                     || i->Subsystem == IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
1342
                     || i->Subsystem == IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
1343
      enum arch_type arch;
1344
      const bfd_target * const *target_ptr;
1345
 
1346
      /* Get the machine.  */
1347
      if (bfd_target_efi_app_p (abfd->xvec))
1348
        arch = pe_arch (bfd_target_efi_app_arch (abfd->xvec));
1349
      else if (bfd_target_efi_bsdrv_p (abfd->xvec))
1350
        arch = pe_arch (bfd_target_efi_bsdrv_arch (abfd->xvec));
1351
      else if (bfd_target_efi_rtdrv_p (abfd->xvec))
1352
        arch = pe_arch (bfd_target_efi_rtdrv_arch (abfd->xvec));
1353
      else
1354
        arch = pe_arch (bfd_target_pei_arch (abfd->xvec));
1355
 
1356
      /* Don't check PE vs. EFI if arch is unknown.  */
1357
      if (arch == arch_type_unknown)
1358
        {
1359
          bfd_preserve_finish (abfd, &preserve);
1360
          return target;
1361
        }
1362
 
1363
      for (target_ptr = bfd_target_vector; *target_ptr != NULL;
1364
           target_ptr++)
1365
        {
1366
          if (*target_ptr == target
1367
              || (*target_ptr)->flavour != bfd_target_coff_flavour)
1368
            continue;
1369
 
1370
          if (bfd_target_efi_app_p (*target_ptr))
1371
            {
1372
              /* Skip incompatible arch.  */
1373
              if (pe_arch (bfd_target_efi_app_arch (*target_ptr)) != arch)
1374
                continue;
1375
 
1376
              if (efi)
1377
                {
1378
                  /* TARGET_PTR is an EFI backend.  Don't match
1379
                     TARGET with a EFI file.  */
1380
                  bfd_set_error (bfd_error_wrong_format);
1381
                  return NULL;
1382
                }
1383
            }
1384
          else if (bfd_target_efi_bsdrv_p (*target_ptr))
1385
            {
1386
              /* Skip incompatible arch.  */
1387
              if (pe_arch (bfd_target_efi_bsdrv_arch (*target_ptr)) != arch)
1388
                continue;
1389
 
1390
              if (efi)
1391
                {
1392
                  /* TARGET_PTR is an EFI backend.  Don't match
1393
                     TARGET with a EFI file.  */
1394
                  bfd_set_error (bfd_error_wrong_format);
1395
                  return NULL;
1396
                }
1397
            }
1398
          else if (bfd_target_efi_rtdrv_p (*target_ptr))
1399
            {
1400
              /* Skip incompatible arch.  */
1401
              if (pe_arch (bfd_target_efi_rtdrv_arch (*target_ptr)) != arch)
1402
                continue;
1403
 
1404
              if (efi)
1405
                {
1406
no_match:
1407
                  /* TARGET_PTR is an EFI backend.  Don't match
1408
                     TARGET with a EFI file.  */
1409
                  bfd_preserve_restore (abfd, &preserve);
1410
                  bfd_set_error (bfd_error_wrong_format);
1411
                  return NULL;
1412
                }
1413
            }
1414
          else if (bfd_target_pei_p (*target_ptr))
1415
            {
1416
              /* Skip incompatible arch.  */
1417
              if (pe_arch (bfd_target_pei_arch (*target_ptr)) != arch)
1418
                continue;
1419
 
1420
              if (!efi)
1421
                {
1422
                  /* TARGET_PTR is a PE backend.  Don't match
1423
                     TARGET with a PE file.  */
1424
                  goto no_match;
1425
                }
1426
            }
1427
        }
1428
 
1429
      bfd_preserve_finish (abfd, &preserve);
1430
    }
1431
  else
1432
    bfd_preserve_restore (abfd, &preserve);
1433
 
1434
  return target;
1435
}
1436
 
1437
#define coff_object_p pe_bfd_object_p
1438
#endif /* COFF_IMAGE_WITH_PE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.