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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [peicode.h] - Blame information for rev 14

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

Line No. Rev Author Line
1 14 khays
/* 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, 2009  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_pei_p (abfd) || scnhdr_int->s_size == 0))
240
          || (bfd_pei_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
  return TRUE;
268
}
269
 
270
/* Create the COFF backend specific information.  */
271
 
272
static void *
273
pe_mkobject_hook (bfd * abfd,
274
                  void * filehdr,
275
                  void * aouthdr ATTRIBUTE_UNUSED)
276
{
277
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
278
  pe_data_type *pe;
279
 
280
  if (! pe_mkobject (abfd))
281
    return NULL;
282
 
283
  pe = pe_data (abfd);
284
  pe->coff.sym_filepos = internal_f->f_symptr;
285
  /* These members communicate important constants about the symbol
286
     table to GDB's symbol-reading code.  These `constants'
287
     unfortunately vary among coff implementations...  */
288
  pe->coff.local_n_btmask = N_BTMASK;
289
  pe->coff.local_n_btshft = N_BTSHFT;
290
  pe->coff.local_n_tmask = N_TMASK;
291
  pe->coff.local_n_tshift = N_TSHIFT;
292
  pe->coff.local_symesz = SYMESZ;
293
  pe->coff.local_auxesz = AUXESZ;
294
  pe->coff.local_linesz = LINESZ;
295
 
296
  pe->coff.timestamp = internal_f->f_timdat;
297
 
298
  obj_raw_syment_count (abfd) =
299
    obj_conv_table_size (abfd) =
300
      internal_f->f_nsyms;
301
 
302
  pe->real_flags = internal_f->f_flags;
303
 
304
  if ((internal_f->f_flags & F_DLL) != 0)
305
    pe->dll = 1;
306
 
307
  if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
308
    abfd->flags |= HAS_DEBUG;
309
 
310
#ifdef COFF_IMAGE_WITH_PE
311
  if (aouthdr)
312
    pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe;
313
#endif
314
 
315
#ifdef ARM
316
  if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
317
    coff_data (abfd) ->flags = 0;
318
#endif
319
 
320
  return (void *) pe;
321
}
322
 
323
static bfd_boolean
324
pe_print_private_bfd_data (bfd *abfd, void * vfile)
325
{
326
  FILE *file = (FILE *) vfile;
327
 
328
  if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
329
    return FALSE;
330
 
331
  if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
332
    return TRUE;
333
 
334
  fputc ('\n', file);
335
 
336
  return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
337
}
338
 
339
/* Copy any private info we understand from the input bfd
340
   to the output bfd.  */
341
 
342
static bfd_boolean
343
pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
344
{
345
  /* PR binutils/716: Copy the large address aware flag.
346
     XXX: Should we be copying other flags or other fields in the pe_data()
347
     structure ?  */
348
  if (pe_data (obfd) != NULL
349
      && pe_data (ibfd) != NULL
350
      && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
351
    pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
352
 
353
  if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
354
    return FALSE;
355
 
356
  if (pe_saved_coff_bfd_copy_private_bfd_data)
357
    return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
358
 
359
  return TRUE;
360
}
361
 
362
#define coff_bfd_copy_private_section_data \
363
  _bfd_XX_bfd_copy_private_section_data
364
 
365
#define coff_get_symbol_info _bfd_XX_get_symbol_info
366
 
367
#ifdef COFF_IMAGE_WITH_PE
368
 
369
/* Code to handle Microsoft's Image Library Format.
370
   Also known as LINK6 format.
371
   Documentation about this format can be found at:
372
 
373
   http://msdn.microsoft.com/library/specs/pecoff_section8.htm  */
374
 
375
/* The following constants specify the sizes of the various data
376
   structures that we have to create in order to build a bfd describing
377
   an ILF object file.  The final "+ 1" in the definitions of SIZEOF_IDATA6
378
   and SIZEOF_IDATA7 below is to allow for the possibility that we might
379
   need a padding byte in order to ensure 16 bit alignment for the section's
380
   contents.
381
 
382
   The value for SIZEOF_ILF_STRINGS is computed as follows:
383
 
384
      There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
385
      per symbol for their names (longest section name is .idata$x).
386
 
387
      There will be two symbols for the imported value, one the symbol name
388
      and one with _imp__ prefixed.  Allowing for the terminating nul's this
389
      is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
390
 
391
      The strings in the string table must start STRING__SIZE_SIZE bytes into
392
      the table in order to for the string lookup code in coffgen/coffcode to
393
      work.  */
394
#define NUM_ILF_RELOCS          8
395
#define NUM_ILF_SECTIONS        6
396
#define NUM_ILF_SYMS            (2 + NUM_ILF_SECTIONS)
397
 
398
#define SIZEOF_ILF_SYMS          (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
399
#define SIZEOF_ILF_SYM_TABLE     (NUM_ILF_SYMS * sizeof (* vars.sym_table))
400
#define SIZEOF_ILF_NATIVE_SYMS   (NUM_ILF_SYMS * sizeof (* vars.native_syms))
401
#define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
402
#define SIZEOF_ILF_EXT_SYMS      (NUM_ILF_SYMS * sizeof (* vars.esym_table))
403
#define SIZEOF_ILF_RELOCS        (NUM_ILF_RELOCS * sizeof (* vars.reltab))
404
#define SIZEOF_ILF_INT_RELOCS    (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
405
#define SIZEOF_ILF_STRINGS       (strlen (symbol_name) * 2 + 8 \
406
                                        + 21 + strlen (source_dll) \
407
                                        + NUM_ILF_SECTIONS * 9 \
408
                                        + STRING_SIZE_SIZE)
