For sections containing uninitialised data, only set their size to s_paddr
[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, 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 \f
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 */