xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/peicode.h (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* Support for the generic parts of PE/PEI, for BFD.
2*e992f068Schristos    Copyright (C) 1995-2022 Free Software Foundation, Inc.
375fd0b74Schristos    Written by Cygnus Solutions.
475fd0b74Schristos 
575fd0b74Schristos    This file is part of BFD, the Binary File Descriptor library.
675fd0b74Schristos 
775fd0b74Schristos    This program is free software; you can redistribute it and/or modify
875fd0b74Schristos    it under the terms of the GNU General Public License as published by
975fd0b74Schristos    the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos    (at your option) any later version.
1175fd0b74Schristos 
1275fd0b74Schristos    This program is distributed in the hope that it will be useful,
1375fd0b74Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1575fd0b74Schristos    GNU General Public License for more details.
1675fd0b74Schristos 
1775fd0b74Schristos    You should have received a copy of the GNU General Public License
1875fd0b74Schristos    along with this program; if not, write to the Free Software
1975fd0b74Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos    MA 02110-1301, USA.  */
2175fd0b74Schristos 
2275fd0b74Schristos 
2375fd0b74Schristos /* Most of this hacked by  Steve Chamberlain,
2475fd0b74Schristos 			sac@cygnus.com
2575fd0b74Schristos 
2675fd0b74Schristos    PE/PEI rearrangement (and code added): Donn Terry
2775fd0b74Schristos 				       Softway Systems, Inc.  */
2875fd0b74Schristos 
2975fd0b74Schristos /* Hey look, some documentation [and in a place you expect to find it]!
3075fd0b74Schristos 
3175fd0b74Schristos    The main reference for the pei format is "Microsoft Portable Executable
3275fd0b74Schristos    and Common Object File Format Specification 4.1".  Get it if you need to
3375fd0b74Schristos    do some serious hacking on this code.
3475fd0b74Schristos 
3575fd0b74Schristos    Another reference:
3675fd0b74Schristos    "Peering Inside the PE: A Tour of the Win32 Portable Executable
3775fd0b74Schristos    File Format", MSJ 1994, Volume 9.
3875fd0b74Schristos 
3975fd0b74Schristos    The *sole* difference between the pe format and the pei format is that the
4075fd0b74Schristos    latter has an MSDOS 2.0 .exe header on the front that prints the message
4175fd0b74Schristos    "This app must be run under Windows." (or some such).
4275fd0b74Schristos    (FIXME: Whether that statement is *really* true or not is unknown.
4375fd0b74Schristos    Are there more subtle differences between pe and pei formats?
4475fd0b74Schristos    For now assume there aren't.  If you find one, then for God sakes
4575fd0b74Schristos    document it here!)
4675fd0b74Schristos 
4775fd0b74Schristos    The Microsoft docs use the word "image" instead of "executable" because
4875fd0b74Schristos    the former can also refer to a DLL (shared library).  Confusion can arise
4975fd0b74Schristos    because the `i' in `pei' also refers to "image".  The `pe' format can
5075fd0b74Schristos    also create images (i.e. executables), it's just that to run on a win32
5175fd0b74Schristos    system you need to use the pei format.
5275fd0b74Schristos 
5375fd0b74Schristos    FIXME: Please add more docs here so the next poor fool that has to hack
5475fd0b74Schristos    on this code has a chance of getting something accomplished without
5575fd0b74Schristos    wasting too much time.  */
5675fd0b74Schristos 
5775fd0b74Schristos #include "libpei.h"
5875fd0b74Schristos 
59*e992f068Schristos static bool (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
6075fd0b74Schristos #ifndef coff_bfd_print_private_bfd_data
6175fd0b74Schristos      NULL;
6275fd0b74Schristos #else
6375fd0b74Schristos      coff_bfd_print_private_bfd_data;
6475fd0b74Schristos #undef coff_bfd_print_private_bfd_data
6575fd0b74Schristos #endif
6675fd0b74Schristos 
67*e992f068Schristos static bool pe_print_private_bfd_data (bfd *, void *);
6875fd0b74Schristos #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
6975fd0b74Schristos 
70*e992f068Schristos static bool (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
7175fd0b74Schristos #ifndef coff_bfd_copy_private_bfd_data
7275fd0b74Schristos      NULL;
7375fd0b74Schristos #else
7475fd0b74Schristos      coff_bfd_copy_private_bfd_data;
7575fd0b74Schristos #undef coff_bfd_copy_private_bfd_data
7675fd0b74Schristos #endif
7775fd0b74Schristos 
78*e992f068Schristos static bool pe_bfd_copy_private_bfd_data (bfd *, bfd *);
7975fd0b74Schristos #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
8075fd0b74Schristos 
8175fd0b74Schristos #define coff_mkobject	   pe_mkobject
8275fd0b74Schristos #define coff_mkobject_hook pe_mkobject_hook
8375fd0b74Schristos 
8475fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
8575fd0b74Schristos /* This structure contains static variables used by the ILF code.  */
8675fd0b74Schristos typedef asection * asection_ptr;
8775fd0b74Schristos 
8875fd0b74Schristos typedef struct
8975fd0b74Schristos {
9075fd0b74Schristos   bfd *			abfd;
9175fd0b74Schristos   bfd_byte *		data;
9275fd0b74Schristos   struct bfd_in_memory * bim;
9375fd0b74Schristos   unsigned short	magic;
9475fd0b74Schristos 
9575fd0b74Schristos   arelent *		reltab;
9675fd0b74Schristos   unsigned int		relcount;
9775fd0b74Schristos 
9875fd0b74Schristos   coff_symbol_type *	sym_cache;
9975fd0b74Schristos   coff_symbol_type *	sym_ptr;
10075fd0b74Schristos   unsigned int		sym_index;
10175fd0b74Schristos 
10275fd0b74Schristos   unsigned int *	sym_table;
10375fd0b74Schristos   unsigned int *	table_ptr;
10475fd0b74Schristos 
10575fd0b74Schristos   combined_entry_type * native_syms;
10675fd0b74Schristos   combined_entry_type * native_ptr;
10775fd0b74Schristos 
10875fd0b74Schristos   coff_symbol_type **	sym_ptr_table;
10975fd0b74Schristos   coff_symbol_type **	sym_ptr_ptr;
11075fd0b74Schristos 
11175fd0b74Schristos   unsigned int		sec_index;
11275fd0b74Schristos 
11375fd0b74Schristos   char *		string_table;
11475fd0b74Schristos   char *		string_ptr;
11575fd0b74Schristos   char *		end_string_ptr;
11675fd0b74Schristos 
11775fd0b74Schristos   SYMENT *		esym_table;
11875fd0b74Schristos   SYMENT *		esym_ptr;
11975fd0b74Schristos 
12075fd0b74Schristos   struct internal_reloc * int_reltab;
12175fd0b74Schristos }
12275fd0b74Schristos pe_ILF_vars;
12375fd0b74Schristos #endif /* COFF_IMAGE_WITH_PE */
12475fd0b74Schristos 
125*e992f068Schristos bfd_cleanup coff_real_object_p
12675fd0b74Schristos   (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
12775fd0b74Schristos 
12875fd0b74Schristos #ifndef NO_COFF_RELOCS
12975fd0b74Schristos static void
coff_swap_reloc_in(bfd * abfd,void * src,void * dst)13075fd0b74Schristos coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
13175fd0b74Schristos {
13275fd0b74Schristos   RELOC *reloc_src = (RELOC *) src;
13375fd0b74Schristos   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
13475fd0b74Schristos 
13575fd0b74Schristos   reloc_dst->r_vaddr  = H_GET_32 (abfd, reloc_src->r_vaddr);
13675fd0b74Schristos   reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
13775fd0b74Schristos   reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
13875fd0b74Schristos #ifdef SWAP_IN_RELOC_OFFSET
13975fd0b74Schristos   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
14075fd0b74Schristos #endif
14175fd0b74Schristos }
14275fd0b74Schristos 
14375fd0b74Schristos static unsigned int
coff_swap_reloc_out(bfd * abfd,void * src,void * dst)14475fd0b74Schristos coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
14575fd0b74Schristos {
14675fd0b74Schristos   struct internal_reloc *reloc_src = (struct internal_reloc *) src;
14775fd0b74Schristos   struct external_reloc *reloc_dst = (struct external_reloc *) dst;
14875fd0b74Schristos 
14975fd0b74Schristos   H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
15075fd0b74Schristos   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
15175fd0b74Schristos   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
15275fd0b74Schristos 
15375fd0b74Schristos #ifdef SWAP_OUT_RELOC_OFFSET
15475fd0b74Schristos   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
15575fd0b74Schristos #endif
15675fd0b74Schristos #ifdef SWAP_OUT_RELOC_EXTRA
15775fd0b74Schristos   SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
15875fd0b74Schristos #endif
15975fd0b74Schristos   return RELSZ;
16075fd0b74Schristos }
16175fd0b74Schristos #endif /* not NO_COFF_RELOCS */
16275fd0b74Schristos 
16375fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
16475fd0b74Schristos #undef FILHDR
16575fd0b74Schristos #define FILHDR struct external_PEI_IMAGE_hdr
16675fd0b74Schristos #endif
16775fd0b74Schristos 
16875fd0b74Schristos static void
coff_swap_filehdr_in(bfd * abfd,void * src,void * dst)16975fd0b74Schristos coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
17075fd0b74Schristos {
17175fd0b74Schristos   FILHDR *filehdr_src = (FILHDR *) src;
17275fd0b74Schristos   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
17375fd0b74Schristos 
17475fd0b74Schristos   filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
17575fd0b74Schristos   filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
17675fd0b74Schristos   filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
17775fd0b74Schristos   filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
17875fd0b74Schristos   filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
17975fd0b74Schristos   filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr);
18075fd0b74Schristos 
18175fd0b74Schristos   /* Other people's tools sometimes generate headers with an nsyms but
18275fd0b74Schristos      a zero symptr.  */
18375fd0b74Schristos   if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
18475fd0b74Schristos     {
18575fd0b74Schristos       filehdr_dst->f_nsyms = 0;
18675fd0b74Schristos       filehdr_dst->f_flags |= F_LSYMS;
18775fd0b74Schristos     }
18875fd0b74Schristos 
18975fd0b74Schristos   filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr);
19075fd0b74Schristos }
19175fd0b74Schristos 
19275fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
19375fd0b74Schristos # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
19475fd0b74Schristos #elif defined COFF_WITH_pex64
19575fd0b74Schristos # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
19675fd0b74Schristos #elif defined COFF_WITH_pep
19775fd0b74Schristos # define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
19875fd0b74Schristos #else
19975fd0b74Schristos # define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
20075fd0b74Schristos #endif
20175fd0b74Schristos 
20275fd0b74Schristos static void
coff_swap_scnhdr_in(bfd * abfd,void * ext,void * in)20375fd0b74Schristos coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
20475fd0b74Schristos {
20575fd0b74Schristos   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
20675fd0b74Schristos   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
20775fd0b74Schristos 
20875fd0b74Schristos   memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
20975fd0b74Schristos 
21075fd0b74Schristos   scnhdr_int->s_vaddr   = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
21175fd0b74Schristos   scnhdr_int->s_paddr   = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
21275fd0b74Schristos   scnhdr_int->s_size    = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
21375fd0b74Schristos   scnhdr_int->s_scnptr  = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
21475fd0b74Schristos   scnhdr_int->s_relptr  = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
21575fd0b74Schristos   scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
21675fd0b74Schristos   scnhdr_int->s_flags   = H_GET_32 (abfd, scnhdr_ext->s_flags);
21775fd0b74Schristos 
21875fd0b74Schristos   /* MS handles overflow of line numbers by carrying into the reloc
21975fd0b74Schristos      field (it appears).  Since it's supposed to be zero for PE
22075fd0b74Schristos      *IMAGE* format, that's safe.  This is still a bit iffy.  */
22175fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
22275fd0b74Schristos   scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
22375fd0b74Schristos 			 + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
22475fd0b74Schristos   scnhdr_int->s_nreloc = 0;
22575fd0b74Schristos #else
22675fd0b74Schristos   scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
22775fd0b74Schristos   scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
22875fd0b74Schristos #endif
22975fd0b74Schristos 
23075fd0b74Schristos   if (scnhdr_int->s_vaddr != 0)
23175fd0b74Schristos     {
23275fd0b74Schristos       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
23375fd0b74Schristos       /* Do not cut upper 32-bits for 64-bit vma.  */
234*e992f068Schristos #if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
23575fd0b74Schristos       scnhdr_int->s_vaddr &= 0xffffffff;
23675fd0b74Schristos #endif
23775fd0b74Schristos     }
23875fd0b74Schristos 
23975fd0b74Schristos #ifndef COFF_NO_HACK_SCNHDR_SIZE
24075fd0b74Schristos   /* If this section holds uninitialized data and is from an object file
24175fd0b74Schristos      or from an executable image that has not initialized the field,
24275fd0b74Schristos      or if the image is an executable file and the physical size is padded,
24375fd0b74Schristos      use the virtual size (stored in s_paddr) instead.  */
24475fd0b74Schristos   if (scnhdr_int->s_paddr > 0
24575fd0b74Schristos       && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
24675fd0b74Schristos 	   && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
24775fd0b74Schristos 	  || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
24875fd0b74Schristos   /* This code used to set scnhdr_int->s_paddr to 0.  However,
24975fd0b74Schristos      coff_set_alignment_hook stores s_paddr in virt_size, which
25075fd0b74Schristos      only works if it correctly holds the virtual size of the
25175fd0b74Schristos      section.  */
25275fd0b74Schristos     scnhdr_int->s_size = scnhdr_int->s_paddr;
25375fd0b74Schristos #endif
25475fd0b74Schristos }
25575fd0b74Schristos 
256*e992f068Schristos static bool
pe_mkobject(bfd * abfd)25775fd0b74Schristos pe_mkobject (bfd * abfd)
25875fd0b74Schristos {
25975fd0b74Schristos   pe_data_type *pe;
260*e992f068Schristos   size_t amt = sizeof (pe_data_type);
26175fd0b74Schristos 
26275fd0b74Schristos   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
26375fd0b74Schristos 
26475fd0b74Schristos   if (abfd->tdata.pe_obj_data == 0)
265*e992f068Schristos     return false;
26675fd0b74Schristos 
26775fd0b74Schristos   pe = pe_data (abfd);
26875fd0b74Schristos 
26975fd0b74Schristos   pe->coff.pe = 1;
27075fd0b74Schristos 
27175fd0b74Schristos   /* in_reloc_p is architecture dependent.  */
27275fd0b74Schristos   pe->in_reloc_p = in_reloc_p;
27375fd0b74Schristos 
274012573ebSchristos   /* Default DOS message string.  */
275012573ebSchristos   pe->dos_message[0]  = 0x0eba1f0e;
276012573ebSchristos   pe->dos_message[1]  = 0xcd09b400;
277012573ebSchristos   pe->dos_message[2]  = 0x4c01b821;
278012573ebSchristos   pe->dos_message[3]  = 0x685421cd;
279012573ebSchristos   pe->dos_message[4]  = 0x70207369;
280012573ebSchristos   pe->dos_message[5]  = 0x72676f72;
281012573ebSchristos   pe->dos_message[6]  = 0x63206d61;
282012573ebSchristos   pe->dos_message[7]  = 0x6f6e6e61;
283012573ebSchristos   pe->dos_message[8]  = 0x65622074;
284012573ebSchristos   pe->dos_message[9]  = 0x6e757220;
285012573ebSchristos   pe->dos_message[10] = 0x206e6920;
286012573ebSchristos   pe->dos_message[11] = 0x20534f44;
287012573ebSchristos   pe->dos_message[12] = 0x65646f6d;
288012573ebSchristos   pe->dos_message[13] = 0x0a0d0d2e;
289012573ebSchristos   pe->dos_message[14] = 0x24;
290012573ebSchristos   pe->dos_message[15] = 0x0;
291012573ebSchristos 
29275fd0b74Schristos   memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
293*e992f068Schristos   return true;
29475fd0b74Schristos }
29575fd0b74Schristos 
29675fd0b74Schristos /* Create the COFF backend specific information.  */
29775fd0b74Schristos 
29875fd0b74Schristos static void *
pe_mkobject_hook(bfd * abfd,void * filehdr,void * aouthdr ATTRIBUTE_UNUSED)29975fd0b74Schristos pe_mkobject_hook (bfd * abfd,
30075fd0b74Schristos 		  void * filehdr,
30175fd0b74Schristos 		  void * aouthdr ATTRIBUTE_UNUSED)
30275fd0b74Schristos {
30375fd0b74Schristos   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
30475fd0b74Schristos   pe_data_type *pe;
30575fd0b74Schristos 
30675fd0b74Schristos   if (! pe_mkobject (abfd))
30775fd0b74Schristos     return NULL;
30875fd0b74Schristos 
30975fd0b74Schristos   pe = pe_data (abfd);
31075fd0b74Schristos   pe->coff.sym_filepos = internal_f->f_symptr;
31175fd0b74Schristos   /* These members communicate important constants about the symbol
31275fd0b74Schristos      table to GDB's symbol-reading code.  These `constants'
31375fd0b74Schristos      unfortunately vary among coff implementations...  */
31475fd0b74Schristos   pe->coff.local_n_btmask = N_BTMASK;
31575fd0b74Schristos   pe->coff.local_n_btshft = N_BTSHFT;
31675fd0b74Schristos   pe->coff.local_n_tmask = N_TMASK;
31775fd0b74Schristos   pe->coff.local_n_tshift = N_TSHIFT;
31875fd0b74Schristos   pe->coff.local_symesz = SYMESZ;
31975fd0b74Schristos   pe->coff.local_auxesz = AUXESZ;
32075fd0b74Schristos   pe->coff.local_linesz = LINESZ;
32175fd0b74Schristos 
32275fd0b74Schristos   pe->coff.timestamp = internal_f->f_timdat;
32375fd0b74Schristos 
32475fd0b74Schristos   obj_raw_syment_count (abfd) =
32575fd0b74Schristos     obj_conv_table_size (abfd) =
32675fd0b74Schristos       internal_f->f_nsyms;
32775fd0b74Schristos 
32875fd0b74Schristos   pe->real_flags = internal_f->f_flags;
32975fd0b74Schristos 
33075fd0b74Schristos   if ((internal_f->f_flags & F_DLL) != 0)
33175fd0b74Schristos     pe->dll = 1;
33275fd0b74Schristos 
33375fd0b74Schristos   if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
33475fd0b74Schristos     abfd->flags |= HAS_DEBUG;
33575fd0b74Schristos 
33675fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
33775fd0b74Schristos   if (aouthdr)
33875fd0b74Schristos     pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe;
33975fd0b74Schristos #endif
34075fd0b74Schristos 
34175fd0b74Schristos #ifdef ARM
34275fd0b74Schristos   if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
34375fd0b74Schristos     coff_data (abfd) ->flags = 0;
34475fd0b74Schristos #endif
34575fd0b74Schristos 
346012573ebSchristos   memcpy (pe->dos_message, internal_f->pe.dos_message,
347012573ebSchristos 	  sizeof (pe->dos_message));
348012573ebSchristos 
34975fd0b74Schristos   return (void *) pe;
35075fd0b74Schristos }
35175fd0b74Schristos 
352*e992f068Schristos static bool
pe_print_private_bfd_data(bfd * abfd,void * vfile)35375fd0b74Schristos pe_print_private_bfd_data (bfd *abfd, void * vfile)
35475fd0b74Schristos {
35575fd0b74Schristos   FILE *file = (FILE *) vfile;
35675fd0b74Schristos 
35775fd0b74Schristos   if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
358*e992f068Schristos     return false;
35975fd0b74Schristos 
36075fd0b74Schristos   if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
361*e992f068Schristos     return true;
36275fd0b74Schristos 
36375fd0b74Schristos   fputc ('\n', file);
36475fd0b74Schristos 
36575fd0b74Schristos   return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
36675fd0b74Schristos }
36775fd0b74Schristos 
36875fd0b74Schristos /* Copy any private info we understand from the input bfd
36975fd0b74Schristos    to the output bfd.  */
37075fd0b74Schristos 
371*e992f068Schristos static bool
pe_bfd_copy_private_bfd_data(bfd * ibfd,bfd * obfd)37275fd0b74Schristos pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
37375fd0b74Schristos {
37475fd0b74Schristos   /* PR binutils/716: Copy the large address aware flag.
37575fd0b74Schristos      XXX: Should we be copying other flags or other fields in the pe_data()
37675fd0b74Schristos      structure ?  */
37775fd0b74Schristos   if (pe_data (obfd) != NULL
37875fd0b74Schristos       && pe_data (ibfd) != NULL
37975fd0b74Schristos       && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
38075fd0b74Schristos     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
38175fd0b74Schristos 
38275fd0b74Schristos   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
383*e992f068Schristos     return false;
38475fd0b74Schristos 
38575fd0b74Schristos   if (pe_saved_coff_bfd_copy_private_bfd_data)
38675fd0b74Schristos     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
38775fd0b74Schristos 
388*e992f068Schristos   return true;
38975fd0b74Schristos }
39075fd0b74Schristos 
39175fd0b74Schristos #define coff_bfd_copy_private_section_data \
39275fd0b74Schristos   _bfd_XX_bfd_copy_private_section_data
39375fd0b74Schristos 
39475fd0b74Schristos #define coff_get_symbol_info _bfd_XX_get_symbol_info
39575fd0b74Schristos 
39675fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
39775fd0b74Schristos 
39875fd0b74Schristos /* Code to handle Microsoft's Image Library Format.
39975fd0b74Schristos    Also known as LINK6 format.
40075fd0b74Schristos    Documentation about this format can be found at:
40175fd0b74Schristos 
40275fd0b74Schristos    http://msdn.microsoft.com/library/specs/pecoff_section8.htm  */
40375fd0b74Schristos 
40475fd0b74Schristos /* The following constants specify the sizes of the various data
40575fd0b74Schristos    structures that we have to create in order to build a bfd describing
40675fd0b74Schristos    an ILF object file.  The final "+ 1" in the definitions of SIZEOF_IDATA6
40775fd0b74Schristos    and SIZEOF_IDATA7 below is to allow for the possibility that we might
40875fd0b74Schristos    need a padding byte in order to ensure 16 bit alignment for the section's
40975fd0b74Schristos    contents.
41075fd0b74Schristos 
41175fd0b74Schristos    The value for SIZEOF_ILF_STRINGS is computed as follows:
41275fd0b74Schristos 
41375fd0b74Schristos       There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
41475fd0b74Schristos       per symbol for their names (longest section name is .idata$x).
41575fd0b74Schristos 
41675fd0b74Schristos       There will be two symbols for the imported value, one the symbol name
41775fd0b74Schristos       and one with _imp__ prefixed.  Allowing for the terminating nul's this
41875fd0b74Schristos       is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
41975fd0b74Schristos 
42075fd0b74Schristos       The strings in the string table must start STRING__SIZE_SIZE bytes into
42175fd0b74Schristos       the table in order to for the string lookup code in coffgen/coffcode to
42275fd0b74Schristos       work.  */
42375fd0b74Schristos #define NUM_ILF_RELOCS		8
42475fd0b74Schristos #define NUM_ILF_SECTIONS	6
42575fd0b74Schristos #define NUM_ILF_SYMS		(2 + NUM_ILF_SECTIONS)
42675fd0b74Schristos 
42775fd0b74Schristos #define SIZEOF_ILF_SYMS		 (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
42875fd0b74Schristos #define SIZEOF_ILF_SYM_TABLE	 (NUM_ILF_SYMS * sizeof (* vars.sym_table))
42975fd0b74Schristos #define SIZEOF_ILF_NATIVE_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.native_syms))
43075fd0b74Schristos #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
43175fd0b74Schristos #define SIZEOF_ILF_EXT_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.esym_table))
43275fd0b74Schristos #define SIZEOF_ILF_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.reltab))
43375fd0b74Schristos #define SIZEOF_ILF_INT_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
43475fd0b74Schristos #define SIZEOF_ILF_STRINGS	 (strlen (symbol_name) * 2 + 8 \
43575fd0b74Schristos 					+ 21 + strlen (source_dll) \
43675fd0b74Schristos 					+ NUM_ILF_SECTIONS * 9 \
43775fd0b74Schristos 					+ STRING_SIZE_SIZE)
43875fd0b74Schristos #define SIZEOF_IDATA2		(5 * 4)
43975fd0b74Schristos 
44075fd0b74Schristos /* For PEx64 idata4 & 5 have thumb size of 8 bytes.  */
44175fd0b74Schristos #ifdef COFF_WITH_pex64
44275fd0b74Schristos #define SIZEOF_IDATA4		(2 * 4)
44375fd0b74Schristos #define SIZEOF_IDATA5		(2 * 4)
44475fd0b74Schristos #else
44575fd0b74Schristos #define SIZEOF_IDATA4		(1 * 4)
44675fd0b74Schristos #define SIZEOF_IDATA5		(1 * 4)
44775fd0b74Schristos #endif
44875fd0b74Schristos 
44975fd0b74Schristos #define SIZEOF_IDATA6		(2 + strlen (symbol_name) + 1 + 1)
45075fd0b74Schristos #define SIZEOF_IDATA7		(strlen (source_dll) + 1 + 1)
45175fd0b74Schristos #define SIZEOF_ILF_SECTIONS	(NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
45275fd0b74Schristos 
45375fd0b74Schristos #define ILF_DATA_SIZE				\
45475fd0b74Schristos     + SIZEOF_ILF_SYMS				\
45575fd0b74Schristos     + SIZEOF_ILF_SYM_TABLE			\
45675fd0b74Schristos     + SIZEOF_ILF_NATIVE_SYMS			\
45775fd0b74Schristos     + SIZEOF_ILF_SYM_PTR_TABLE			\
45875fd0b74Schristos     + SIZEOF_ILF_EXT_SYMS			\
45975fd0b74Schristos     + SIZEOF_ILF_RELOCS				\
46075fd0b74Schristos     + SIZEOF_ILF_INT_RELOCS			\
46175fd0b74Schristos     + SIZEOF_ILF_STRINGS			\
46275fd0b74Schristos     + SIZEOF_IDATA2				\
46375fd0b74Schristos     + SIZEOF_IDATA4				\
46475fd0b74Schristos     + SIZEOF_IDATA5				\
46575fd0b74Schristos     + SIZEOF_IDATA6				\
46675fd0b74Schristos     + SIZEOF_IDATA7				\
46775fd0b74Schristos     + SIZEOF_ILF_SECTIONS			\
46875fd0b74Schristos     + MAX_TEXT_SECTION_SIZE
46975fd0b74Schristos 
47075fd0b74Schristos /* Create an empty relocation against the given symbol.  */
47175fd0b74Schristos 
47275fd0b74Schristos static void
pe_ILF_make_a_symbol_reloc(pe_ILF_vars * vars,bfd_vma address,bfd_reloc_code_real_type reloc,struct bfd_symbol ** sym,unsigned int sym_index)47375fd0b74Schristos pe_ILF_make_a_symbol_reloc (pe_ILF_vars *		vars,
47475fd0b74Schristos 			    bfd_vma			address,
47575fd0b74Schristos 			    bfd_reloc_code_real_type	reloc,
47675fd0b74Schristos 			    struct bfd_symbol **	sym,
47775fd0b74Schristos 			    unsigned int		sym_index)
47875fd0b74Schristos {
47975fd0b74Schristos   arelent * entry;
48075fd0b74Schristos   struct internal_reloc * internal;
48175fd0b74Schristos 
48275fd0b74Schristos   entry = vars->reltab + vars->relcount;
48375fd0b74Schristos   internal = vars->int_reltab + vars->relcount;
48475fd0b74Schristos 
48575fd0b74Schristos   entry->address     = address;
48675fd0b74Schristos   entry->addend      = 0;
48775fd0b74Schristos   entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
48875fd0b74Schristos   entry->sym_ptr_ptr = sym;
48975fd0b74Schristos 
49075fd0b74Schristos   internal->r_vaddr  = address;
49175fd0b74Schristos   internal->r_symndx = sym_index;
492*e992f068Schristos   internal->r_type   = entry->howto ? entry->howto->type : 0;
49375fd0b74Schristos 
49475fd0b74Schristos   vars->relcount ++;
49575fd0b74Schristos 
49675fd0b74Schristos   BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
49775fd0b74Schristos }
49875fd0b74Schristos 
49975fd0b74Schristos /* Create an empty relocation against the given section.  */
50075fd0b74Schristos 
50175fd0b74Schristos static void
pe_ILF_make_a_reloc(pe_ILF_vars * vars,bfd_vma address,bfd_reloc_code_real_type reloc,asection_ptr sec)50275fd0b74Schristos pe_ILF_make_a_reloc (pe_ILF_vars *	       vars,
50375fd0b74Schristos 		     bfd_vma		       address,
50475fd0b74Schristos 		     bfd_reloc_code_real_type  reloc,
50575fd0b74Schristos 		     asection_ptr	       sec)
50675fd0b74Schristos {
50775fd0b74Schristos   pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
50875fd0b74Schristos 			      coff_section_data (vars->abfd, sec)->i);
50975fd0b74Schristos }
51075fd0b74Schristos 
51175fd0b74Schristos /* Move the queued relocs into the given section.  */
51275fd0b74Schristos 
51375fd0b74Schristos static void
pe_ILF_save_relocs(pe_ILF_vars * vars,asection_ptr sec)51475fd0b74Schristos pe_ILF_save_relocs (pe_ILF_vars * vars,
51575fd0b74Schristos 		    asection_ptr  sec)
51675fd0b74Schristos {
51775fd0b74Schristos   /* Make sure that there is somewhere to store the internal relocs.  */
51875fd0b74Schristos   if (coff_section_data (vars->abfd, sec) == NULL)
51975fd0b74Schristos     /* We should probably return an error indication here.  */
52075fd0b74Schristos     abort ();
52175fd0b74Schristos 
52275fd0b74Schristos   coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
523*e992f068Schristos   coff_section_data (vars->abfd, sec)->keep_relocs = true;
52475fd0b74Schristos 
52575fd0b74Schristos   sec->relocation  = vars->reltab;
52675fd0b74Schristos   sec->reloc_count = vars->relcount;
52775fd0b74Schristos   sec->flags      |= SEC_RELOC;
52875fd0b74Schristos 
52975fd0b74Schristos   vars->reltab     += vars->relcount;
53075fd0b74Schristos   vars->int_reltab += vars->relcount;
53175fd0b74Schristos   vars->relcount   = 0;
53275fd0b74Schristos 
53375fd0b74Schristos   BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
53475fd0b74Schristos }
53575fd0b74Schristos 
53675fd0b74Schristos /* Create a global symbol and add it to the relevant tables.  */
53775fd0b74Schristos 
53875fd0b74Schristos static void
pe_ILF_make_a_symbol(pe_ILF_vars * vars,const char * prefix,const char * symbol_name,asection_ptr section,flagword extra_flags)53975fd0b74Schristos pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
54075fd0b74Schristos 		      const char *   prefix,
54175fd0b74Schristos 		      const char *   symbol_name,
54275fd0b74Schristos 		      asection_ptr   section,
54375fd0b74Schristos 		      flagword       extra_flags)
54475fd0b74Schristos {
54575fd0b74Schristos   coff_symbol_type * sym;
54675fd0b74Schristos   combined_entry_type * ent;
54775fd0b74Schristos   SYMENT * esym;
54875fd0b74Schristos   unsigned short sclass;
54975fd0b74Schristos 
55075fd0b74Schristos   if (extra_flags & BSF_LOCAL)
55175fd0b74Schristos     sclass = C_STAT;
55275fd0b74Schristos   else
55375fd0b74Schristos     sclass = C_EXT;
55475fd0b74Schristos 
55575fd0b74Schristos #ifdef THUMBPEMAGIC
55675fd0b74Schristos   if (vars->magic == THUMBPEMAGIC)
55775fd0b74Schristos     {
55875fd0b74Schristos       if (extra_flags & BSF_FUNCTION)
55975fd0b74Schristos 	sclass = C_THUMBEXTFUNC;
56075fd0b74Schristos       else if (extra_flags & BSF_LOCAL)
56175fd0b74Schristos 	sclass = C_THUMBSTAT;
56275fd0b74Schristos       else
56375fd0b74Schristos 	sclass = C_THUMBEXT;
56475fd0b74Schristos     }
56575fd0b74Schristos #endif
56675fd0b74Schristos 
56775fd0b74Schristos   BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
56875fd0b74Schristos 
56975fd0b74Schristos   sym = vars->sym_ptr;
57075fd0b74Schristos   ent = vars->native_ptr;
57175fd0b74Schristos   esym = vars->esym_ptr;
57275fd0b74Schristos 
57375fd0b74Schristos   /* Copy the symbol's name into the string table.  */
57475fd0b74Schristos   sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
57575fd0b74Schristos 
57675fd0b74Schristos   if (section == NULL)
57775fd0b74Schristos     section = bfd_und_section_ptr;
57875fd0b74Schristos 
57975fd0b74Schristos   /* Initialise the external symbol.  */
58075fd0b74Schristos   H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
58175fd0b74Schristos 	    esym->e.e.e_offset);
58275fd0b74Schristos   H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
58375fd0b74Schristos   esym->e_sclass[0] = sclass;
58475fd0b74Schristos 
58575fd0b74Schristos   /* The following initialisations are unnecessary - the memory is
58675fd0b74Schristos      zero initialised.  They are just kept here as reminders.  */
58775fd0b74Schristos 
58875fd0b74Schristos   /* Initialise the internal symbol structure.  */
58975fd0b74Schristos   ent->u.syment.n_sclass	  = sclass;
59075fd0b74Schristos   ent->u.syment.n_scnum		  = section->target_index;
591*e992f068Schristos   ent->u.syment._n._n_n._n_offset = (uintptr_t) sym;
592*e992f068Schristos   ent->is_sym = true;
59375fd0b74Schristos 
59475fd0b74Schristos   sym->symbol.the_bfd = vars->abfd;
59575fd0b74Schristos   sym->symbol.name    = vars->string_ptr;
59675fd0b74Schristos   sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
59775fd0b74Schristos   sym->symbol.section = section;
59875fd0b74Schristos   sym->native	      = ent;
59975fd0b74Schristos 
60075fd0b74Schristos   * vars->table_ptr = vars->sym_index;
60175fd0b74Schristos   * vars->sym_ptr_ptr = sym;
60275fd0b74Schristos 
60375fd0b74Schristos   /* Adjust pointers for the next symbol.  */
60475fd0b74Schristos   vars->sym_index ++;
60575fd0b74Schristos   vars->sym_ptr ++;
60675fd0b74Schristos   vars->sym_ptr_ptr ++;
60775fd0b74Schristos   vars->table_ptr ++;
60875fd0b74Schristos   vars->native_ptr ++;
60975fd0b74Schristos   vars->esym_ptr ++;
61075fd0b74Schristos   vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
61175fd0b74Schristos 
61275fd0b74Schristos   BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
61375fd0b74Schristos }
61475fd0b74Schristos 
61575fd0b74Schristos /* Create a section.  */
61675fd0b74Schristos 
61775fd0b74Schristos static asection_ptr
pe_ILF_make_a_section(pe_ILF_vars * vars,const char * name,unsigned int size,flagword extra_flags)61875fd0b74Schristos pe_ILF_make_a_section (pe_ILF_vars * vars,
61975fd0b74Schristos 		       const char *  name,
62075fd0b74Schristos 		       unsigned int  size,
62175fd0b74Schristos 		       flagword      extra_flags)
62275fd0b74Schristos {
62375fd0b74Schristos   asection_ptr sec;
62475fd0b74Schristos   flagword     flags;
625*e992f068Schristos   intptr_t alignment;
62675fd0b74Schristos 
62775fd0b74Schristos   sec = bfd_make_section_old_way (vars->abfd, name);
62875fd0b74Schristos   if (sec == NULL)
62975fd0b74Schristos     return NULL;
63075fd0b74Schristos 
63175fd0b74Schristos   flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
63275fd0b74Schristos 
633012573ebSchristos   bfd_set_section_flags (sec, flags | extra_flags);
63475fd0b74Schristos 
635012573ebSchristos   bfd_set_section_alignment (sec, 2);
63675fd0b74Schristos 
63775fd0b74Schristos   /* Check that we will not run out of space.  */
63875fd0b74Schristos   BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
63975fd0b74Schristos 
64075fd0b74Schristos   /* Set the section size and contents.  The actual
64175fd0b74Schristos      contents are filled in by our parent.  */
642012573ebSchristos   bfd_set_section_size (sec, (bfd_size_type) size);
64375fd0b74Schristos   sec->contents = vars->data;
64475fd0b74Schristos   sec->target_index = vars->sec_index ++;
64575fd0b74Schristos 
64675fd0b74Schristos   /* Advance data pointer in the vars structure.  */
64775fd0b74Schristos   vars->data += size;
64875fd0b74Schristos 
64975fd0b74Schristos   /* Skip the padding byte if it was not needed.
65075fd0b74Schristos      The logic here is that if the string length is odd,
65175fd0b74Schristos      then the entire string length, including the null byte,
65275fd0b74Schristos      is even and so the extra, padding byte, is not needed.  */
65375fd0b74Schristos   if (size & 1)
65475fd0b74Schristos     vars->data --;
65575fd0b74Schristos 
65675fd0b74Schristos   /* PR 18758: See note in pe_ILF_buid_a_bfd.  We must make sure that we
657*e992f068Schristos      preserve host alignment requirements.  The BFD_ASSERTs in this
658*e992f068Schristos      functions will warn us if we run out of room, but we should
659*e992f068Schristos      already have enough padding built in to ILF_DATA_SIZE.  */
660*e992f068Schristos #if GCC_VERSION >= 3000
661*e992f068Schristos   alignment = __alignof__ (struct coff_section_tdata);
662*e992f068Schristos #else
663*e992f068Schristos   alignment = 8;
66475fd0b74Schristos #endif
665*e992f068Schristos   vars->data
666*e992f068Schristos     = (bfd_byte *) (((intptr_t) vars->data + alignment - 1) & -alignment);
667*e992f068Schristos 
66875fd0b74Schristos   /* Create a coff_section_tdata structure for our use.  */
66975fd0b74Schristos   sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
67075fd0b74Schristos   vars->data += sizeof (struct coff_section_tdata);
67175fd0b74Schristos 
67275fd0b74Schristos   BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
67375fd0b74Schristos 
67475fd0b74Schristos   /* Create a symbol to refer to this section.  */
67575fd0b74Schristos   pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
67675fd0b74Schristos 
67775fd0b74Schristos   /* Cache the index to the symbol in the coff_section_data structure.  */
67875fd0b74Schristos   coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
67975fd0b74Schristos 
68075fd0b74Schristos   return sec;
68175fd0b74Schristos }
68275fd0b74Schristos 
68375fd0b74Schristos /* This structure contains the code that goes into the .text section
68475fd0b74Schristos    in order to perform a jump into the DLL lookup table.  The entries
68575fd0b74Schristos    in the table are index by the magic number used to represent the
68675fd0b74Schristos    machine type in the PE file.  The contents of the data[] arrays in
68775fd0b74Schristos    these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
68875fd0b74Schristos    The SIZE field says how many bytes in the DATA array are actually
68975fd0b74Schristos    used.  The OFFSET field says where in the data array the address
69075fd0b74Schristos    of the .idata$5 section should be placed.  */
69175fd0b74Schristos #define MAX_TEXT_SECTION_SIZE 32
69275fd0b74Schristos 
69375fd0b74Schristos typedef struct
69475fd0b74Schristos {
69575fd0b74Schristos   unsigned short magic;
69675fd0b74Schristos   unsigned char  data[MAX_TEXT_SECTION_SIZE];
69775fd0b74Schristos   unsigned int   size;
69875fd0b74Schristos   unsigned int   offset;
69975fd0b74Schristos }
70075fd0b74Schristos jump_table;
70175fd0b74Schristos 
702*e992f068Schristos static const jump_table jtab[] =
70375fd0b74Schristos {
70475fd0b74Schristos #ifdef I386MAGIC
70575fd0b74Schristos   { I386MAGIC,
70675fd0b74Schristos     { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
70775fd0b74Schristos     8, 2
70875fd0b74Schristos   },
70975fd0b74Schristos #endif
71075fd0b74Schristos 
71175fd0b74Schristos #ifdef AMD64MAGIC
71275fd0b74Schristos   { AMD64MAGIC,
71375fd0b74Schristos     { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
71475fd0b74Schristos     8, 2
71575fd0b74Schristos   },
71675fd0b74Schristos #endif
71775fd0b74Schristos 
71875fd0b74Schristos #ifdef  MC68MAGIC
71975fd0b74Schristos   { MC68MAGIC,
72075fd0b74Schristos     { /* XXX fill me in */ },
72175fd0b74Schristos     0, 0
72275fd0b74Schristos   },
72375fd0b74Schristos #endif
72475fd0b74Schristos 
72575fd0b74Schristos #ifdef  MIPS_ARCH_MAGIC_WINCE
72675fd0b74Schristos   { MIPS_ARCH_MAGIC_WINCE,
72775fd0b74Schristos     { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
72875fd0b74Schristos       0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
72975fd0b74Schristos     16, 0
73075fd0b74Schristos   },
73175fd0b74Schristos #endif
73275fd0b74Schristos 
73375fd0b74Schristos #ifdef  SH_ARCH_MAGIC_WINCE
73475fd0b74Schristos   { SH_ARCH_MAGIC_WINCE,
73575fd0b74Schristos     { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
73675fd0b74Schristos       0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
73775fd0b74Schristos     12, 8
73875fd0b74Schristos   },
73975fd0b74Schristos #endif
74075fd0b74Schristos 
741*e992f068Schristos #ifdef AARCH64MAGIC
742*e992f068Schristos /* We don't currently support jumping to DLLs, so if
743*e992f068Schristos    someone does try emit a runtime trap.  Through UDF #0.  */
744*e992f068Schristos   { AARCH64MAGIC,
745*e992f068Schristos     { 0x00, 0x00, 0x00, 0x00 },
746*e992f068Schristos     4, 0
747*e992f068Schristos   },
748*e992f068Schristos 
749*e992f068Schristos #endif
750*e992f068Schristos 
75175fd0b74Schristos #ifdef  ARMPEMAGIC
75275fd0b74Schristos   { ARMPEMAGIC,
75375fd0b74Schristos     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
75475fd0b74Schristos       0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
75575fd0b74Schristos     12, 8
75675fd0b74Schristos   },
75775fd0b74Schristos #endif
75875fd0b74Schristos 
75975fd0b74Schristos #ifdef  THUMBPEMAGIC
76075fd0b74Schristos   { THUMBPEMAGIC,
76175fd0b74Schristos     { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
76275fd0b74Schristos       0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
76375fd0b74Schristos     16, 12
76475fd0b74Schristos   },
76575fd0b74Schristos #endif
76675fd0b74Schristos   { 0, { 0 }, 0, 0 }
76775fd0b74Schristos };
76875fd0b74Schristos 
76975fd0b74Schristos #ifndef NUM_ENTRIES
77075fd0b74Schristos #define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
77175fd0b74Schristos #endif
77275fd0b74Schristos 
77375fd0b74Schristos /* Build a full BFD from the information supplied in a ILF object.  */
77475fd0b74Schristos 
775*e992f068Schristos static bool
pe_ILF_build_a_bfd(bfd * abfd,unsigned int magic,char * symbol_name,char * source_dll,unsigned int ordinal,unsigned int types)77675fd0b74Schristos pe_ILF_build_a_bfd (bfd *	    abfd,
77775fd0b74Schristos 		    unsigned int    magic,
77875fd0b74Schristos 		    char *	    symbol_name,
77975fd0b74Schristos 		    char *	    source_dll,
78075fd0b74Schristos 		    unsigned int    ordinal,
78175fd0b74Schristos 		    unsigned int    types)
78275fd0b74Schristos {
78375fd0b74Schristos   bfd_byte *		   ptr;
78475fd0b74Schristos   pe_ILF_vars		   vars;
78575fd0b74Schristos   struct internal_filehdr  internal_f;
78675fd0b74Schristos   unsigned int		   import_type;
78775fd0b74Schristos   unsigned int		   import_name_type;
78875fd0b74Schristos   asection_ptr		   id4, id5, id6 = NULL, text = NULL;
78975fd0b74Schristos   coff_symbol_type **	   imp_sym;
79075fd0b74Schristos   unsigned int		   imp_index;
791*e992f068Schristos   intptr_t alignment;
79275fd0b74Schristos 
79375fd0b74Schristos   /* Decode and verify the types field of the ILF structure.  */
79475fd0b74Schristos   import_type = types & 0x3;
79575fd0b74Schristos   import_name_type = (types & 0x1c) >> 2;
79675fd0b74Schristos 
79775fd0b74Schristos   switch (import_type)
79875fd0b74Schristos     {
79975fd0b74Schristos     case IMPORT_CODE:
80075fd0b74Schristos     case IMPORT_DATA:
80175fd0b74Schristos       break;
80275fd0b74Schristos 
80375fd0b74Schristos     case IMPORT_CONST:
80475fd0b74Schristos       /* XXX code yet to be written.  */
805ede78133Schristos       /* xgettext:c-format */
806ede78133Schristos       _bfd_error_handler (_("%pB: unhandled import type; %x"),
80775fd0b74Schristos 			  abfd, import_type);
808*e992f068Schristos       return false;
80975fd0b74Schristos 
81075fd0b74Schristos     default:
811ede78133Schristos       /* xgettext:c-format */
812ede78133Schristos       _bfd_error_handler (_("%pB: unrecognized import type; %x"),
81375fd0b74Schristos 			  abfd, import_type);
814*e992f068Schristos       return false;
81575fd0b74Schristos     }
81675fd0b74Schristos 
81775fd0b74Schristos   switch (import_name_type)
81875fd0b74Schristos     {
81975fd0b74Schristos     case IMPORT_ORDINAL:
82075fd0b74Schristos     case IMPORT_NAME:
82175fd0b74Schristos     case IMPORT_NAME_NOPREFIX:
82275fd0b74Schristos     case IMPORT_NAME_UNDECORATE:
82375fd0b74Schristos       break;
82475fd0b74Schristos 
82575fd0b74Schristos     default:
826ede78133Schristos       /* xgettext:c-format */
827ede78133Schristos       _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
82875fd0b74Schristos 			  abfd, import_name_type);
829*e992f068Schristos       return false;
83075fd0b74Schristos     }
83175fd0b74Schristos 
83275fd0b74Schristos   /* Initialise local variables.
83375fd0b74Schristos 
83475fd0b74Schristos      Note these are kept in a structure rather than being
83575fd0b74Schristos      declared as statics since bfd frowns on global variables.
83675fd0b74Schristos 
83775fd0b74Schristos      We are going to construct the contents of the BFD in memory,
83875fd0b74Schristos      so allocate all the space that we will need right now.  */
83975fd0b74Schristos   vars.bim
84075fd0b74Schristos     = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
84175fd0b74Schristos   if (vars.bim == NULL)
842*e992f068Schristos     return false;
84375fd0b74Schristos 
84475fd0b74Schristos   ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
84575fd0b74Schristos   vars.bim->buffer = ptr;
84675fd0b74Schristos   vars.bim->size   = ILF_DATA_SIZE;
84775fd0b74Schristos   if (ptr == NULL)
84875fd0b74Schristos     goto error_return;
84975fd0b74Schristos 
85075fd0b74Schristos   /* Initialise the pointers to regions of the memory and the
85175fd0b74Schristos      other contents of the pe_ILF_vars structure as well.  */
85275fd0b74Schristos   vars.sym_cache = (coff_symbol_type *) ptr;
85375fd0b74Schristos   vars.sym_ptr   = (coff_symbol_type *) ptr;
85475fd0b74Schristos   vars.sym_index = 0;
85575fd0b74Schristos   ptr += SIZEOF_ILF_SYMS;
85675fd0b74Schristos 
85775fd0b74Schristos   vars.sym_table = (unsigned int *) ptr;
85875fd0b74Schristos   vars.table_ptr = (unsigned int *) ptr;
85975fd0b74Schristos   ptr += SIZEOF_ILF_SYM_TABLE;
86075fd0b74Schristos 
86175fd0b74Schristos   vars.native_syms = (combined_entry_type *) ptr;
86275fd0b74Schristos   vars.native_ptr  = (combined_entry_type *) ptr;
86375fd0b74Schristos   ptr += SIZEOF_ILF_NATIVE_SYMS;
86475fd0b74Schristos 
86575fd0b74Schristos   vars.sym_ptr_table = (coff_symbol_type **) ptr;
86675fd0b74Schristos   vars.sym_ptr_ptr   = (coff_symbol_type **) ptr;
86775fd0b74Schristos   ptr += SIZEOF_ILF_SYM_PTR_TABLE;
86875fd0b74Schristos 
86975fd0b74Schristos   vars.esym_table = (SYMENT *) ptr;
87075fd0b74Schristos   vars.esym_ptr   = (SYMENT *) ptr;
87175fd0b74Schristos   ptr += SIZEOF_ILF_EXT_SYMS;
87275fd0b74Schristos 
87375fd0b74Schristos   vars.reltab   = (arelent *) ptr;
87475fd0b74Schristos   vars.relcount = 0;
87575fd0b74Schristos   ptr += SIZEOF_ILF_RELOCS;
87675fd0b74Schristos 
87775fd0b74Schristos   vars.int_reltab  = (struct internal_reloc *) ptr;
87875fd0b74Schristos   ptr += SIZEOF_ILF_INT_RELOCS;
87975fd0b74Schristos 
88075fd0b74Schristos   vars.string_table = (char *) ptr;
88175fd0b74Schristos   vars.string_ptr   = (char *) ptr + STRING_SIZE_SIZE;
88275fd0b74Schristos   ptr += SIZEOF_ILF_STRINGS;
88375fd0b74Schristos   vars.end_string_ptr = (char *) ptr;
88475fd0b74Schristos 
88575fd0b74Schristos   /* The remaining space in bim->buffer is used
88675fd0b74Schristos      by the pe_ILF_make_a_section() function.  */
887*e992f068Schristos 
88875fd0b74Schristos   /* PR 18758: Make sure that the data area is sufficiently aligned for
889*e992f068Schristos      struct coff_section_tdata.  __alignof__ is a gcc extension, hence
890*e992f068Schristos      the test of GCC_VERSION.  For other compilers we assume 8 byte
891*e992f068Schristos      alignment.  */
892*e992f068Schristos #if GCC_VERSION >= 3000
893*e992f068Schristos   alignment = __alignof__ (struct coff_section_tdata);
894*e992f068Schristos #else
895*e992f068Schristos   alignment = 8;
89675fd0b74Schristos #endif
897*e992f068Schristos   ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
89875fd0b74Schristos 
89975fd0b74Schristos   vars.data = ptr;
90075fd0b74Schristos   vars.abfd = abfd;
90175fd0b74Schristos   vars.sec_index = 0;
90275fd0b74Schristos   vars.magic = magic;
90375fd0b74Schristos 
90475fd0b74Schristos   /* Create the initial .idata$<n> sections:
90575fd0b74Schristos      [.idata$2:  Import Directory Table -- not needed]
90675fd0b74Schristos      .idata$4:  Import Lookup Table
90775fd0b74Schristos      .idata$5:  Import Address Table
90875fd0b74Schristos 
90975fd0b74Schristos      Note we do not create a .idata$3 section as this is
91075fd0b74Schristos      created for us by the linker script.  */
91175fd0b74Schristos   id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
91275fd0b74Schristos   id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
91375fd0b74Schristos   if (id4 == NULL || id5 == NULL)
91475fd0b74Schristos     goto error_return;
91575fd0b74Schristos 
91675fd0b74Schristos   /* Fill in the contents of these sections.  */
91775fd0b74Schristos   if (import_name_type == IMPORT_ORDINAL)
91875fd0b74Schristos     {
91975fd0b74Schristos       if (ordinal == 0)
920ede78133Schristos 	/* See PR 20907 for a reproducer.  */
921ede78133Schristos 	goto error_return;
92275fd0b74Schristos 
923*e992f068Schristos #if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
92475fd0b74Schristos       ((unsigned int *) id4->contents)[0] = ordinal;
92575fd0b74Schristos       ((unsigned int *) id4->contents)[1] = 0x80000000;
92675fd0b74Schristos       ((unsigned int *) id5->contents)[0] = ordinal;
92775fd0b74Schristos       ((unsigned int *) id5->contents)[1] = 0x80000000;
92875fd0b74Schristos #else
92975fd0b74Schristos       * (unsigned int *) id4->contents = ordinal | 0x80000000;
93075fd0b74Schristos       * (unsigned int *) id5->contents = ordinal | 0x80000000;
93175fd0b74Schristos #endif
93275fd0b74Schristos     }
93375fd0b74Schristos   else
93475fd0b74Schristos     {
93575fd0b74Schristos       char * symbol;
93675fd0b74Schristos       unsigned int len;
93775fd0b74Schristos 
93875fd0b74Schristos       /* Create .idata$6 - the Hint Name Table.  */
93975fd0b74Schristos       id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
94075fd0b74Schristos       if (id6 == NULL)
94175fd0b74Schristos 	goto error_return;
94275fd0b74Schristos 
94375fd0b74Schristos       /* If necessary, trim the import symbol name.  */
94475fd0b74Schristos       symbol = symbol_name;
94575fd0b74Schristos 
94675fd0b74Schristos       /* As used by MS compiler, '_', '@', and '?' are alternative
94775fd0b74Schristos 	 forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
94875fd0b74Schristos 	 '@' used for fastcall (in C),  '_' everywhere else.  Only one
94975fd0b74Schristos 	 of these is used for a symbol.  We strip this leading char for
95075fd0b74Schristos 	 IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
95175fd0b74Schristos 	 PE COFF 6.0 spec (section 8.3, Import Name Type).  */
95275fd0b74Schristos 
95375fd0b74Schristos       if (import_name_type != IMPORT_NAME)
95475fd0b74Schristos 	{
95575fd0b74Schristos 	  char c = symbol[0];
95675fd0b74Schristos 
95775fd0b74Schristos 	  /* Check that we don't remove for targets with empty
95875fd0b74Schristos 	     USER_LABEL_PREFIX the leading underscore.  */
95975fd0b74Schristos 	  if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
96075fd0b74Schristos 	      || c == '@' || c == '?')
96175fd0b74Schristos 	    symbol++;
96275fd0b74Schristos 	}
96375fd0b74Schristos 
96475fd0b74Schristos       len = strlen (symbol);
96575fd0b74Schristos       if (import_name_type == IMPORT_NAME_UNDECORATE)
96675fd0b74Schristos 	{
96775fd0b74Schristos 	  /* Truncate at the first '@'.  */
96875fd0b74Schristos 	  char *at = strchr (symbol, '@');
96975fd0b74Schristos 
97075fd0b74Schristos 	  if (at != NULL)
97175fd0b74Schristos 	    len = at - symbol;
97275fd0b74Schristos 	}
97375fd0b74Schristos 
97475fd0b74Schristos       id6->contents[0] = ordinal & 0xff;
97575fd0b74Schristos       id6->contents[1] = ordinal >> 8;
97675fd0b74Schristos 
97775fd0b74Schristos       memcpy ((char *) id6->contents + 2, symbol, len);
97875fd0b74Schristos       id6->contents[len + 2] = '\0';
97975fd0b74Schristos     }
98075fd0b74Schristos 
98175fd0b74Schristos   if (import_name_type != IMPORT_ORDINAL)
98275fd0b74Schristos     {
98375fd0b74Schristos       pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
98475fd0b74Schristos       pe_ILF_save_relocs (&vars, id4);
98575fd0b74Schristos 
98675fd0b74Schristos       pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
98775fd0b74Schristos       pe_ILF_save_relocs (&vars, id5);
98875fd0b74Schristos     }
98975fd0b74Schristos 
99075fd0b74Schristos   /* Create an import symbol.  */
99175fd0b74Schristos   pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
99275fd0b74Schristos   imp_sym   = vars.sym_ptr_ptr - 1;
99375fd0b74Schristos   imp_index = vars.sym_index - 1;
99475fd0b74Schristos 
99575fd0b74Schristos   /* Create extra sections depending upon the type of import we are dealing with.  */
99675fd0b74Schristos   switch (import_type)
99775fd0b74Schristos     {
99875fd0b74Schristos       int i;
99975fd0b74Schristos 
100075fd0b74Schristos     case IMPORT_CODE:
100175fd0b74Schristos       /* CODE functions are special, in that they get a trampoline that
100275fd0b74Schristos 	 jumps to the main import symbol.  Create a .text section to hold it.
100375fd0b74Schristos 	 First we need to look up its contents in the jump table.  */
100475fd0b74Schristos       for (i = NUM_ENTRIES (jtab); i--;)
100575fd0b74Schristos 	{
100675fd0b74Schristos 	  if (jtab[i].size == 0)
100775fd0b74Schristos 	    continue;
100875fd0b74Schristos 	  if (jtab[i].magic == magic)
100975fd0b74Schristos 	    break;
101075fd0b74Schristos 	}
101175fd0b74Schristos       /* If we did not find a matching entry something is wrong.  */
101275fd0b74Schristos       if (i < 0)
101375fd0b74Schristos 	abort ();
101475fd0b74Schristos 
101575fd0b74Schristos       /* Create the .text section.  */
101675fd0b74Schristos       text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
101775fd0b74Schristos       if (text == NULL)
101875fd0b74Schristos 	goto error_return;
101975fd0b74Schristos 
102075fd0b74Schristos       /* Copy in the jump code.  */
102175fd0b74Schristos       memcpy (text->contents, jtab[i].data, jtab[i].size);
102275fd0b74Schristos 
102375fd0b74Schristos       /* Create a reloc for the data in the text section.  */
102475fd0b74Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
102575fd0b74Schristos       if (magic == MIPS_ARCH_MAGIC_WINCE)
102675fd0b74Schristos 	{
102775fd0b74Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
102875fd0b74Schristos 				      (struct bfd_symbol **) imp_sym,
102975fd0b74Schristos 				      imp_index);
103075fd0b74Schristos 	  pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
103175fd0b74Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
103275fd0b74Schristos 				      (struct bfd_symbol **) imp_sym,
103375fd0b74Schristos 				      imp_index);
103475fd0b74Schristos 	}
103575fd0b74Schristos       else
103675fd0b74Schristos #endif
103775fd0b74Schristos #ifdef AMD64MAGIC
103875fd0b74Schristos       if (magic == AMD64MAGIC)
103975fd0b74Schristos 	{
104075fd0b74Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
104175fd0b74Schristos 				      BFD_RELOC_32_PCREL, (asymbol **) imp_sym,
104275fd0b74Schristos 				      imp_index);
104375fd0b74Schristos 	}
104475fd0b74Schristos       else
104575fd0b74Schristos #endif
104675fd0b74Schristos 	pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
104775fd0b74Schristos 				    BFD_RELOC_32, (asymbol **) imp_sym,
104875fd0b74Schristos 				    imp_index);
104975fd0b74Schristos 
105075fd0b74Schristos       pe_ILF_save_relocs (& vars, text);
105175fd0b74Schristos       break;
105275fd0b74Schristos 
105375fd0b74Schristos     case IMPORT_DATA:
105475fd0b74Schristos       break;
105575fd0b74Schristos 
105675fd0b74Schristos     default:
105775fd0b74Schristos       /* XXX code not yet written.  */
105875fd0b74Schristos       abort ();
105975fd0b74Schristos     }
106075fd0b74Schristos 
106175fd0b74Schristos   /* Initialise the bfd.  */
106275fd0b74Schristos   memset (& internal_f, 0, sizeof (internal_f));
106375fd0b74Schristos 
106475fd0b74Schristos   internal_f.f_magic  = magic;
106575fd0b74Schristos   internal_f.f_symptr = 0;
106675fd0b74Schristos   internal_f.f_nsyms  = 0;
106775fd0b74Schristos   internal_f.f_flags  = F_AR32WR | F_LNNO; /* XXX is this correct ?  */
106875fd0b74Schristos 
106975fd0b74Schristos   if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
107075fd0b74Schristos       || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
107175fd0b74Schristos     goto error_return;
107275fd0b74Schristos 
107375fd0b74Schristos   if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
107475fd0b74Schristos     goto error_return;
107575fd0b74Schristos 
107675fd0b74Schristos   coff_data (abfd)->pe = 1;
107775fd0b74Schristos #ifdef THUMBPEMAGIC
107875fd0b74Schristos   if (vars.magic == THUMBPEMAGIC)
107975fd0b74Schristos     /* Stop some linker warnings about thumb code not supporting interworking.  */
108075fd0b74Schristos     coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
108175fd0b74Schristos #endif
108275fd0b74Schristos 
108375fd0b74Schristos   /* Switch from file contents to memory contents.  */
108475fd0b74Schristos   bfd_cache_close (abfd);
108575fd0b74Schristos 
108675fd0b74Schristos   abfd->iostream = (void *) vars.bim;
108775fd0b74Schristos   abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
108875fd0b74Schristos   abfd->iovec = &_bfd_memory_iovec;
108975fd0b74Schristos   abfd->where = 0;
109075fd0b74Schristos   abfd->origin = 0;
109175fd0b74Schristos   obj_sym_filepos (abfd) = 0;
109275fd0b74Schristos 
109375fd0b74Schristos   /* Now create a symbol describing the imported value.  */
109475fd0b74Schristos   switch (import_type)
109575fd0b74Schristos     {
109675fd0b74Schristos     case IMPORT_CODE:
109775fd0b74Schristos       pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
109875fd0b74Schristos 			    BSF_NOT_AT_END | BSF_FUNCTION);
109975fd0b74Schristos 
110075fd0b74Schristos       break;
110175fd0b74Schristos 
110275fd0b74Schristos     case IMPORT_DATA:
110375fd0b74Schristos       /* Nothing to do here.  */
110475fd0b74Schristos       break;
110575fd0b74Schristos 
110675fd0b74Schristos     default:
110775fd0b74Schristos       /* XXX code not yet written.  */
110875fd0b74Schristos       abort ();
110975fd0b74Schristos     }
111075fd0b74Schristos 
111175fd0b74Schristos   /* Create an import symbol for the DLL, without the .dll suffix.  */
111275fd0b74Schristos   ptr = (bfd_byte *) strrchr (source_dll, '.');
111375fd0b74Schristos   if (ptr)
111475fd0b74Schristos     * ptr = 0;
111575fd0b74Schristos   pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
111675fd0b74Schristos   if (ptr)
111775fd0b74Schristos     * ptr = '.';
111875fd0b74Schristos 
111975fd0b74Schristos   /* Point the bfd at the symbol table.  */
112075fd0b74Schristos   obj_symbols (abfd) = vars.sym_cache;
1121012573ebSchristos   abfd->symcount = vars.sym_index;
112275fd0b74Schristos 
112375fd0b74Schristos   obj_raw_syments (abfd) = vars.native_syms;
112475fd0b74Schristos   obj_raw_syment_count (abfd) = vars.sym_index;
112575fd0b74Schristos 
112675fd0b74Schristos   obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1127*e992f068Schristos   obj_coff_keep_syms (abfd) = true;
112875fd0b74Schristos 
112975fd0b74Schristos   obj_convert (abfd) = vars.sym_table;
113075fd0b74Schristos   obj_conv_table_size (abfd) = vars.sym_index;
113175fd0b74Schristos 
113275fd0b74Schristos   obj_coff_strings (abfd) = vars.string_table;
1133*e992f068Schristos   obj_coff_keep_strings (abfd) = true;
113475fd0b74Schristos 
113575fd0b74Schristos   abfd->flags |= HAS_SYMS;
113675fd0b74Schristos 
1137*e992f068Schristos   return true;
113875fd0b74Schristos 
113975fd0b74Schristos  error_return:
114075fd0b74Schristos   free (vars.bim->buffer);
114175fd0b74Schristos   free (vars.bim);
1142*e992f068Schristos   return false;
114375fd0b74Schristos }
114475fd0b74Schristos 
114575fd0b74Schristos /* We have detected a Image Library Format archive element.
114675fd0b74Schristos    Decode the element and return the appropriate target.  */
114775fd0b74Schristos 
1148*e992f068Schristos static bfd_cleanup
pe_ILF_object_p(bfd * abfd)114975fd0b74Schristos pe_ILF_object_p (bfd * abfd)
115075fd0b74Schristos {
115175fd0b74Schristos   bfd_byte	  buffer[14];
115275fd0b74Schristos   bfd_byte *	  ptr;
115375fd0b74Schristos   char *	  symbol_name;
115475fd0b74Schristos   char *	  source_dll;
115575fd0b74Schristos   unsigned int	  machine;
115675fd0b74Schristos   bfd_size_type	  size;
115775fd0b74Schristos   unsigned int	  ordinal;
115875fd0b74Schristos   unsigned int	  types;
115975fd0b74Schristos   unsigned int	  magic;
116075fd0b74Schristos 
116175fd0b74Schristos   /* Upon entry the first six bytes of the ILF header have
116275fd0b74Schristos       already been read.  Now read the rest of the header.  */
116375fd0b74Schristos   if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14)
116475fd0b74Schristos     return NULL;
116575fd0b74Schristos 
116675fd0b74Schristos   ptr = buffer;
116775fd0b74Schristos 
116875fd0b74Schristos   machine = H_GET_16 (abfd, ptr);
116975fd0b74Schristos   ptr += 2;
117075fd0b74Schristos 
117175fd0b74Schristos   /* Check that the machine type is recognised.  */
117275fd0b74Schristos   magic = 0;
117375fd0b74Schristos 
117475fd0b74Schristos   switch (machine)
117575fd0b74Schristos     {
117675fd0b74Schristos     case IMAGE_FILE_MACHINE_UNKNOWN:
117775fd0b74Schristos     case IMAGE_FILE_MACHINE_ALPHA:
117875fd0b74Schristos     case IMAGE_FILE_MACHINE_ALPHA64:
117975fd0b74Schristos     case IMAGE_FILE_MACHINE_IA64:
118075fd0b74Schristos       break;
118175fd0b74Schristos 
118275fd0b74Schristos     case IMAGE_FILE_MACHINE_I386:
118375fd0b74Schristos #ifdef I386MAGIC
118475fd0b74Schristos       magic = I386MAGIC;
118575fd0b74Schristos #endif
118675fd0b74Schristos       break;
118775fd0b74Schristos 
118875fd0b74Schristos     case IMAGE_FILE_MACHINE_AMD64:
118975fd0b74Schristos #ifdef AMD64MAGIC
119075fd0b74Schristos       magic = AMD64MAGIC;
119175fd0b74Schristos #endif
119275fd0b74Schristos       break;
119375fd0b74Schristos 
119475fd0b74Schristos     case IMAGE_FILE_MACHINE_R3000:
119575fd0b74Schristos     case IMAGE_FILE_MACHINE_R4000:
119675fd0b74Schristos     case IMAGE_FILE_MACHINE_R10000:
119775fd0b74Schristos 
119875fd0b74Schristos     case IMAGE_FILE_MACHINE_MIPS16:
119975fd0b74Schristos     case IMAGE_FILE_MACHINE_MIPSFPU:
120075fd0b74Schristos     case IMAGE_FILE_MACHINE_MIPSFPU16:
120175fd0b74Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
120275fd0b74Schristos       magic = MIPS_ARCH_MAGIC_WINCE;
120375fd0b74Schristos #endif
120475fd0b74Schristos       break;
120575fd0b74Schristos 
120675fd0b74Schristos     case IMAGE_FILE_MACHINE_SH3:
120775fd0b74Schristos     case IMAGE_FILE_MACHINE_SH4:
120875fd0b74Schristos #ifdef SH_ARCH_MAGIC_WINCE
120975fd0b74Schristos       magic = SH_ARCH_MAGIC_WINCE;
121075fd0b74Schristos #endif
121175fd0b74Schristos       break;
121275fd0b74Schristos 
121375fd0b74Schristos     case IMAGE_FILE_MACHINE_ARM:
121475fd0b74Schristos #ifdef ARMPEMAGIC
121575fd0b74Schristos       magic = ARMPEMAGIC;
121675fd0b74Schristos #endif
121775fd0b74Schristos       break;
121875fd0b74Schristos 
1219*e992f068Schristos     case IMAGE_FILE_MACHINE_ARM64:
1220*e992f068Schristos #ifdef AARCH64MAGIC
1221*e992f068Schristos       magic = AARCH64MAGIC;
1222*e992f068Schristos #endif
1223*e992f068Schristos       break;
1224*e992f068Schristos 
122575fd0b74Schristos     case IMAGE_FILE_MACHINE_THUMB:
122675fd0b74Schristos #ifdef THUMBPEMAGIC
122775fd0b74Schristos       {
122875fd0b74Schristos 	extern const bfd_target TARGET_LITTLE_SYM;
122975fd0b74Schristos 
123075fd0b74Schristos 	if (abfd->xvec == & TARGET_LITTLE_SYM)
123175fd0b74Schristos 	  magic = THUMBPEMAGIC;
123275fd0b74Schristos       }
123375fd0b74Schristos #endif
123475fd0b74Schristos       break;
123575fd0b74Schristos 
123675fd0b74Schristos     case IMAGE_FILE_MACHINE_POWERPC:
123775fd0b74Schristos       /* We no longer support PowerPC.  */
123875fd0b74Schristos     default:
123975fd0b74Schristos       _bfd_error_handler
1240ede78133Schristos 	/* xgettext:c-format */
1241ede78133Schristos 	(_("%pB: unrecognised machine type (0x%x)"
124275fd0b74Schristos 	   " in Import Library Format archive"),
124375fd0b74Schristos 	 abfd, machine);
124475fd0b74Schristos       bfd_set_error (bfd_error_malformed_archive);
124575fd0b74Schristos 
124675fd0b74Schristos       return NULL;
124775fd0b74Schristos       break;
124875fd0b74Schristos     }
124975fd0b74Schristos 
125075fd0b74Schristos   if (magic == 0)
125175fd0b74Schristos     {
125275fd0b74Schristos       _bfd_error_handler
1253ede78133Schristos 	/* xgettext:c-format */
1254ede78133Schristos 	(_("%pB: recognised but unhandled machine type (0x%x)"
125575fd0b74Schristos 	   " in Import Library Format archive"),
125675fd0b74Schristos 	 abfd, machine);
125775fd0b74Schristos       bfd_set_error (bfd_error_wrong_format);
125875fd0b74Schristos 
125975fd0b74Schristos       return NULL;
126075fd0b74Schristos     }
126175fd0b74Schristos 
126275fd0b74Schristos   /* We do not bother to check the date.
126375fd0b74Schristos      date = H_GET_32 (abfd, ptr);  */
126475fd0b74Schristos   ptr += 4;
126575fd0b74Schristos 
126675fd0b74Schristos   size = H_GET_32 (abfd, ptr);
126775fd0b74Schristos   ptr += 4;
126875fd0b74Schristos 
126975fd0b74Schristos   if (size == 0)
127075fd0b74Schristos     {
127175fd0b74Schristos       _bfd_error_handler
1272ede78133Schristos 	(_("%pB: size field is zero in Import Library Format header"), abfd);
127375fd0b74Schristos       bfd_set_error (bfd_error_malformed_archive);
127475fd0b74Schristos 
127575fd0b74Schristos       return NULL;
127675fd0b74Schristos     }
127775fd0b74Schristos 
127875fd0b74Schristos   ordinal = H_GET_16 (abfd, ptr);
127975fd0b74Schristos   ptr += 2;
128075fd0b74Schristos 
128175fd0b74Schristos   types = H_GET_16 (abfd, ptr);
128275fd0b74Schristos   /* ptr += 2; */
128375fd0b74Schristos 
128475fd0b74Schristos   /* Now read in the two strings that follow.  */
1285*e992f068Schristos   ptr = (bfd_byte *) _bfd_alloc_and_read (abfd, size, size);
128675fd0b74Schristos   if (ptr == NULL)
128775fd0b74Schristos     return NULL;
128875fd0b74Schristos 
128975fd0b74Schristos   symbol_name = (char *) ptr;
1290ede78133Schristos   /* See PR 20905 for an example of where the strnlen is necessary.  */
1291ede78133Schristos   source_dll  = symbol_name + strnlen (symbol_name, size - 1) + 1;
129275fd0b74Schristos 
129375fd0b74Schristos   /* Verify that the strings are null terminated.  */
129475fd0b74Schristos   if (ptr[size - 1] != 0
129575fd0b74Schristos       || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
129675fd0b74Schristos     {
129775fd0b74Schristos       _bfd_error_handler
1298ede78133Schristos 	(_("%pB: string not null terminated in ILF object file"), abfd);
129975fd0b74Schristos       bfd_set_error (bfd_error_malformed_archive);
130075fd0b74Schristos       bfd_release (abfd, ptr);
130175fd0b74Schristos       return NULL;
130275fd0b74Schristos     }
130375fd0b74Schristos 
130475fd0b74Schristos   /* Now construct the bfd.  */
130575fd0b74Schristos   if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
130675fd0b74Schristos 			    source_dll, ordinal, types))
130775fd0b74Schristos     {
130875fd0b74Schristos       bfd_release (abfd, ptr);
130975fd0b74Schristos       return NULL;
131075fd0b74Schristos     }
131175fd0b74Schristos 
1312*e992f068Schristos   return _bfd_no_cleanup;
131375fd0b74Schristos }
131475fd0b74Schristos 
131575fd0b74Schristos static void
pe_bfd_read_buildid(bfd * abfd)131675fd0b74Schristos pe_bfd_read_buildid (bfd *abfd)
131775fd0b74Schristos {
131875fd0b74Schristos   pe_data_type *pe = pe_data (abfd);
131975fd0b74Schristos   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
132075fd0b74Schristos   asection *section;
132175fd0b74Schristos   bfd_byte *data = 0;
132275fd0b74Schristos   bfd_size_type dataoff;
132375fd0b74Schristos   unsigned int i;
132475fd0b74Schristos   bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
132575fd0b74Schristos   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
132675fd0b74Schristos 
132775fd0b74Schristos   if (size == 0)
132875fd0b74Schristos     return;
132975fd0b74Schristos 
133075fd0b74Schristos   addr += extra->ImageBase;
133175fd0b74Schristos 
1332ede78133Schristos   /* Search for the section containing the DebugDirectory.  */
133375fd0b74Schristos   for (section = abfd->sections; section != NULL; section = section->next)
133475fd0b74Schristos     {
133575fd0b74Schristos       if ((addr >= section->vma) && (addr < (section->vma + section->size)))
133675fd0b74Schristos 	break;
133775fd0b74Schristos     }
133875fd0b74Schristos 
133975fd0b74Schristos   if (section == NULL)
134075fd0b74Schristos     return;
1341ede78133Schristos 
1342ede78133Schristos   if (!(section->flags & SEC_HAS_CONTENTS))
134375fd0b74Schristos     return;
134475fd0b74Schristos 
134575fd0b74Schristos   dataoff = addr - section->vma;
134675fd0b74Schristos 
1347ede78133Schristos   /* PR 20605 and 22373: Make sure that the data is really there.
1348ede78133Schristos      Note - since we are dealing with unsigned quantities we have
1349ede78133Schristos      to be careful to check for potential overflows.  */
1350ede78133Schristos   if (dataoff >= section->size
1351ede78133Schristos       || size > section->size - dataoff)
1352ede78133Schristos     {
1353ede78133Schristos       _bfd_error_handler
1354ede78133Schristos 	(_("%pB: error: debug data ends beyond end of debug directory"),
1355ede78133Schristos 	 abfd);
1356ede78133Schristos       return;
1357ede78133Schristos     }
1358ede78133Schristos 
135975fd0b74Schristos   /* Read the whole section. */
136075fd0b74Schristos   if (!bfd_malloc_and_get_section (abfd, section, &data))
136175fd0b74Schristos     {
136275fd0b74Schristos       free (data);
136375fd0b74Schristos       return;
136475fd0b74Schristos     }
136575fd0b74Schristos 
136675fd0b74Schristos   /* Search for a CodeView entry in the DebugDirectory */
136775fd0b74Schristos   for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
136875fd0b74Schristos     {
136975fd0b74Schristos       struct external_IMAGE_DEBUG_DIRECTORY *ext
137075fd0b74Schristos 	= &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
137175fd0b74Schristos       struct internal_IMAGE_DEBUG_DIRECTORY idd;
137275fd0b74Schristos 
137375fd0b74Schristos       _bfd_XXi_swap_debugdir_in (abfd, ext, &idd);
137475fd0b74Schristos 
137575fd0b74Schristos       if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
137675fd0b74Schristos 	{
137775fd0b74Schristos 	  char buffer[256 + 1];
137875fd0b74Schristos 	  CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
137975fd0b74Schristos 
138075fd0b74Schristos 	  /*
138175fd0b74Schristos 	    The debug entry doesn't have to have to be in a section, in which
138275fd0b74Schristos 	    case AddressOfRawData is 0, so always use PointerToRawData.
138375fd0b74Schristos 	  */
138475fd0b74Schristos 	  if (_bfd_XXi_slurp_codeview_record (abfd,
138575fd0b74Schristos 					      (file_ptr) idd.PointerToRawData,
138675fd0b74Schristos 					      idd.SizeOfData, cvinfo))
138775fd0b74Schristos 	    {
138875fd0b74Schristos 	      struct bfd_build_id* build_id = bfd_alloc (abfd,
138975fd0b74Schristos 			 sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
139075fd0b74Schristos 	      if (build_id)
139175fd0b74Schristos 		{
139275fd0b74Schristos 		  build_id->size = cvinfo->SignatureLength;
139375fd0b74Schristos 		  memcpy(build_id->data,  cvinfo->Signature,
139475fd0b74Schristos 			 cvinfo->SignatureLength);
139575fd0b74Schristos 		  abfd->build_id = build_id;
139675fd0b74Schristos 		}
139775fd0b74Schristos 	    }
139875fd0b74Schristos 	  break;
139975fd0b74Schristos 	}
140075fd0b74Schristos     }
1401012573ebSchristos 
1402012573ebSchristos   free (data);
140375fd0b74Schristos }
140475fd0b74Schristos 
1405*e992f068Schristos static bfd_cleanup
pe_bfd_object_p(bfd * abfd)140675fd0b74Schristos pe_bfd_object_p (bfd * abfd)
140775fd0b74Schristos {
140875fd0b74Schristos   bfd_byte buffer[6];
1409ede78133Schristos   struct external_DOS_hdr dos_hdr;
141075fd0b74Schristos   struct external_PEI_IMAGE_hdr image_hdr;
141175fd0b74Schristos   struct internal_filehdr internal_f;
141275fd0b74Schristos   struct internal_aouthdr internal_a;
1413*e992f068Schristos   bfd_size_type opt_hdr_size;
141475fd0b74Schristos   file_ptr offset;
1415*e992f068Schristos   bfd_cleanup result;
141675fd0b74Schristos 
141775fd0b74Schristos   /* Detect if this a Microsoft Import Library Format element.  */
141875fd0b74Schristos   /* First read the beginning of the header.  */
141975fd0b74Schristos   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
142075fd0b74Schristos       || bfd_bread (buffer, (bfd_size_type) 6, abfd) != 6)
142175fd0b74Schristos     {
142275fd0b74Schristos       if (bfd_get_error () != bfd_error_system_call)
142375fd0b74Schristos 	bfd_set_error (bfd_error_wrong_format);
142475fd0b74Schristos       return NULL;
142575fd0b74Schristos     }
142675fd0b74Schristos 
142775fd0b74Schristos   /* Then check the magic and the version (only 0 is supported).  */
142875fd0b74Schristos   if (H_GET_32 (abfd, buffer) == 0xffff0000
142975fd0b74Schristos       && H_GET_16 (abfd, buffer + 4) == 0)
143075fd0b74Schristos     return pe_ILF_object_p (abfd);
143175fd0b74Schristos 
143275fd0b74Schristos   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
143375fd0b74Schristos       || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
143475fd0b74Schristos 	 != sizeof (dos_hdr))
143575fd0b74Schristos     {
143675fd0b74Schristos       if (bfd_get_error () != bfd_error_system_call)
143775fd0b74Schristos 	bfd_set_error (bfd_error_wrong_format);
143875fd0b74Schristos       return NULL;
143975fd0b74Schristos     }
144075fd0b74Schristos 
144175fd0b74Schristos   /* There are really two magic numbers involved; the magic number
144275fd0b74Schristos      that says this is a NT executable (PEI) and the magic number that
1443ede78133Schristos      determines the architecture.  The former is IMAGE_DOS_SIGNATURE, stored in
144475fd0b74Schristos      the e_magic field.  The latter is stored in the f_magic field.
144575fd0b74Schristos      If the NT magic number isn't valid, the architecture magic number
144675fd0b74Schristos      could be mimicked by some other field (specifically, the number
144775fd0b74Schristos      of relocs in section 3).  Since this routine can only be called
144875fd0b74Schristos      correctly for a PEI file, check the e_magic number here, and, if
144975fd0b74Schristos      it doesn't match, clobber the f_magic number so that we don't get
145075fd0b74Schristos      a false match.  */
1451ede78133Schristos   if (H_GET_16 (abfd, dos_hdr.e_magic) != IMAGE_DOS_SIGNATURE)
145275fd0b74Schristos     {
145375fd0b74Schristos       bfd_set_error (bfd_error_wrong_format);
145475fd0b74Schristos       return NULL;
145575fd0b74Schristos     }
145675fd0b74Schristos 
145775fd0b74Schristos   offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
145875fd0b74Schristos   if (bfd_seek (abfd, offset, SEEK_SET) != 0
145975fd0b74Schristos       || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
146075fd0b74Schristos 	  != sizeof (image_hdr)))
146175fd0b74Schristos     {
146275fd0b74Schristos       if (bfd_get_error () != bfd_error_system_call)
146375fd0b74Schristos 	bfd_set_error (bfd_error_wrong_format);
146475fd0b74Schristos       return NULL;
146575fd0b74Schristos     }
146675fd0b74Schristos 
146775fd0b74Schristos   if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
146875fd0b74Schristos     {
146975fd0b74Schristos       bfd_set_error (bfd_error_wrong_format);
147075fd0b74Schristos       return NULL;
147175fd0b74Schristos     }
147275fd0b74Schristos 
147375fd0b74Schristos   /* Swap file header, so that we get the location for calling
147475fd0b74Schristos      real_object_p.  */
147575fd0b74Schristos   bfd_coff_swap_filehdr_in (abfd, &image_hdr, &internal_f);
147675fd0b74Schristos 
147775fd0b74Schristos   if (! bfd_coff_bad_format_hook (abfd, &internal_f)
147875fd0b74Schristos       || internal_f.f_opthdr > bfd_coff_aoutsz (abfd))
147975fd0b74Schristos     {
148075fd0b74Schristos       bfd_set_error (bfd_error_wrong_format);
148175fd0b74Schristos       return NULL;
148275fd0b74Schristos     }
148375fd0b74Schristos 
1484012573ebSchristos   memcpy (internal_f.pe.dos_message, dos_hdr.dos_message,
1485012573ebSchristos 	  sizeof (internal_f.pe.dos_message));
1486012573ebSchristos 
148775fd0b74Schristos   /* Read the optional header, which has variable size.  */
148875fd0b74Schristos   opt_hdr_size = internal_f.f_opthdr;
148975fd0b74Schristos 
149075fd0b74Schristos   if (opt_hdr_size != 0)
149175fd0b74Schristos     {
149275fd0b74Schristos       bfd_size_type amt = opt_hdr_size;
1493*e992f068Schristos       bfd_byte * opthdr;
149475fd0b74Schristos 
149575fd0b74Schristos       /* PR 17521 file: 230-131433-0.004.  */
149675fd0b74Schristos       if (amt < sizeof (PEAOUTHDR))
149775fd0b74Schristos 	amt = sizeof (PEAOUTHDR);
149875fd0b74Schristos 
1499*e992f068Schristos       opthdr = _bfd_alloc_and_read (abfd, amt, opt_hdr_size);
150075fd0b74Schristos       if (opthdr == NULL)
150175fd0b74Schristos 	return NULL;
1502*e992f068Schristos       if (amt > opt_hdr_size)
1503*e992f068Schristos 	memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
150475fd0b74Schristos 
150575fd0b74Schristos       bfd_set_error (bfd_error_no_error);
150675fd0b74Schristos       bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
150775fd0b74Schristos       if (bfd_get_error () != bfd_error_no_error)
150875fd0b74Schristos 	return NULL;
150975fd0b74Schristos     }
151075fd0b74Schristos 
151175fd0b74Schristos 
151275fd0b74Schristos   result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
151375fd0b74Schristos 			       (opt_hdr_size != 0
151475fd0b74Schristos 				? &internal_a
151575fd0b74Schristos 				: (struct internal_aouthdr *) NULL));
151675fd0b74Schristos 
151775fd0b74Schristos 
151875fd0b74Schristos   if (result)
151975fd0b74Schristos     {
152075fd0b74Schristos       /* Now the whole header has been processed, see if there is a build-id */
152175fd0b74Schristos       pe_bfd_read_buildid(abfd);
152275fd0b74Schristos     }
152375fd0b74Schristos 
152475fd0b74Schristos   return result;
152575fd0b74Schristos }
152675fd0b74Schristos 
152775fd0b74Schristos #define coff_object_p pe_bfd_object_p
152875fd0b74Schristos #endif /* COFF_IMAGE_WITH_PE */
1529