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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [peicode.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

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