409
#define SIZEOF_IDATA2           (5 * 4)
410
 
411
/* For PEx64 idata4 & 5 have thumb size of 8 bytes.  */
412
#ifdef COFF_WITH_pex64
413
#define SIZEOF_IDATA4           (2 * 4)
414
#define SIZEOF_IDATA5           (2 * 4)
415
#else
416
#define SIZEOF_IDATA4           (1 * 4)
417
#define SIZEOF_IDATA5           (1 * 4)
418
#endif
419
 
420
#define SIZEOF_IDATA6           (2 + strlen (symbol_name) + 1 + 1)
421
#define SIZEOF_IDATA7           (strlen (source_dll) + 1 + 1)
422
#define SIZEOF_ILF_SECTIONS     (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
423
 
424
#define ILF_DATA_SIZE                           \
425
    + SIZEOF_ILF_SYMS                           \
426
    + SIZEOF_ILF_SYM_TABLE                      \
427
    + SIZEOF_ILF_NATIVE_SYMS                    \
428
    + SIZEOF_ILF_SYM_PTR_TABLE                  \
429
    + SIZEOF_ILF_EXT_SYMS                       \
430
    + SIZEOF_ILF_RELOCS                         \
431
    + SIZEOF_ILF_INT_RELOCS                     \
432
    + SIZEOF_ILF_STRINGS                        \
433
    + SIZEOF_IDATA2                             \
434
    + SIZEOF_IDATA4                             \
435
    + SIZEOF_IDATA5                             \
436
    + SIZEOF_IDATA6                             \
437
    + SIZEOF_IDATA7                             \
438
    + SIZEOF_ILF_SECTIONS                       \
439
    + MAX_TEXT_SECTION_SIZE
440
 
441
/* Create an empty relocation against the given symbol.  */
442
 
443
static void
444
pe_ILF_make_a_symbol_reloc (pe_ILF_vars *               vars,
445
                            bfd_vma                     address,
446
                            bfd_reloc_code_real_type    reloc,
447
                            struct bfd_symbol **        sym,
448
                            unsigned int                sym_index)
449
{
450
  arelent * entry;
451
  struct internal_reloc * internal;
452
 
453
  entry = vars->reltab + vars->relcount;
454
  internal = vars->int_reltab + vars->relcount;
455
 
456
  entry->address     = address;
457
  entry->addend      = 0;
458
  entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
459
  entry->sym_ptr_ptr = sym;
460
 
461
  internal->r_vaddr  = address;
462
  internal->r_symndx = sym_index;
463
  internal->r_type   = entry->howto->type;
464
 
465
  vars->relcount ++;
466
 
467
  BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
468
}
469
 
470
/* Create an empty relocation against the given section.  */
471
 
472
static void
473
pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
474
                     bfd_vma                   address,
475
                     bfd_reloc_code_real_type  reloc,
476
                     asection_ptr              sec)
477
{
478
  pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
479
                              coff_section_data (vars->abfd, sec)->i);
480
}
481
 
482
/* Move the queued relocs into the given section.  */
483
 
484
static void
485
pe_ILF_save_relocs (pe_ILF_vars * vars,
486
                    asection_ptr  sec)
487
{
488
  /* Make sure that there is somewhere to store the internal relocs.  */
489
  if (coff_section_data (vars->abfd, sec) == NULL)
490
    /* We should probably return an error indication here.  */
491
    abort ();
492
 
493
  coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
494
  coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
495
 
496
  sec->relocation  = vars->reltab;
497
  sec->reloc_count = vars->relcount;
498
  sec->flags      |= SEC_RELOC;
499
 
500
  vars->reltab     += vars->relcount;
501
  vars->int_reltab += vars->relcount;
502
  vars->relcount   = 0;
503
 
504
  BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
505
}
506
 
