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