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

Subversion Repositories open8_urisc

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

Details | Compare with Previous | View Log

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