507
/* Create a global symbol and add it to the relevant tables.  */
508
 
509
static void
510
pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
511
                      const char *   prefix,
512
                      const char *   symbol_name,
513
                      asection_ptr   section,
514
                      flagword       extra_flags)
515
{
516
  coff_symbol_type * sym;
517
  combined_entry_type * ent;
518
  SYMENT * esym;
519
  unsigned short sclass;
520
 
521
  if (extra_flags & BSF_LOCAL)
522
    sclass = C_STAT;
523
  else
524
    sclass = C_EXT;
525
 
526
#ifdef THUMBPEMAGIC
527
  if (vars->magic == THUMBPEMAGIC)
528
    {
529
      if (extra_flags & BSF_FUNCTION)
530
        sclass = C_THUMBEXTFUNC;
531
      else if (extra_flags & BSF_LOCAL)
532
        sclass = C_THUMBSTAT;
533
      else
534
        sclass = C_THUMBEXT;
535
    }
536
#endif
537
 
538
  BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
539
 
540
  sym = vars->sym_ptr;
541
  ent = vars->native_ptr;
542
  esym = vars->esym_ptr;
543
 
544
  /* Copy the symbol's name into the string table.  */
545
  sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
546
 
547
  if (section == NULL)
548
    section = (asection_ptr) & bfd_und_section;
549
 
550
  /* Initialise the external symbol.  */
551
  H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
552
            esym->e.e.e_offset);
553
  H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
554
  esym->e_sclass[0] = sclass;
555
 
556
  /* The following initialisations are unnecessary - the memory is
557
     zero initialised.  They are just kept here as reminders.  */
558
 
559
  /* Initialise the internal symbol structure.  */
560
  ent->u.syment.n_sclass          = sclass;
561
  ent->u.syment.n_scnum           = section->target_index;
562
  ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
563
 
564
  sym->symbol.the_bfd = vars->abfd;
565
  sym->symbol.name    = vars->string_ptr;
566
  sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
567
  sym->symbol.section = section;
568
  sym->native         = ent;
569
 
570
  * vars->table_ptr = vars->sym_index;
571
  * vars->sym_ptr_ptr = sym;
572
 
573
  /* Adjust pointers for the next symbol.  */
574
  vars->sym_index ++;
575
  vars->sym_ptr ++;
576
  vars->sym_ptr_ptr ++;
577
  vars->table_ptr ++;
578
  vars->native_ptr ++;
579
  vars->esym_ptr ++;
580
  vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
581
 
582
  BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
583
}
584
 
585
/* Create a section.  */
586
 
587
static asection_ptr
588
pe_ILF_make_a_section (pe_ILF_vars * vars,
589
                       const char *  name,
590
                       unsigned int  size,
591
                       flagword      extra_flags)
592
{
593
  asection_ptr sec;
594
  flagword     flags;
595
 
596
  sec = bfd_make_section_old_way (vars->abfd, name);
597
  if (sec == NULL)
598
    return NULL;
599
 
600
  flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
601
 
602
  bfd_set_section_flags (vars->abfd, sec, flags | extra_flags);
603
 
604
  bfd_set_section_alignment (vars->abfd, sec, 2);
605
 
606
  /* Check that we will not run out of space.  */
607
  BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
608
 
609
  /* Set the section size and contents.  The actual
610
     contents are filled in by our parent.  */
611
  bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size);
612
  sec->contents = vars->data;
613
  sec->target_index = vars->sec_index ++;
614
 
615
  /* Advance data pointer in the vars structure.  */
616
  vars->data += size;
617
 
618
  /* Skip the padding byte if it was not needed.
619
     The logic here is that if the string length is odd,
620
     then the entire string length, including the null byte,
621
     is even and so the extra, padding byte, is not needed.  */
622
  if (size & 1)
623
    vars->data --;
624
 
625
  /* Create a coff_section_tdata structure for our use.  */
626
  sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
627
  vars->data += sizeof (struct coff_section_tdata);
628
 
629
  BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
630
 
631
  /* Create a symbol to refer to this section.  */
632
  pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
633
 
634
  /* Cache the index to the symbol in the coff_section_data structure.  */
635
  coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
636
 
637
  return sec;
638
}
639
 
640
/* This structure contains the code that goes into the .text section
641
   in order to perform a jump into the DLL lookup table.  The entries
642
   in the table are index by the magic number used to represent the
643
   machine type in the PE file.  The contents of the data[] arrays in
644
   these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
645
   The SIZE field says how many bytes in the DATA array are actually
646
   used.  The OFFSET field says where in the data array the address
647
   of the .idata$5 section should be placed.  */
