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