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