648
#define MAX_TEXT_SECTION_SIZE 32
649
 
650
typedef struct
651
{
652
  unsigned short magic;
653
  unsigned char  data[MAX_TEXT_SECTION_SIZE];
654
  unsigned int   size;
655
  unsigned int   offset;
656
}
657
jump_table;
658
 
659
static jump_table jtab[] =
660
{
661
#ifdef I386MAGIC
662
  { I386MAGIC,
663
    { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
664
    8, 2
665
  },
666
#endif
667
 
668
#ifdef AMD64MAGIC
669
  { AMD64MAGIC,
670
    { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
671
    8, 2
672
  },
673
#endif
674
 
675
#ifdef  MC68MAGIC
676
  { MC68MAGIC,
677
    { /* XXX fill me in */ },
678
    0, 0
679
  },
680
#endif
681
 
682
#ifdef  MIPS_ARCH_MAGIC_WINCE
683
  { MIPS_ARCH_MAGIC_WINCE,
684
    { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
685
      0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
686
    16, 0
687
  },
688
#endif
689
 
690
#ifdef  SH_ARCH_MAGIC_WINCE
691
  { SH_ARCH_MAGIC_WINCE,
692
    { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
693
      0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
694
    12, 8
695
  },
696
#endif
697
 
698
#ifdef  ARMPEMAGIC
699
  { ARMPEMAGIC,
700
    { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
701
      0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
702
    12, 8
703
  },
704
#endif
705
 
706
#ifdef  THUMBPEMAGIC
707
  { THUMBPEMAGIC,
708
    { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
709
      0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
710
    16, 12
711
  },
712
#endif
713
  { 0, { 0 }, 0, 0 }
714
};
715
 
716
#ifndef NUM_ENTRIES
717
#define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
718
#endif
719
 
720
/* Build a full BFD from the information supplied in a ILF object.  */
721
 
722
static bfd_boolean
723
pe_ILF_build_a_bfd (bfd *           abfd,
724
                    unsigned int    magic,
725
                    char *          symbol_name,
726
                    char *          source_dll,
727
                    unsigned int    ordinal,
728
                    unsigned int    types)
729
{
730
  bfd_byte *               ptr;
731
  pe_ILF_vars              vars;
732
  struct internal_filehdr  internal_f;
733
  unsigned int             import_type;
734
  unsigned int             import_name_type;
735
  asection_ptr             id4, id5, id6 = NULL, text = NULL;
736
  coff_symbol_type **      imp_sym;
737
  unsigned int             imp_index;
738
 
739
  /* Decode and verify the types field of the ILF structure.  */
740
  import_type = types & 0x3;
741
  import_name_type = (types & 0x1c) >> 2;
742
 
743
  switch (import_type)
744
    {
745
    case IMPORT_CODE:
746
    case IMPORT_DATA:
747
      break;
748
 
749
    case IMPORT_CONST:
750
      /* XXX code yet to be written.  */
751
      _bfd_error_handler (_("%B: Unhandled import type; %x"),
752
                          abfd, import_type);
753
      return FALSE;
754
 
755
    default:
756
      _bfd_error_handler (_("%B: Unrecognised import type; %x"),
757
                          abfd, import_type);
758
      return FALSE;
759
    }
760
 
761
  switch (import_name_type)
762
    {
763
    case IMPORT_ORDINAL:
764
    case IMPORT_NAME:
765
    case IMPORT_NAME_NOPREFIX:
766
    case IMPORT_NAME_UNDECORATE:
767
      break;
768
 
769
    default:
770
      _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
771
                          abfd, import_name_type);
772
      return FALSE;
773
    }
774
 
775
  /* Initialise local variables.
776
 
777
     Note these are kept in a structure rather than being
778
     declared as statics since bfd frowns on global variables.
779
 
780
     We are going to construct the contents of the BFD in memory,
781
     so allocate all the space that we will need right now.  */
782
  vars.bim
783
    = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
784
  if (vars.bim == NULL)
785
    return FALSE;
786
 
787
  ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
788
  vars.bim->buffer = ptr;
789
  vars.bim->size   = ILF_DATA_SIZE;
790
  if (ptr == NULL)
791
    goto error_return;
792
 
793
  /* Initialise the pointers to regions of the memory and the
794
     other contents of the pe_ILF_vars structure as well.  */
795
  vars.sym_cache = (coff_symbol_type *) ptr;
796
  vars.sym_ptr   = (coff_symbol_type *) ptr;
797
  vars.sym_index = 0;
798
  ptr += SIZEOF_ILF_SYMS;
799
 
800
  vars.sym_table = (unsigned int *) ptr;
801
  vars.table_ptr = (unsigned int *) ptr;
802
  ptr += SIZEOF_ILF_SYM_TABLE;
803
 
804
  vars.native_syms = (combined_entry_type *) ptr;
805
  vars.native_ptr  = (combined_entry_type *) ptr;
806
  ptr += SIZEOF_ILF_NATIVE_SYMS;
807
 
808
  vars.sym_ptr_table = (coff_symbol_type **) ptr;
809
  vars.sym_ptr_ptr   = (coff_symbol_type **) ptr;
810
  ptr += SIZEOF_ILF_SYM_PTR_TABLE;
811
 
812
  vars.esym_table = (SYMENT *) ptr;
813
  vars.esym_ptr   = (SYMENT *) ptr;
814
  ptr += SIZEOF_ILF_EXT_SYMS;
815
 
816
  vars.reltab   = (arelent *) ptr;
817
  vars.relcount = 0;
818
  ptr += SIZEOF_ILF_RELOCS;
819
 
820
  vars.int_reltab  = (struct internal_reloc *) ptr;
821
  ptr += SIZEOF_ILF_INT_RELOCS;
822
 
823
  vars.string_table = (char *) ptr;
824
  vars.string_ptr   = (char *) ptr + STRING_SIZE_SIZE;
825
  ptr += SIZEOF_ILF_STRINGS;
826
  vars.end_string_ptr = (char *) ptr;
827
 
828
  /* The remaining space in bim->buffer is used
829
     by the pe_ILF_make_a_section() function.  */
830
  vars.data = ptr;
831
  vars.abfd = abfd;
832
  vars.sec_index = 0;
833
  vars.magic = magic;
834
 
835
  /* Create the initial .idata$<n> sections:
836
     [.idata$2:  Import Directory Table -- not needed]
837
     .idata$4:  Import Lookup Table
838
     .idata$5:  Import Address Table
839
 
840
     Note we do not create a .idata$3 section as this is
841
     created for us by the linker script.  */
842
  id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
843
  id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
844
  if (id4 == NULL || id5 == NULL)
845
    goto error_return;
846
 
847
  /* Fill in the contents of these sections.  */
848
  if (import_name_type == IMPORT_ORDINAL)
849
    {
850
      if (ordinal == 0)
851
        /* XXX - treat as IMPORT_NAME ??? */
852
        abort ();
853
 
854
#ifdef COFF_WITH_pex64
855
      ((unsigned int *) id4->contents)[0] = ordinal;
856
      ((unsigned int *) id4->contents)[1] = 0x80000000;
857
      ((unsigned int *) id5->contents)[0] = ordinal;
858
      ((unsigned int *) id5->contents)[1] = 0x80000000;
859
#else
860
      * (unsigned int *) id4->contents = ordinal | 0x80000000;
861
      * (unsigned int *) id5->contents = ordinal | 0x80000000;
862
#endif
863
    }
864
  else
865
    {
866
      char * symbol;
867
      unsigned int len;
868
 
869
      /* Create .idata$6 - the Hint Name Table.  */
870
      id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
871
      if (id6 == NULL)
872
        goto error_return;
873
 
874
      /* If necessary, trim the import symbol name.  */
875
      symbol = symbol_name;
876
 
877
      /* As used by MS compiler, '_', '@', and '?' are alternative
878
         forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
879
         '@' used for fastcall (in C),  '_' everywhere else.  Only one
880
         of these is used for a symbol.  We strip this leading char for
881
         IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
882
         PE COFF 6.0 spec (section 8.3, Import Name Type).  */
883
 
884
      if (import_name_type != IMPORT_NAME)
885
        {
886
          char c = symbol[0];
887
          if (c == '_' || c == '@' || c == '?')
888
            symbol++;
889
        }
890
 
891
      len = strlen (symbol);
892
      if (import_name_type == IMPORT_NAME_UNDECORATE)
893
        {
894
          /* Truncate at the first '@'.  */
895
          char *at = strchr (symbol, '@');
896
 
897
          if (at != NULL)
898
            len = at - symbol;
899
        }
900
 
901
      id6->contents[0] = ordinal & 0xff;
902
      id6->contents[1] = ordinal >> 8;
903
 
904
      memcpy ((char *) id6->contents + 2, symbol, len);
905
      id6->contents[len + 2] = '\0';
906
    }
907
 
908
  if (import_name_type != IMPORT_ORDINAL)
909
    {
910
      pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
911
      pe_ILF_save_relocs (&vars, id4);
912
 
913
      pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
914
      pe_ILF_save_relocs (&vars, id5);
915
    }
916
 
917
  /* Create extra sections depending upon the type of import we are dealing with.  */
918
  switch (import_type)
919
    {
920
      int i;
921
 
922
    case IMPORT_CODE:
923
      /* Create a .text section.
924
         First we need to look up its contents in the jump table.  */
925
      for (i = NUM_ENTRIES (jtab); i--;)
926
        {
927
          if (jtab[i].size == 0)
928
            continue;
929
          if (jtab[i].magic == magic)
930
            break;
931
        }
932
      /* If we did not find a matching entry something is wrong.  */
933
      if (i < 0)
934
        abort ();
935
 
936
      /* Create the .text section.  */
937
      text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
938
      if (text == NULL)
939
        goto error_return;
940
 
941
      /* Copy in the jump code.  */
942
      memcpy (text->contents, jtab[i].data, jtab[i].size);
943
 
944
      /* Create an import symbol.  */
945
      pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
946
      imp_sym   = vars.sym_ptr_ptr - 1;
947
      imp_index = vars.sym_index - 1;
948
 
949
      /* Create a reloc for the data in the text section.  */
950
#ifdef MIPS_ARCH_MAGIC_WINCE
951
      if (magic == MIPS_ARCH_MAGIC_WINCE)
952
        {
953
          pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
954
                                      (struct bfd_symbol **) imp_sym,
955
                                      imp_index);
956
          pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
957
          pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
958
                                      (struct bfd_symbol **) imp_sym,
959
                                      imp_index);
960
        }
961
      else
962
#endif
963
        pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
964
                                    BFD_RELOC_32, (asymbol **) imp_sym,
965
                                    imp_index);
966
 
967
      pe_ILF_save_relocs (& vars, text);
968
      break;
969
 
970
    case IMPORT_DATA:
971
      break;
972
 
973
    default:
974
      /* XXX code not yet written.  */
975
      abort ();
976
    }
977
 
978
  /* Initialise the bfd.  */
979
  memset (& internal_f, 0, sizeof (internal_f));
980
 
981
  internal_f.f_magic  = magic;
982
  internal_f.f_symptr = 0;
983
  internal_f.f_nsyms  = 0;
984
  internal_f.f_flags  = F_AR32WR | F_LNNO; /* XXX is this correct ?  */
985
 
986
  if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
987
      || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
988
    goto error_return;
989
 
990
  if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
991
    goto error_return;
992
 
993
  coff_data (abfd)->pe = 1;
994
#ifdef THUMBPEMAGIC
995
  if (vars.magic == THUMBPEMAGIC)
996
    /* Stop some linker warnings about thumb code not supporting interworking.  */
997
    coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
998
#endif
999
 
1000
  /* Switch from file contents to memory contents.  */
1001
  bfd_cache_close (abfd);
1002
 
1003
  abfd->iostream = (void *) vars.bim;
1004
  abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
1005
  abfd->iovec = &_bfd_memory_iovec;
1006
  abfd->where = 0;
1007
  abfd->origin = 0;
1008
  obj_sym_filepos (abfd) = 0;
1009
 
1010
  /* Now create a symbol describing the imported value.  */
1011
  switch (import_type)
1012
    {
1013
    case IMPORT_CODE:
1014
      pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
1015
                            BSF_NOT_AT_END | BSF_FUNCTION);
1016
 
1017
      /* Create an import symbol for the DLL, without the
1018
       .dll suffix.  */
1019
      ptr = (bfd_byte *) strrchr (source_dll, '.');
1020
      if (ptr)
1021
        * ptr = 0;
1022
      pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
1023
      if (ptr)
1024
        * ptr = '.';
1025
      break;
1026
 
1027
    case IMPORT_DATA:
1028
      /* Nothing to do here.  */
1029
      break;
1030
 
1031
    default:
1032
      /* XXX code not yet written.  */
1033
      abort ();
1034
    }
1035
 
1036
  /* Point the bfd at the symbol table.  */
1037
  obj_symbols (abfd) = vars.sym_cache;
1038
  bfd_get_symcount (abfd) = vars.sym_index;
1039
 
1040
  obj_raw_syments (abfd) = vars.native_syms;
1041
  obj_raw_syment_count (abfd) = vars.sym_index;
1042
 
1043
  obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1044
  obj_coff_keep_syms (abfd) = TRUE;
1045
 
1046
  obj_convert (abfd) = vars.sym_table;
1047
  obj_conv_table_size (abfd) = vars.sym_index;
1048
 
1049
  obj_coff_strings (abfd) = vars.string_table;
1050
  obj_coff_keep_strings (abfd) = TRUE;
1051
 
1052
  abfd->flags |= HAS_SYMS;
1053
 
1054
  return TRUE;
1055
 
1056
 error_return:
1057
  if (vars.bim->buffer != NULL)
1058
    free (vars.bim->buffer);
1059
  free (vars.bim);
1060
  return FALSE;
1061
}
1062
 
1063
/* We have detected a Image Library Format archive element.
1064
   Decode the element and return the appropriate target.  */
1065
 
1066
static const bfd_target *
1067
pe_ILF_object_p (bfd * abfd)
1068
{
1069
  bfd_byte        buffer[16];
1070
  bfd_byte *      ptr;
1071
  char *          symbol_name;
1072
  char *          source_dll;
1073
  unsigned int    machine;
1074
  bfd_size_type   size;
1075
  unsigned int    ordinal;
1076
  unsigned int    types;
1077
  unsigned int    magic;
1078
 
1079
  /* Upon entry the first four buyes of the ILF header have
1080
      already been read.  Now read the rest of the header.  */
1081
  if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16)
1082
    return NULL;
1083
 
1084
  ptr = buffer;
1085
 
1086
  /*  We do not bother to check the version number.
1087
      version = H_GET_16 (abfd, ptr);  */
1088
  ptr += 2;
1089
 
1090
  machine = H_GET_16 (abfd, ptr);
1091
  ptr += 2;
1092
 
1093
  /* Check that the machine type is recognised.  */
1094
  magic = 0;
1095
 
1096
  switch (machine)
1097
    {
1098
    case IMAGE_FILE_MACHINE_UNKNOWN:
1099
    case IMAGE_FILE_MACHINE_ALPHA:
1100
    case IMAGE_FILE_MACHINE_ALPHA64:
1101
    case IMAGE_FILE_MACHINE_IA64:
1102
      break;
1103
 
1104
    case IMAGE_FILE_MACHINE_I386:
1105
#ifdef I386MAGIC
1106
      magic = I386MAGIC;
1107
#endif
1108
      break;
1109
 
1110
    case IMAGE_FILE_MACHINE_AMD64:
1111
#ifdef AMD64MAGIC
1112
      magic = AMD64MAGIC;
1113
#endif
1114
      break;
1115
 
1116
    case IMAGE_FILE_MACHINE_M68K:
1117
#ifdef MC68AGIC
1118
      magic = MC68MAGIC;
1119
#endif
1120
      break;
1121
 
1122
    case IMAGE_FILE_MACHINE_R3000:
1123
    case IMAGE_FILE_MACHINE_R4000:
1124
    case IMAGE_FILE_MACHINE_R10000:
1125
 
1126
    case IMAGE_FILE_MACHINE_MIPS16:
1127
    case IMAGE_FILE_MACHINE_MIPSFPU:
1128
    case IMAGE_FILE_MACHINE_MIPSFPU16:
1129
#ifdef MIPS_ARCH_MAGIC_WINCE
1130
      magic = MIPS_ARCH_MAGIC_WINCE;
1131
#endif
1132
      break;
1133
 
1134
    case IMAGE_FILE_MACHINE_SH3:
1135
    case IMAGE_FILE_MACHINE_SH4:
1136
#ifdef SH_ARCH_MAGIC_WINCE
1137
      magic = SH_ARCH_MAGIC_WINCE;
1138
#endif
1139
      break;
1140
 
1141
    case IMAGE_FILE_MACHINE_ARM:
1142
#ifdef ARMPEMAGIC
1143
      magic = ARMPEMAGIC;
1144
#endif
1145
      break;
1146
 
1147
    case IMAGE_FILE_MACHINE_THUMB:
1148
#ifdef THUMBPEMAGIC
1149
      {
1150
        extern const bfd_target TARGET_LITTLE_SYM;
1151
 
1152
        if (abfd->xvec == & TARGET_LITTLE_SYM)
1153
          magic = THUMBPEMAGIC;
1154
      }
1155
#endif
1156
      break;
1157
 
1158
    case IMAGE_FILE_MACHINE_POWERPC:
1159
      /* We no longer support PowerPC.  */
1160
    default:
1161
      _bfd_error_handler
1162
        (_("%B: Unrecognised machine type (0x%x)"
1163
           " in Import Library Format archive"),
1164
         abfd, machine);
1165
      bfd_set_error (bfd_error_malformed_archive);
1166
 
1167
      return NULL;
1168
      break;
1169
    }
1170
 
1171
  if (magic == 0)
1172
    {
1173
      _bfd_error_handler
1174
        (_("%B: Recognised but unhandled machine type (0x%x)"
1175
           " in Import Library Format archive"),
1176
         abfd, machine);
1177
      bfd_set_error (bfd_error_wrong_format);
1178
 
1179
      return NULL;
1180
    }
1181
 
1182
  /* We do not bother to check the date.
1183
     date = H_GET_32 (abfd, ptr);  */
1184
  ptr += 4;
1185
 
1186
  size = H_GET_32 (abfd, ptr);
1187
  ptr += 4;
1188
 
1189
  if (size == 0)
1190
    {
1191
      _bfd_error_handler
1192
        (_("%B: size field is zero in Import Library Format header"), abfd);
1193
      bfd_set_error (bfd_error_malformed_archive);
1194
 
1195
      return NULL;
1196
    }
1197
 
1198
  ordinal = H_GET_16 (abfd, ptr);
1199
  ptr += 2;
1200
 
1201
  types = H_GET_16 (abfd, ptr);
1202
  /* ptr += 2; */
1203
 
1204
  /* Now read in the two strings that follow.  */
1205
  ptr = (bfd_byte *) bfd_alloc (abfd, size);
1206
  if (ptr == NULL)
1207
    return NULL;
1208
 
1209
  if (bfd_bread (ptr, size, abfd) != size)
1210
    {
1211
      bfd_release (abfd, ptr);
1212
      return NULL;
1213
    }
1214
 
1215
  symbol_name = (char *) ptr;
1216
  source_dll  = symbol_name + strlen (symbol_name) + 1;
1217
 
1218
  /* Verify that the strings are null terminated.  */
1219
  if (ptr[size - 1] != 0
1220
      || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
1221
    {
1222
      _bfd_error_handler
1223
        (_("%B: string not null terminated in ILF object file."), abfd);
1224
      bfd_set_error (bfd_error_malformed_archive);
1225
      bfd_release (abfd, ptr);
1226
      return NULL;
1227
    }
1228
 
1229
  /* Now construct the bfd.  */
1230
  if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
1231
                            source_dll, ordinal, types))
