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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [peicode.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

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