1232
    {
1233
      bfd_release (abfd, ptr);
1234
      return NULL;
1235
    }
1236
 
1237
  return abfd->xvec;
1238
}
1239
 
1240
static const bfd_target *
1241
pe_bfd_object_p (bfd * abfd)
1242
{
1243
  bfd_byte buffer[4];
1244
  struct external_PEI_DOS_hdr dos_hdr;
1245
  struct external_PEI_IMAGE_hdr image_hdr;
1246
  file_ptr offset;
1247
 
1248
  /* Detect if this a Microsoft Import Library Format element.  */
1249
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1250
      || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4)
1251
    {
1252
      if (bfd_get_error () != bfd_error_system_call)
1253
        bfd_set_error (bfd_error_wrong_format);
1254
      return NULL;
1255
    }
1256
 
1257
  if (H_GET_32 (abfd, buffer) == 0xffff0000)
1258
    return pe_ILF_object_p (abfd);
1259
 
1260
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1261
      || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
1262
         != sizeof (dos_hdr))
1263
    {
1264
      if (bfd_get_error () != bfd_error_system_call)
1265
        bfd_set_error (bfd_error_wrong_format);
1266
      return NULL;
1267
    }
1268
 
1269
  /* There are really two magic numbers involved; the magic number
1270
     that says this is a NT executable (PEI) and the magic number that
1271
     determines the architecture.  The former is DOSMAGIC, stored in
1272
     the e_magic field.  The latter is stored in the f_magic field.
1273
     If the NT magic number isn't valid, the architecture magic number
1274
     could be mimicked by some other field (specifically, the number
1275
     of relocs in section 3).  Since this routine can only be called
1276
     correctly for a PEI file, check the e_magic number here, and, if
1277
     it doesn't match, clobber the f_magic number so that we don't get
1278
     a false match.  */
1279
  if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
1280
    {
1281
      bfd_set_error (bfd_error_wrong_format);
1282
      return NULL;
1283
    }
1284
 
1285
  offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
1286
  if (bfd_seek (abfd, offset, SEEK_SET) != 0
1287
      || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
1288
          != sizeof (image_hdr)))
1289
    {
1290
      if (bfd_get_error () != bfd_error_system_call)
1291
        bfd_set_error (bfd_error_wrong_format);
1292
      return NULL;
1293
    }
1294
 
1295
  if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
1296
    {
1297
      bfd_set_error (bfd_error_wrong_format);
1298
      return NULL;
1299
    }
1300
 
1301
  /* Here is the hack.  coff_object_p wants to read filhsz bytes to
1302
     pick up the COFF header for PE, see "struct external_PEI_filehdr"
1303
     in include/coff/pe.h.  We adjust so that that will work. */
1304
  if (bfd_seek (abfd, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0)
1305
    {
1306
      if (bfd_get_error () != bfd_error_system_call)
1307
        bfd_set_error (bfd_error_wrong_format);
1308
      return NULL;
1309
    }
1310
 
1311
  return coff_object_p (abfd);
1312
}
1313
 
1314
#define coff_object_p pe_bfd_object_p
1315
#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.