xref: /netbsd/external/gpl3/gdb/dist/bfd/peicode.h (revision 1424dfb3)
1377e23a2Schristos /* Support for the generic parts of PE/PEI, for BFD.
2*1424dfb3Schristos    Copyright (C) 1995-2020 Free Software Foundation, Inc.
3377e23a2Schristos    Written by Cygnus Solutions.
4377e23a2Schristos 
5377e23a2Schristos    This file is part of BFD, the Binary File Descriptor library.
6377e23a2Schristos 
7377e23a2Schristos    This program is free software; you can redistribute it and/or modify
8377e23a2Schristos    it under the terms of the GNU General Public License as published by
9377e23a2Schristos    the Free Software Foundation; either version 3 of the License, or
10377e23a2Schristos    (at your option) any later version.
11377e23a2Schristos 
12377e23a2Schristos    This program is distributed in the hope that it will be useful,
13377e23a2Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14377e23a2Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15377e23a2Schristos    GNU General Public License for more details.
16377e23a2Schristos 
17377e23a2Schristos    You should have received a copy of the GNU General Public License
18377e23a2Schristos    along with this program; if not, write to the Free Software
19377e23a2Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20377e23a2Schristos    MA 02110-1301, USA.  */
21377e23a2Schristos 
22377e23a2Schristos 
23377e23a2Schristos /* Most of this hacked by  Steve Chamberlain,
24377e23a2Schristos 			sac@cygnus.com
25377e23a2Schristos 
26377e23a2Schristos    PE/PEI rearrangement (and code added): Donn Terry
27377e23a2Schristos 				       Softway Systems, Inc.  */
28377e23a2Schristos 
29377e23a2Schristos /* Hey look, some documentation [and in a place you expect to find it]!
30377e23a2Schristos 
31377e23a2Schristos    The main reference for the pei format is "Microsoft Portable Executable
32377e23a2Schristos    and Common Object File Format Specification 4.1".  Get it if you need to
33377e23a2Schristos    do some serious hacking on this code.
34377e23a2Schristos 
35377e23a2Schristos    Another reference:
36377e23a2Schristos    "Peering Inside the PE: A Tour of the Win32 Portable Executable
37377e23a2Schristos    File Format", MSJ 1994, Volume 9.
38377e23a2Schristos 
39377e23a2Schristos    The *sole* difference between the pe format and the pei format is that the
40377e23a2Schristos    latter has an MSDOS 2.0 .exe header on the front that prints the message
41377e23a2Schristos    "This app must be run under Windows." (or some such).
42377e23a2Schristos    (FIXME: Whether that statement is *really* true or not is unknown.
43377e23a2Schristos    Are there more subtle differences between pe and pei formats?
44377e23a2Schristos    For now assume there aren't.  If you find one, then for God sakes
45377e23a2Schristos    document it here!)
46377e23a2Schristos 
47377e23a2Schristos    The Microsoft docs use the word "image" instead of "executable" because
48377e23a2Schristos    the former can also refer to a DLL (shared library).  Confusion can arise
49377e23a2Schristos    because the `i' in `pei' also refers to "image".  The `pe' format can
50377e23a2Schristos    also create images (i.e. executables), it's just that to run on a win32
51377e23a2Schristos    system you need to use the pei format.
52377e23a2Schristos 
53377e23a2Schristos    FIXME: Please add more docs here so the next poor fool that has to hack
54377e23a2Schristos    on this code has a chance of getting something accomplished without
55377e23a2Schristos    wasting too much time.  */
56377e23a2Schristos 
57377e23a2Schristos #include "libpei.h"
58377e23a2Schristos 
59377e23a2Schristos static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
60377e23a2Schristos #ifndef coff_bfd_print_private_bfd_data
61377e23a2Schristos      NULL;
62377e23a2Schristos #else
63377e23a2Schristos      coff_bfd_print_private_bfd_data;
64377e23a2Schristos #undef coff_bfd_print_private_bfd_data
65377e23a2Schristos #endif
66377e23a2Schristos 
67377e23a2Schristos static bfd_boolean			pe_print_private_bfd_data (bfd *, void *);
68377e23a2Schristos #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
69377e23a2Schristos 
70377e23a2Schristos static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
71377e23a2Schristos #ifndef coff_bfd_copy_private_bfd_data
72377e23a2Schristos      NULL;
73377e23a2Schristos #else
74377e23a2Schristos      coff_bfd_copy_private_bfd_data;
75377e23a2Schristos #undef coff_bfd_copy_private_bfd_data
76377e23a2Schristos #endif
77377e23a2Schristos 
78377e23a2Schristos static bfd_boolean		       pe_bfd_copy_private_bfd_data (bfd *, bfd *);
79377e23a2Schristos #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
80377e23a2Schristos 
81377e23a2Schristos #define coff_mkobject	   pe_mkobject
82377e23a2Schristos #define coff_mkobject_hook pe_mkobject_hook
83377e23a2Schristos 
84377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
85377e23a2Schristos /* This structure contains static variables used by the ILF code.  */
86377e23a2Schristos typedef asection * asection_ptr;
87377e23a2Schristos 
88377e23a2Schristos typedef struct
89377e23a2Schristos {
90377e23a2Schristos   bfd *			abfd;
91377e23a2Schristos   bfd_byte *		data;
92377e23a2Schristos   struct bfd_in_memory * bim;
93377e23a2Schristos   unsigned short	magic;
94377e23a2Schristos 
95377e23a2Schristos   arelent *		reltab;
96377e23a2Schristos   unsigned int		relcount;
97377e23a2Schristos 
98377e23a2Schristos   coff_symbol_type *	sym_cache;
99377e23a2Schristos   coff_symbol_type *	sym_ptr;
100377e23a2Schristos   unsigned int		sym_index;
101377e23a2Schristos 
102377e23a2Schristos   unsigned int *	sym_table;
103377e23a2Schristos   unsigned int *	table_ptr;
104377e23a2Schristos 
105377e23a2Schristos   combined_entry_type * native_syms;
106377e23a2Schristos   combined_entry_type * native_ptr;
107377e23a2Schristos 
108377e23a2Schristos   coff_symbol_type **	sym_ptr_table;
109377e23a2Schristos   coff_symbol_type **	sym_ptr_ptr;
110377e23a2Schristos 
111377e23a2Schristos   unsigned int		sec_index;
112377e23a2Schristos 
113377e23a2Schristos   char *		string_table;
114377e23a2Schristos   char *		string_ptr;
115377e23a2Schristos   char *		end_string_ptr;
116377e23a2Schristos 
117377e23a2Schristos   SYMENT *		esym_table;
118377e23a2Schristos   SYMENT *		esym_ptr;
119377e23a2Schristos 
120377e23a2Schristos   struct internal_reloc * int_reltab;
121377e23a2Schristos }
122377e23a2Schristos pe_ILF_vars;
123377e23a2Schristos #endif /* COFF_IMAGE_WITH_PE */
1247af5a897Schristos 
125*1424dfb3Schristos bfd_cleanup coff_real_object_p
1267af5a897Schristos   (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
127377e23a2Schristos 
128377e23a2Schristos #ifndef NO_COFF_RELOCS
129377e23a2Schristos static void
coff_swap_reloc_in(bfd * abfd,void * src,void * dst)130377e23a2Schristos coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
131377e23a2Schristos {
132377e23a2Schristos   RELOC *reloc_src = (RELOC *) src;
133377e23a2Schristos   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
134377e23a2Schristos 
135377e23a2Schristos   reloc_dst->r_vaddr  = H_GET_32 (abfd, reloc_src->r_vaddr);
136377e23a2Schristos   reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
137377e23a2Schristos   reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
138377e23a2Schristos #ifdef SWAP_IN_RELOC_OFFSET
139377e23a2Schristos   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
140377e23a2Schristos #endif
141377e23a2Schristos }
142377e23a2Schristos 
143377e23a2Schristos static unsigned int
coff_swap_reloc_out(bfd * abfd,void * src,void * dst)144377e23a2Schristos coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
145377e23a2Schristos {
146377e23a2Schristos   struct internal_reloc *reloc_src = (struct internal_reloc *) src;
147377e23a2Schristos   struct external_reloc *reloc_dst = (struct external_reloc *) dst;
148377e23a2Schristos 
149377e23a2Schristos   H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
150377e23a2Schristos   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
151377e23a2Schristos   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
152377e23a2Schristos 
153377e23a2Schristos #ifdef SWAP_OUT_RELOC_OFFSET
154377e23a2Schristos   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
155377e23a2Schristos #endif
156377e23a2Schristos #ifdef SWAP_OUT_RELOC_EXTRA
157377e23a2Schristos   SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
158377e23a2Schristos #endif
159377e23a2Schristos   return RELSZ;
160377e23a2Schristos }
161377e23a2Schristos #endif /* not NO_COFF_RELOCS */
162377e23a2Schristos 
1637af5a897Schristos #ifdef COFF_IMAGE_WITH_PE
1647af5a897Schristos #undef FILHDR
1657af5a897Schristos #define FILHDR struct external_PEI_IMAGE_hdr
1667af5a897Schristos #endif
1677af5a897Schristos 
168377e23a2Schristos static void
coff_swap_filehdr_in(bfd * abfd,void * src,void * dst)169377e23a2Schristos coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
170377e23a2Schristos {
171377e23a2Schristos   FILHDR *filehdr_src = (FILHDR *) src;
172377e23a2Schristos   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
173377e23a2Schristos 
174377e23a2Schristos   filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
175377e23a2Schristos   filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
176377e23a2Schristos   filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
177377e23a2Schristos   filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
178377e23a2Schristos   filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
179377e23a2Schristos   filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr);
180377e23a2Schristos 
181377e23a2Schristos   /* Other people's tools sometimes generate headers with an nsyms but
182377e23a2Schristos      a zero symptr.  */
183377e23a2Schristos   if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
184377e23a2Schristos     {
185377e23a2Schristos       filehdr_dst->f_nsyms = 0;
186377e23a2Schristos       filehdr_dst->f_flags |= F_LSYMS;
187377e23a2Schristos     }
188377e23a2Schristos 
189377e23a2Schristos   filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr);
190377e23a2Schristos }
191377e23a2Schristos 
192377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
193377e23a2Schristos # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
194377e23a2Schristos #elif defined COFF_WITH_pex64
195377e23a2Schristos # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
196377e23a2Schristos #elif defined COFF_WITH_pep
197377e23a2Schristos # define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
198377e23a2Schristos #else
199377e23a2Schristos # define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
200377e23a2Schristos #endif
201377e23a2Schristos 
202377e23a2Schristos static void
coff_swap_scnhdr_in(bfd * abfd,void * ext,void * in)203377e23a2Schristos coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
204377e23a2Schristos {
205377e23a2Schristos   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
206377e23a2Schristos   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
207377e23a2Schristos 
208377e23a2Schristos   memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
209377e23a2Schristos 
210377e23a2Schristos   scnhdr_int->s_vaddr   = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
211377e23a2Schristos   scnhdr_int->s_paddr   = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
212377e23a2Schristos   scnhdr_int->s_size    = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
213377e23a2Schristos   scnhdr_int->s_scnptr  = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
214377e23a2Schristos   scnhdr_int->s_relptr  = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
215377e23a2Schristos   scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
216377e23a2Schristos   scnhdr_int->s_flags   = H_GET_32 (abfd, scnhdr_ext->s_flags);
217377e23a2Schristos 
218377e23a2Schristos   /* MS handles overflow of line numbers by carrying into the reloc
219377e23a2Schristos      field (it appears).  Since it's supposed to be zero for PE
220377e23a2Schristos      *IMAGE* format, that's safe.  This is still a bit iffy.  */
221377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
222377e23a2Schristos   scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
223377e23a2Schristos 			 + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
224377e23a2Schristos   scnhdr_int->s_nreloc = 0;
225377e23a2Schristos #else
226377e23a2Schristos   scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
227377e23a2Schristos   scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
228377e23a2Schristos #endif
229377e23a2Schristos 
230377e23a2Schristos   if (scnhdr_int->s_vaddr != 0)
231377e23a2Schristos     {
232377e23a2Schristos       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
233377e23a2Schristos       /* Do not cut upper 32-bits for 64-bit vma.  */
234377e23a2Schristos #ifndef COFF_WITH_pex64
235377e23a2Schristos       scnhdr_int->s_vaddr &= 0xffffffff;
236377e23a2Schristos #endif
237377e23a2Schristos     }
238377e23a2Schristos 
239377e23a2Schristos #ifndef COFF_NO_HACK_SCNHDR_SIZE
240377e23a2Schristos   /* If this section holds uninitialized data and is from an object file
241377e23a2Schristos      or from an executable image that has not initialized the field,
242377e23a2Schristos      or if the image is an executable file and the physical size is padded,
243377e23a2Schristos      use the virtual size (stored in s_paddr) instead.  */
244377e23a2Schristos   if (scnhdr_int->s_paddr > 0
245377e23a2Schristos       && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
246377e23a2Schristos 	   && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
247377e23a2Schristos 	  || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
248377e23a2Schristos   /* This code used to set scnhdr_int->s_paddr to 0.  However,
249377e23a2Schristos      coff_set_alignment_hook stores s_paddr in virt_size, which
250377e23a2Schristos      only works if it correctly holds the virtual size of the
251377e23a2Schristos      section.  */
252377e23a2Schristos     scnhdr_int->s_size = scnhdr_int->s_paddr;
253377e23a2Schristos #endif
254377e23a2Schristos }
255377e23a2Schristos 
256377e23a2Schristos static bfd_boolean
pe_mkobject(bfd * abfd)257377e23a2Schristos pe_mkobject (bfd * abfd)
258377e23a2Schristos {
259377e23a2Schristos   pe_data_type *pe;
260*1424dfb3Schristos   size_t amt = sizeof (pe_data_type);
261377e23a2Schristos 
262377e23a2Schristos   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
263377e23a2Schristos 
264377e23a2Schristos   if (abfd->tdata.pe_obj_data == 0)
265377e23a2Schristos     return FALSE;
266377e23a2Schristos 
267377e23a2Schristos   pe = pe_data (abfd);
268377e23a2Schristos 
269377e23a2Schristos   pe->coff.pe = 1;
270377e23a2Schristos 
271377e23a2Schristos   /* in_reloc_p is architecture dependent.  */
272377e23a2Schristos   pe->in_reloc_p = in_reloc_p;
273377e23a2Schristos 
274*1424dfb3Schristos   /* Default DOS message string.  */
275*1424dfb3Schristos   pe->dos_message[0]  = 0x0eba1f0e;
276*1424dfb3Schristos   pe->dos_message[1]  = 0xcd09b400;
277*1424dfb3Schristos   pe->dos_message[2]  = 0x4c01b821;
278*1424dfb3Schristos   pe->dos_message[3]  = 0x685421cd;
279*1424dfb3Schristos   pe->dos_message[4]  = 0x70207369;
280*1424dfb3Schristos   pe->dos_message[5]  = 0x72676f72;
281*1424dfb3Schristos   pe->dos_message[6]  = 0x63206d61;
282*1424dfb3Schristos   pe->dos_message[7]  = 0x6f6e6e61;
283*1424dfb3Schristos   pe->dos_message[8]  = 0x65622074;
284*1424dfb3Schristos   pe->dos_message[9]  = 0x6e757220;
285*1424dfb3Schristos   pe->dos_message[10] = 0x206e6920;
286*1424dfb3Schristos   pe->dos_message[11] = 0x20534f44;
287*1424dfb3Schristos   pe->dos_message[12] = 0x65646f6d;
288*1424dfb3Schristos   pe->dos_message[13] = 0x0a0d0d2e;
289*1424dfb3Schristos   pe->dos_message[14] = 0x24;
290*1424dfb3Schristos   pe->dos_message[15] = 0x0;
291*1424dfb3Schristos 
2925e098073Schristos   memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
293377e23a2Schristos   return TRUE;
294377e23a2Schristos }
295377e23a2Schristos 
296377e23a2Schristos /* Create the COFF backend specific information.  */
297377e23a2Schristos 
298377e23a2Schristos static void *
pe_mkobject_hook(bfd * abfd,void * filehdr,void * aouthdr ATTRIBUTE_UNUSED)299377e23a2Schristos pe_mkobject_hook (bfd * abfd,
300377e23a2Schristos 		  void * filehdr,
301377e23a2Schristos 		  void * aouthdr ATTRIBUTE_UNUSED)
302377e23a2Schristos {
303377e23a2Schristos   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
304377e23a2Schristos   pe_data_type *pe;
305377e23a2Schristos 
306377e23a2Schristos   if (! pe_mkobject (abfd))
307377e23a2Schristos     return NULL;
308377e23a2Schristos 
309377e23a2Schristos   pe = pe_data (abfd);
310377e23a2Schristos   pe->coff.sym_filepos = internal_f->f_symptr;
311377e23a2Schristos   /* These members communicate important constants about the symbol
312377e23a2Schristos      table to GDB's symbol-reading code.  These `constants'
313377e23a2Schristos      unfortunately vary among coff implementations...  */
314377e23a2Schristos   pe->coff.local_n_btmask = N_BTMASK;
315377e23a2Schristos   pe->coff.local_n_btshft = N_BTSHFT;
316377e23a2Schristos   pe->coff.local_n_tmask = N_TMASK;
317377e23a2Schristos   pe->coff.local_n_tshift = N_TSHIFT;
318377e23a2Schristos   pe->coff.local_symesz = SYMESZ;
319377e23a2Schristos   pe->coff.local_auxesz = AUXESZ;
320377e23a2Schristos   pe->coff.local_linesz = LINESZ;
321377e23a2Schristos 
322377e23a2Schristos   pe->coff.timestamp = internal_f->f_timdat;
323377e23a2Schristos 
324377e23a2Schristos   obj_raw_syment_count (abfd) =
325377e23a2Schristos     obj_conv_table_size (abfd) =
326377e23a2Schristos       internal_f->f_nsyms;
327377e23a2Schristos 
328377e23a2Schristos   pe->real_flags = internal_f->f_flags;
329377e23a2Schristos 
330377e23a2Schristos   if ((internal_f->f_flags & F_DLL) != 0)
331377e23a2Schristos     pe->dll = 1;
332377e23a2Schristos 
333377e23a2Schristos   if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
334377e23a2Schristos     abfd->flags |= HAS_DEBUG;
335377e23a2Schristos 
336377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
337377e23a2Schristos   if (aouthdr)
338377e23a2Schristos     pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe;
339377e23a2Schristos #endif
340377e23a2Schristos 
341377e23a2Schristos #ifdef ARM
342377e23a2Schristos   if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
343377e23a2Schristos     coff_data (abfd) ->flags = 0;
344377e23a2Schristos #endif
345377e23a2Schristos 
346*1424dfb3Schristos   memcpy (pe->dos_message, internal_f->pe.dos_message,
347*1424dfb3Schristos 	  sizeof (pe->dos_message));
348*1424dfb3Schristos 
349377e23a2Schristos   return (void *) pe;
350377e23a2Schristos }
351377e23a2Schristos 
352377e23a2Schristos static bfd_boolean
pe_print_private_bfd_data(bfd * abfd,void * vfile)353377e23a2Schristos pe_print_private_bfd_data (bfd *abfd, void * vfile)
354377e23a2Schristos {
355377e23a2Schristos   FILE *file = (FILE *) vfile;
356377e23a2Schristos 
357377e23a2Schristos   if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
358377e23a2Schristos     return FALSE;
359377e23a2Schristos 
360377e23a2Schristos   if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
361377e23a2Schristos     return TRUE;
362377e23a2Schristos 
363377e23a2Schristos   fputc ('\n', file);
364377e23a2Schristos 
365377e23a2Schristos   return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
366377e23a2Schristos }
367377e23a2Schristos 
368377e23a2Schristos /* Copy any private info we understand from the input bfd
369377e23a2Schristos    to the output bfd.  */
370377e23a2Schristos 
371377e23a2Schristos static bfd_boolean
pe_bfd_copy_private_bfd_data(bfd * ibfd,bfd * obfd)372377e23a2Schristos pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
373377e23a2Schristos {
374377e23a2Schristos   /* PR binutils/716: Copy the large address aware flag.
375377e23a2Schristos      XXX: Should we be copying other flags or other fields in the pe_data()
376377e23a2Schristos      structure ?  */
377377e23a2Schristos   if (pe_data (obfd) != NULL
378377e23a2Schristos       && pe_data (ibfd) != NULL
379377e23a2Schristos       && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
380377e23a2Schristos     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
381377e23a2Schristos 
382377e23a2Schristos   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
383377e23a2Schristos     return FALSE;
384377e23a2Schristos 
385377e23a2Schristos   if (pe_saved_coff_bfd_copy_private_bfd_data)
386377e23a2Schristos     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
387377e23a2Schristos 
388377e23a2Schristos   return TRUE;
389377e23a2Schristos }
390377e23a2Schristos 
391377e23a2Schristos #define coff_bfd_copy_private_section_data \
392377e23a2Schristos   _bfd_XX_bfd_copy_private_section_data
393377e23a2Schristos 
394377e23a2Schristos #define coff_get_symbol_info _bfd_XX_get_symbol_info
395377e23a2Schristos 
396377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
397377e23a2Schristos 
398377e23a2Schristos /* Code to handle Microsoft's Image Library Format.
399377e23a2Schristos    Also known as LINK6 format.
400377e23a2Schristos    Documentation about this format can be found at:
401377e23a2Schristos 
402377e23a2Schristos    http://msdn.microsoft.com/library/specs/pecoff_section8.htm  */
403377e23a2Schristos 
404377e23a2Schristos /* The following constants specify the sizes of the various data
405377e23a2Schristos    structures that we have to create in order to build a bfd describing
406377e23a2Schristos    an ILF object file.  The final "+ 1" in the definitions of SIZEOF_IDATA6
407377e23a2Schristos    and SIZEOF_IDATA7 below is to allow for the possibility that we might
408377e23a2Schristos    need a padding byte in order to ensure 16 bit alignment for the section's
409377e23a2Schristos    contents.
410377e23a2Schristos 
411377e23a2Schristos    The value for SIZEOF_ILF_STRINGS is computed as follows:
412377e23a2Schristos 
413377e23a2Schristos       There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
414377e23a2Schristos       per symbol for their names (longest section name is .idata$x).
415377e23a2Schristos 
416377e23a2Schristos       There will be two symbols for the imported value, one the symbol name
417377e23a2Schristos       and one with _imp__ prefixed.  Allowing for the terminating nul's this
418377e23a2Schristos       is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
419377e23a2Schristos 
420377e23a2Schristos       The strings in the string table must start STRING__SIZE_SIZE bytes into
421377e23a2Schristos       the table in order to for the string lookup code in coffgen/coffcode to
422377e23a2Schristos       work.  */
423377e23a2Schristos #define NUM_ILF_RELOCS		8
424377e23a2Schristos #define NUM_ILF_SECTIONS	6
425377e23a2Schristos #define NUM_ILF_SYMS		(2 + NUM_ILF_SECTIONS)
426377e23a2Schristos 
427377e23a2Schristos #define SIZEOF_ILF_SYMS		 (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
428377e23a2Schristos #define SIZEOF_ILF_SYM_TABLE	 (NUM_ILF_SYMS * sizeof (* vars.sym_table))
429377e23a2Schristos #define SIZEOF_ILF_NATIVE_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.native_syms))
430377e23a2Schristos #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
431377e23a2Schristos #define SIZEOF_ILF_EXT_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.esym_table))
432377e23a2Schristos #define SIZEOF_ILF_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.reltab))
433377e23a2Schristos #define SIZEOF_ILF_INT_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
434377e23a2Schristos #define SIZEOF_ILF_STRINGS	 (strlen (symbol_name) * 2 + 8 \
435377e23a2Schristos 					+ 21 + strlen (source_dll) \
436377e23a2Schristos 					+ NUM_ILF_SECTIONS * 9 \
437377e23a2Schristos 					+ STRING_SIZE_SIZE)
438377e23a2Schristos #define SIZEOF_IDATA2		(5 * 4)
439377e23a2Schristos 
440377e23a2Schristos /* For PEx64 idata4 & 5 have thumb size of 8 bytes.  */
441377e23a2Schristos #ifdef COFF_WITH_pex64
442377e23a2Schristos #define SIZEOF_IDATA4		(2 * 4)
443377e23a2Schristos #define SIZEOF_IDATA5		(2 * 4)
444377e23a2Schristos #else
445377e23a2Schristos #define SIZEOF_IDATA4		(1 * 4)
446377e23a2Schristos #define SIZEOF_IDATA5		(1 * 4)
447377e23a2Schristos #endif
448377e23a2Schristos 
449377e23a2Schristos #define SIZEOF_IDATA6		(2 + strlen (symbol_name) + 1 + 1)
450377e23a2Schristos #define SIZEOF_IDATA7		(strlen (source_dll) + 1 + 1)
451377e23a2Schristos #define SIZEOF_ILF_SECTIONS	(NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
452377e23a2Schristos 
453377e23a2Schristos #define ILF_DATA_SIZE				\
454377e23a2Schristos     + SIZEOF_ILF_SYMS				\
455377e23a2Schristos     + SIZEOF_ILF_SYM_TABLE			\
456377e23a2Schristos     + SIZEOF_ILF_NATIVE_SYMS			\
457377e23a2Schristos     + SIZEOF_ILF_SYM_PTR_TABLE			\
458377e23a2Schristos     + SIZEOF_ILF_EXT_SYMS			\
459377e23a2Schristos     + SIZEOF_ILF_RELOCS				\
460377e23a2Schristos     + SIZEOF_ILF_INT_RELOCS			\
461377e23a2Schristos     + SIZEOF_ILF_STRINGS			\
462377e23a2Schristos     + SIZEOF_IDATA2				\
463377e23a2Schristos     + SIZEOF_IDATA4				\
464377e23a2Schristos     + SIZEOF_IDATA5				\
465377e23a2Schristos     + SIZEOF_IDATA6				\
466377e23a2Schristos     + SIZEOF_IDATA7				\
467377e23a2Schristos     + SIZEOF_ILF_SECTIONS			\
468377e23a2Schristos     + MAX_TEXT_SECTION_SIZE
469377e23a2Schristos 
470377e23a2Schristos /* Create an empty relocation against the given symbol.  */
471377e23a2Schristos 
472377e23a2Schristos 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)473377e23a2Schristos pe_ILF_make_a_symbol_reloc (pe_ILF_vars *		vars,
474377e23a2Schristos 			    bfd_vma			address,
475377e23a2Schristos 			    bfd_reloc_code_real_type	reloc,
476377e23a2Schristos 			    struct bfd_symbol **	sym,
477377e23a2Schristos 			    unsigned int		sym_index)
478377e23a2Schristos {
479377e23a2Schristos   arelent * entry;
480377e23a2Schristos   struct internal_reloc * internal;
481377e23a2Schristos 
482377e23a2Schristos   entry = vars->reltab + vars->relcount;
483377e23a2Schristos   internal = vars->int_reltab + vars->relcount;
484377e23a2Schristos 
485377e23a2Schristos   entry->address     = address;
486377e23a2Schristos   entry->addend      = 0;
487377e23a2Schristos   entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
488377e23a2Schristos   entry->sym_ptr_ptr = sym;
489377e23a2Schristos 
490377e23a2Schristos   internal->r_vaddr  = address;
491377e23a2Schristos   internal->r_symndx = sym_index;
492377e23a2Schristos   internal->r_type   = entry->howto->type;
493377e23a2Schristos 
494377e23a2Schristos   vars->relcount ++;
495377e23a2Schristos 
496377e23a2Schristos   BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
497377e23a2Schristos }
498377e23a2Schristos 
499377e23a2Schristos /* Create an empty relocation against the given section.  */
500377e23a2Schristos 
501377e23a2Schristos static void
pe_ILF_make_a_reloc(pe_ILF_vars * vars,bfd_vma address,bfd_reloc_code_real_type reloc,asection_ptr sec)502377e23a2Schristos pe_ILF_make_a_reloc (pe_ILF_vars *	       vars,
503377e23a2Schristos 		     bfd_vma		       address,
504377e23a2Schristos 		     bfd_reloc_code_real_type  reloc,
505377e23a2Schristos 		     asection_ptr	       sec)
506377e23a2Schristos {
507377e23a2Schristos   pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
508377e23a2Schristos 			      coff_section_data (vars->abfd, sec)->i);
509377e23a2Schristos }
510377e23a2Schristos 
511377e23a2Schristos /* Move the queued relocs into the given section.  */
512377e23a2Schristos 
513377e23a2Schristos static void
pe_ILF_save_relocs(pe_ILF_vars * vars,asection_ptr sec)514377e23a2Schristos pe_ILF_save_relocs (pe_ILF_vars * vars,
515377e23a2Schristos 		    asection_ptr  sec)
516377e23a2Schristos {
517377e23a2Schristos   /* Make sure that there is somewhere to store the internal relocs.  */
518377e23a2Schristos   if (coff_section_data (vars->abfd, sec) == NULL)
519377e23a2Schristos     /* We should probably return an error indication here.  */
520377e23a2Schristos     abort ();
521377e23a2Schristos 
522377e23a2Schristos   coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
523377e23a2Schristos   coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
524377e23a2Schristos 
525377e23a2Schristos   sec->relocation  = vars->reltab;
526377e23a2Schristos   sec->reloc_count = vars->relcount;
527377e23a2Schristos   sec->flags      |= SEC_RELOC;
528377e23a2Schristos 
529377e23a2Schristos   vars->reltab     += vars->relcount;
530377e23a2Schristos   vars->int_reltab += vars->relcount;
531377e23a2Schristos   vars->relcount   = 0;
532377e23a2Schristos 
533377e23a2Schristos   BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
534377e23a2Schristos }
535377e23a2Schristos 
536377e23a2Schristos /* Create a global symbol and add it to the relevant tables.  */
537377e23a2Schristos 
538377e23a2Schristos static void
pe_ILF_make_a_symbol(pe_ILF_vars * vars,const char * prefix,const char * symbol_name,asection_ptr section,flagword extra_flags)539377e23a2Schristos pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
540377e23a2Schristos 		      const char *   prefix,
541377e23a2Schristos 		      const char *   symbol_name,
542377e23a2Schristos 		      asection_ptr   section,
543377e23a2Schristos 		      flagword       extra_flags)
544377e23a2Schristos {
545377e23a2Schristos   coff_symbol_type * sym;
546377e23a2Schristos   combined_entry_type * ent;
547377e23a2Schristos   SYMENT * esym;
548377e23a2Schristos   unsigned short sclass;
549377e23a2Schristos 
550377e23a2Schristos   if (extra_flags & BSF_LOCAL)
551377e23a2Schristos     sclass = C_STAT;
552377e23a2Schristos   else
553377e23a2Schristos     sclass = C_EXT;
554377e23a2Schristos 
555377e23a2Schristos #ifdef THUMBPEMAGIC
556377e23a2Schristos   if (vars->magic == THUMBPEMAGIC)
557377e23a2Schristos     {
558377e23a2Schristos       if (extra_flags & BSF_FUNCTION)
559377e23a2Schristos 	sclass = C_THUMBEXTFUNC;
560377e23a2Schristos       else if (extra_flags & BSF_LOCAL)
561377e23a2Schristos 	sclass = C_THUMBSTAT;
562377e23a2Schristos       else
563377e23a2Schristos 	sclass = C_THUMBEXT;
564377e23a2Schristos     }
565377e23a2Schristos #endif
566377e23a2Schristos 
567377e23a2Schristos   BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
568377e23a2Schristos 
569377e23a2Schristos   sym = vars->sym_ptr;
570377e23a2Schristos   ent = vars->native_ptr;
571377e23a2Schristos   esym = vars->esym_ptr;
572377e23a2Schristos 
573377e23a2Schristos   /* Copy the symbol's name into the string table.  */
574377e23a2Schristos   sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
575377e23a2Schristos 
576377e23a2Schristos   if (section == NULL)
57748596154Schristos     section = bfd_und_section_ptr;
578377e23a2Schristos 
579377e23a2Schristos   /* Initialise the external symbol.  */
580377e23a2Schristos   H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
581377e23a2Schristos 	    esym->e.e.e_offset);
582377e23a2Schristos   H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
583377e23a2Schristos   esym->e_sclass[0] = sclass;
584377e23a2Schristos 
585377e23a2Schristos   /* The following initialisations are unnecessary - the memory is
586377e23a2Schristos      zero initialised.  They are just kept here as reminders.  */
587377e23a2Schristos 
588377e23a2Schristos   /* Initialise the internal symbol structure.  */
589377e23a2Schristos   ent->u.syment.n_sclass	  = sclass;
590377e23a2Schristos   ent->u.syment.n_scnum		  = section->target_index;
591377e23a2Schristos   ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
5925e098073Schristos   ent->is_sym = TRUE;
593377e23a2Schristos 
594377e23a2Schristos   sym->symbol.the_bfd = vars->abfd;
595377e23a2Schristos   sym->symbol.name    = vars->string_ptr;
596377e23a2Schristos   sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
597377e23a2Schristos   sym->symbol.section = section;
598377e23a2Schristos   sym->native	      = ent;
599377e23a2Schristos 
600377e23a2Schristos   * vars->table_ptr = vars->sym_index;
601377e23a2Schristos   * vars->sym_ptr_ptr = sym;
602377e23a2Schristos 
603377e23a2Schristos   /* Adjust pointers for the next symbol.  */
604377e23a2Schristos   vars->sym_index ++;
605377e23a2Schristos   vars->sym_ptr ++;
606377e23a2Schristos   vars->sym_ptr_ptr ++;
607377e23a2Schristos   vars->table_ptr ++;
608377e23a2Schristos   vars->native_ptr ++;
609377e23a2Schristos   vars->esym_ptr ++;
610377e23a2Schristos   vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
611377e23a2Schristos 
612377e23a2Schristos   BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
613377e23a2Schristos }
614377e23a2Schristos 
615377e23a2Schristos /* Create a section.  */
616377e23a2Schristos 
617377e23a2Schristos static asection_ptr
pe_ILF_make_a_section(pe_ILF_vars * vars,const char * name,unsigned int size,flagword extra_flags)618377e23a2Schristos pe_ILF_make_a_section (pe_ILF_vars * vars,
619377e23a2Schristos 		       const char *  name,
620377e23a2Schristos 		       unsigned int  size,
621377e23a2Schristos 		       flagword      extra_flags)
622377e23a2Schristos {
623377e23a2Schristos   asection_ptr sec;
624377e23a2Schristos   flagword     flags;
625*1424dfb3Schristos   intptr_t alignment;
626377e23a2Schristos 
627377e23a2Schristos   sec = bfd_make_section_old_way (vars->abfd, name);
628377e23a2Schristos   if (sec == NULL)
629377e23a2Schristos     return NULL;
630377e23a2Schristos 
631377e23a2Schristos   flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
632377e23a2Schristos 
633*1424dfb3Schristos   bfd_set_section_flags (sec, flags | extra_flags);
634377e23a2Schristos 
635*1424dfb3Schristos   bfd_set_section_alignment (sec, 2);
636377e23a2Schristos 
637377e23a2Schristos   /* Check that we will not run out of space.  */
638377e23a2Schristos   BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
639377e23a2Schristos 
640377e23a2Schristos   /* Set the section size and contents.  The actual
641377e23a2Schristos      contents are filled in by our parent.  */
642*1424dfb3Schristos   bfd_set_section_size (sec, (bfd_size_type) size);
643377e23a2Schristos   sec->contents = vars->data;
644377e23a2Schristos   sec->target_index = vars->sec_index ++;
645377e23a2Schristos 
646377e23a2Schristos   /* Advance data pointer in the vars structure.  */
647377e23a2Schristos   vars->data += size;
648377e23a2Schristos 
649377e23a2Schristos   /* Skip the padding byte if it was not needed.
650377e23a2Schristos      The logic here is that if the string length is odd,
651377e23a2Schristos      then the entire string length, including the null byte,
652377e23a2Schristos      is even and so the extra, padding byte, is not needed.  */
653377e23a2Schristos   if (size & 1)
654377e23a2Schristos     vars->data --;
655377e23a2Schristos 
656c03b94e9Schristos   /* PR 18758: See note in pe_ILF_buid_a_bfd.  We must make sure that we
657*1424dfb3Schristos      preserve host alignment requirements.  The BFD_ASSERTs in this
658*1424dfb3Schristos      functions will warn us if we run out of room, but we should
659*1424dfb3Schristos      already have enough padding built in to ILF_DATA_SIZE.  */
660*1424dfb3Schristos #if GCC_VERSION >= 3000
661*1424dfb3Schristos   alignment = __alignof__ (struct coff_section_tdata);
662*1424dfb3Schristos #else
663*1424dfb3Schristos   alignment = 8;
664c03b94e9Schristos #endif
665*1424dfb3Schristos   vars->data
666*1424dfb3Schristos     = (bfd_byte *) (((intptr_t) vars->data + alignment - 1) & -alignment);
667*1424dfb3Schristos 
668377e23a2Schristos   /* Create a coff_section_tdata structure for our use.  */
669377e23a2Schristos   sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
670377e23a2Schristos   vars->data += sizeof (struct coff_section_tdata);
671377e23a2Schristos 
672377e23a2Schristos   BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
673377e23a2Schristos 
674377e23a2Schristos   /* Create a symbol to refer to this section.  */
675377e23a2Schristos   pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
676377e23a2Schristos 
677377e23a2Schristos   /* Cache the index to the symbol in the coff_section_data structure.  */
678377e23a2Schristos   coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
679377e23a2Schristos 
680377e23a2Schristos   return sec;
681377e23a2Schristos }
682377e23a2Schristos 
683377e23a2Schristos /* This structure contains the code that goes into the .text section
684377e23a2Schristos    in order to perform a jump into the DLL lookup table.  The entries
685377e23a2Schristos    in the table are index by the magic number used to represent the
686377e23a2Schristos    machine type in the PE file.  The contents of the data[] arrays in
687377e23a2Schristos    these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
688377e23a2Schristos    The SIZE field says how many bytes in the DATA array are actually
689377e23a2Schristos    used.  The OFFSET field says where in the data array the address
690377e23a2Schristos    of the .idata$5 section should be placed.  */
691377e23a2Schristos #define MAX_TEXT_SECTION_SIZE 32
692377e23a2Schristos 
693377e23a2Schristos typedef struct
694377e23a2Schristos {
695377e23a2Schristos   unsigned short magic;
696377e23a2Schristos   unsigned char  data[MAX_TEXT_SECTION_SIZE];
697377e23a2Schristos   unsigned int   size;
698377e23a2Schristos   unsigned int   offset;
699377e23a2Schristos }
700377e23a2Schristos jump_table;
701377e23a2Schristos 
702377e23a2Schristos static jump_table jtab[] =
703377e23a2Schristos {
704377e23a2Schristos #ifdef I386MAGIC
705377e23a2Schristos   { I386MAGIC,
706377e23a2Schristos     { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
707377e23a2Schristos     8, 2
708377e23a2Schristos   },
709377e23a2Schristos #endif
710377e23a2Schristos 
711377e23a2Schristos #ifdef AMD64MAGIC
712377e23a2Schristos   { AMD64MAGIC,
713377e23a2Schristos     { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
714377e23a2Schristos     8, 2
715377e23a2Schristos   },
716377e23a2Schristos #endif
717377e23a2Schristos 
718377e23a2Schristos #ifdef  MC68MAGIC
719377e23a2Schristos   { MC68MAGIC,
720377e23a2Schristos     { /* XXX fill me in */ },
721377e23a2Schristos     0, 0
722377e23a2Schristos   },
723377e23a2Schristos #endif
724377e23a2Schristos 
725377e23a2Schristos #ifdef  MIPS_ARCH_MAGIC_WINCE
726377e23a2Schristos   { MIPS_ARCH_MAGIC_WINCE,
727377e23a2Schristos     { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
728377e23a2Schristos       0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
729377e23a2Schristos     16, 0
730377e23a2Schristos   },
731377e23a2Schristos #endif
732377e23a2Schristos 
733377e23a2Schristos #ifdef  SH_ARCH_MAGIC_WINCE
734377e23a2Schristos   { SH_ARCH_MAGIC_WINCE,
735377e23a2Schristos     { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
736377e23a2Schristos       0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
737377e23a2Schristos     12, 8
738377e23a2Schristos   },
739377e23a2Schristos #endif
740377e23a2Schristos 
741377e23a2Schristos #ifdef  ARMPEMAGIC
742377e23a2Schristos   { ARMPEMAGIC,
743377e23a2Schristos     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
744377e23a2Schristos       0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
745377e23a2Schristos     12, 8
746377e23a2Schristos   },
747377e23a2Schristos #endif
748377e23a2Schristos 
749377e23a2Schristos #ifdef  THUMBPEMAGIC
750377e23a2Schristos   { THUMBPEMAGIC,
751377e23a2Schristos     { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
752377e23a2Schristos       0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
753377e23a2Schristos     16, 12
754377e23a2Schristos   },
755377e23a2Schristos #endif
756377e23a2Schristos   { 0, { 0 }, 0, 0 }
757377e23a2Schristos };
758377e23a2Schristos 
759377e23a2Schristos #ifndef NUM_ENTRIES
760377e23a2Schristos #define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
761377e23a2Schristos #endif
762377e23a2Schristos 
763377e23a2Schristos /* Build a full BFD from the information supplied in a ILF object.  */
764377e23a2Schristos 
765377e23a2Schristos static bfd_boolean
pe_ILF_build_a_bfd(bfd * abfd,unsigned int magic,char * symbol_name,char * source_dll,unsigned int ordinal,unsigned int types)766377e23a2Schristos pe_ILF_build_a_bfd (bfd *	    abfd,
767377e23a2Schristos 		    unsigned int    magic,
768377e23a2Schristos 		    char *	    symbol_name,
769377e23a2Schristos 		    char *	    source_dll,
770377e23a2Schristos 		    unsigned int    ordinal,
771377e23a2Schristos 		    unsigned int    types)
772377e23a2Schristos {
773377e23a2Schristos   bfd_byte *		   ptr;
774377e23a2Schristos   pe_ILF_vars		   vars;
775377e23a2Schristos   struct internal_filehdr  internal_f;
776377e23a2Schristos   unsigned int		   import_type;
777377e23a2Schristos   unsigned int		   import_name_type;
778377e23a2Schristos   asection_ptr		   id4, id5, id6 = NULL, text = NULL;
779377e23a2Schristos   coff_symbol_type **	   imp_sym;
780377e23a2Schristos   unsigned int		   imp_index;
781*1424dfb3Schristos   intptr_t alignment;
782377e23a2Schristos 
783377e23a2Schristos   /* Decode and verify the types field of the ILF structure.  */
784377e23a2Schristos   import_type = types & 0x3;
785377e23a2Schristos   import_name_type = (types & 0x1c) >> 2;
786377e23a2Schristos 
787377e23a2Schristos   switch (import_type)
788377e23a2Schristos     {
789377e23a2Schristos     case IMPORT_CODE:
790377e23a2Schristos     case IMPORT_DATA:
791377e23a2Schristos       break;
792377e23a2Schristos 
793377e23a2Schristos     case IMPORT_CONST:
794377e23a2Schristos       /* XXX code yet to be written.  */
7951c468f90Schristos       /* xgettext:c-format */
79607163879Schristos       _bfd_error_handler (_("%pB: unhandled import type; %x"),
797377e23a2Schristos 			  abfd, import_type);
798377e23a2Schristos       return FALSE;
799377e23a2Schristos 
800377e23a2Schristos     default:
8011c468f90Schristos       /* xgettext:c-format */
80207163879Schristos       _bfd_error_handler (_("%pB: unrecognized import type; %x"),
803377e23a2Schristos 			  abfd, import_type);
804377e23a2Schristos       return FALSE;
805377e23a2Schristos     }
806377e23a2Schristos 
807377e23a2Schristos   switch (import_name_type)
808377e23a2Schristos     {
809377e23a2Schristos     case IMPORT_ORDINAL:
810377e23a2Schristos     case IMPORT_NAME:
811377e23a2Schristos     case IMPORT_NAME_NOPREFIX:
812377e23a2Schristos     case IMPORT_NAME_UNDECORATE:
813377e23a2Schristos       break;
814377e23a2Schristos 
815377e23a2Schristos     default:
8161c468f90Schristos       /* xgettext:c-format */
81707163879Schristos       _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
818377e23a2Schristos 			  abfd, import_name_type);
819377e23a2Schristos       return FALSE;
820377e23a2Schristos     }
821377e23a2Schristos 
822377e23a2Schristos   /* Initialise local variables.
823377e23a2Schristos 
824377e23a2Schristos      Note these are kept in a structure rather than being
825377e23a2Schristos      declared as statics since bfd frowns on global variables.
826377e23a2Schristos 
827377e23a2Schristos      We are going to construct the contents of the BFD in memory,
828377e23a2Schristos      so allocate all the space that we will need right now.  */
829377e23a2Schristos   vars.bim
830377e23a2Schristos     = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
831377e23a2Schristos   if (vars.bim == NULL)
832377e23a2Schristos     return FALSE;
833377e23a2Schristos 
834377e23a2Schristos   ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
835377e23a2Schristos   vars.bim->buffer = ptr;
836377e23a2Schristos   vars.bim->size   = ILF_DATA_SIZE;
837377e23a2Schristos   if (ptr == NULL)
838377e23a2Schristos     goto error_return;
839377e23a2Schristos 
840377e23a2Schristos   /* Initialise the pointers to regions of the memory and the
841377e23a2Schristos      other contents of the pe_ILF_vars structure as well.  */
842377e23a2Schristos   vars.sym_cache = (coff_symbol_type *) ptr;
843377e23a2Schristos   vars.sym_ptr   = (coff_symbol_type *) ptr;
844377e23a2Schristos   vars.sym_index = 0;
845377e23a2Schristos   ptr += SIZEOF_ILF_SYMS;
846377e23a2Schristos 
847377e23a2Schristos   vars.sym_table = (unsigned int *) ptr;
848377e23a2Schristos   vars.table_ptr = (unsigned int *) ptr;
849377e23a2Schristos   ptr += SIZEOF_ILF_SYM_TABLE;
850377e23a2Schristos 
851377e23a2Schristos   vars.native_syms = (combined_entry_type *) ptr;
852377e23a2Schristos   vars.native_ptr  = (combined_entry_type *) ptr;
853377e23a2Schristos   ptr += SIZEOF_ILF_NATIVE_SYMS;
854377e23a2Schristos 
855377e23a2Schristos   vars.sym_ptr_table = (coff_symbol_type **) ptr;
856377e23a2Schristos   vars.sym_ptr_ptr   = (coff_symbol_type **) ptr;
857377e23a2Schristos   ptr += SIZEOF_ILF_SYM_PTR_TABLE;
858377e23a2Schristos 
859377e23a2Schristos   vars.esym_table = (SYMENT *) ptr;
860377e23a2Schristos   vars.esym_ptr   = (SYMENT *) ptr;
861377e23a2Schristos   ptr += SIZEOF_ILF_EXT_SYMS;
862377e23a2Schristos 
863377e23a2Schristos   vars.reltab   = (arelent *) ptr;
864377e23a2Schristos   vars.relcount = 0;
865377e23a2Schristos   ptr += SIZEOF_ILF_RELOCS;
866377e23a2Schristos 
867377e23a2Schristos   vars.int_reltab  = (struct internal_reloc *) ptr;
868377e23a2Schristos   ptr += SIZEOF_ILF_INT_RELOCS;
869377e23a2Schristos 
870377e23a2Schristos   vars.string_table = (char *) ptr;
871377e23a2Schristos   vars.string_ptr   = (char *) ptr + STRING_SIZE_SIZE;
872377e23a2Schristos   ptr += SIZEOF_ILF_STRINGS;
873377e23a2Schristos   vars.end_string_ptr = (char *) ptr;
874377e23a2Schristos 
875377e23a2Schristos   /* The remaining space in bim->buffer is used
876377e23a2Schristos      by the pe_ILF_make_a_section() function.  */
877*1424dfb3Schristos 
878c03b94e9Schristos   /* PR 18758: Make sure that the data area is sufficiently aligned for
879*1424dfb3Schristos      struct coff_section_tdata.  __alignof__ is a gcc extension, hence
880*1424dfb3Schristos      the test of GCC_VERSION.  For other compilers we assume 8 byte
881*1424dfb3Schristos      alignment.  */
882*1424dfb3Schristos #if GCC_VERSION >= 3000
883*1424dfb3Schristos   alignment = __alignof__ (struct coff_section_tdata);
884*1424dfb3Schristos #else
885*1424dfb3Schristos   alignment = 8;
886c03b94e9Schristos #endif
887*1424dfb3Schristos   ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
888c03b94e9Schristos 
889377e23a2Schristos   vars.data = ptr;
890377e23a2Schristos   vars.abfd = abfd;
891377e23a2Schristos   vars.sec_index = 0;
892377e23a2Schristos   vars.magic = magic;
893377e23a2Schristos 
894377e23a2Schristos   /* Create the initial .idata$<n> sections:
895377e23a2Schristos      [.idata$2:  Import Directory Table -- not needed]
896377e23a2Schristos      .idata$4:  Import Lookup Table
897377e23a2Schristos      .idata$5:  Import Address Table
898377e23a2Schristos 
899377e23a2Schristos      Note we do not create a .idata$3 section as this is
900377e23a2Schristos      created for us by the linker script.  */
901377e23a2Schristos   id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
902377e23a2Schristos   id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
903377e23a2Schristos   if (id4 == NULL || id5 == NULL)
904377e23a2Schristos     goto error_return;
905377e23a2Schristos 
906377e23a2Schristos   /* Fill in the contents of these sections.  */
907377e23a2Schristos   if (import_name_type == IMPORT_ORDINAL)
908377e23a2Schristos     {
909377e23a2Schristos       if (ordinal == 0)
9101c468f90Schristos 	/* See PR 20907 for a reproducer.  */
9111c468f90Schristos 	goto error_return;
912377e23a2Schristos 
913377e23a2Schristos #ifdef COFF_WITH_pex64
914377e23a2Schristos       ((unsigned int *) id4->contents)[0] = ordinal;
915377e23a2Schristos       ((unsigned int *) id4->contents)[1] = 0x80000000;
916377e23a2Schristos       ((unsigned int *) id5->contents)[0] = ordinal;
917377e23a2Schristos       ((unsigned int *) id5->contents)[1] = 0x80000000;
918377e23a2Schristos #else
919377e23a2Schristos       * (unsigned int *) id4->contents = ordinal | 0x80000000;
920377e23a2Schristos       * (unsigned int *) id5->contents = ordinal | 0x80000000;
921377e23a2Schristos #endif
922377e23a2Schristos     }
923377e23a2Schristos   else
924377e23a2Schristos     {
925377e23a2Schristos       char * symbol;
926377e23a2Schristos       unsigned int len;
927377e23a2Schristos 
928377e23a2Schristos       /* Create .idata$6 - the Hint Name Table.  */
929377e23a2Schristos       id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
930377e23a2Schristos       if (id6 == NULL)
931377e23a2Schristos 	goto error_return;
932377e23a2Schristos 
933377e23a2Schristos       /* If necessary, trim the import symbol name.  */
934377e23a2Schristos       symbol = symbol_name;
935377e23a2Schristos 
936377e23a2Schristos       /* As used by MS compiler, '_', '@', and '?' are alternative
937377e23a2Schristos 	 forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
938377e23a2Schristos 	 '@' used for fastcall (in C),  '_' everywhere else.  Only one
939377e23a2Schristos 	 of these is used for a symbol.  We strip this leading char for
940377e23a2Schristos 	 IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
941377e23a2Schristos 	 PE COFF 6.0 spec (section 8.3, Import Name Type).  */
942377e23a2Schristos 
943377e23a2Schristos       if (import_name_type != IMPORT_NAME)
944377e23a2Schristos 	{
945377e23a2Schristos 	  char c = symbol[0];
94648596154Schristos 
94748596154Schristos 	  /* Check that we don't remove for targets with empty
94848596154Schristos 	     USER_LABEL_PREFIX the leading underscore.  */
94948596154Schristos 	  if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
95048596154Schristos 	      || c == '@' || c == '?')
951377e23a2Schristos 	    symbol++;
952377e23a2Schristos 	}
953377e23a2Schristos 
954377e23a2Schristos       len = strlen (symbol);
955377e23a2Schristos       if (import_name_type == IMPORT_NAME_UNDECORATE)
956377e23a2Schristos 	{
957377e23a2Schristos 	  /* Truncate at the first '@'.  */
958377e23a2Schristos 	  char *at = strchr (symbol, '@');
959377e23a2Schristos 
960377e23a2Schristos 	  if (at != NULL)
961377e23a2Schristos 	    len = at - symbol;
962377e23a2Schristos 	}
963377e23a2Schristos 
964377e23a2Schristos       id6->contents[0] = ordinal & 0xff;
965377e23a2Schristos       id6->contents[1] = ordinal >> 8;
966377e23a2Schristos 
967377e23a2Schristos       memcpy ((char *) id6->contents + 2, symbol, len);
968377e23a2Schristos       id6->contents[len + 2] = '\0';
969377e23a2Schristos     }
970377e23a2Schristos 
971377e23a2Schristos   if (import_name_type != IMPORT_ORDINAL)
972377e23a2Schristos     {
973377e23a2Schristos       pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
974377e23a2Schristos       pe_ILF_save_relocs (&vars, id4);
975377e23a2Schristos 
976377e23a2Schristos       pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
977377e23a2Schristos       pe_ILF_save_relocs (&vars, id5);
978377e23a2Schristos     }
979377e23a2Schristos 
980c03b94e9Schristos   /* Create an import symbol.  */
981c03b94e9Schristos   pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
982c03b94e9Schristos   imp_sym   = vars.sym_ptr_ptr - 1;
983c03b94e9Schristos   imp_index = vars.sym_index - 1;
984c03b94e9Schristos 
985377e23a2Schristos   /* Create extra sections depending upon the type of import we are dealing with.  */
986377e23a2Schristos   switch (import_type)
987377e23a2Schristos     {
988377e23a2Schristos       int i;
989377e23a2Schristos 
990377e23a2Schristos     case IMPORT_CODE:
991c03b94e9Schristos       /* CODE functions are special, in that they get a trampoline that
992c03b94e9Schristos 	 jumps to the main import symbol.  Create a .text section to hold it.
993377e23a2Schristos 	 First we need to look up its contents in the jump table.  */
994377e23a2Schristos       for (i = NUM_ENTRIES (jtab); i--;)
995377e23a2Schristos 	{
996377e23a2Schristos 	  if (jtab[i].size == 0)
997377e23a2Schristos 	    continue;
998377e23a2Schristos 	  if (jtab[i].magic == magic)
999377e23a2Schristos 	    break;
1000377e23a2Schristos 	}
1001377e23a2Schristos       /* If we did not find a matching entry something is wrong.  */
1002377e23a2Schristos       if (i < 0)
1003377e23a2Schristos 	abort ();
1004377e23a2Schristos 
1005377e23a2Schristos       /* Create the .text section.  */
1006377e23a2Schristos       text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
1007377e23a2Schristos       if (text == NULL)
1008377e23a2Schristos 	goto error_return;
1009377e23a2Schristos 
1010377e23a2Schristos       /* Copy in the jump code.  */
1011377e23a2Schristos       memcpy (text->contents, jtab[i].data, jtab[i].size);
1012377e23a2Schristos 
1013377e23a2Schristos       /* Create a reloc for the data in the text section.  */
1014377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
1015377e23a2Schristos       if (magic == MIPS_ARCH_MAGIC_WINCE)
1016377e23a2Schristos 	{
1017377e23a2Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
1018377e23a2Schristos 				      (struct bfd_symbol **) imp_sym,
1019377e23a2Schristos 				      imp_index);
1020377e23a2Schristos 	  pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
1021377e23a2Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
1022377e23a2Schristos 				      (struct bfd_symbol **) imp_sym,
1023377e23a2Schristos 				      imp_index);
1024377e23a2Schristos 	}
1025377e23a2Schristos       else
1026377e23a2Schristos #endif
1027ed6a76a9Schristos #ifdef AMD64MAGIC
1028ed6a76a9Schristos       if (magic == AMD64MAGIC)
1029ed6a76a9Schristos 	{
1030ed6a76a9Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
1031ed6a76a9Schristos 				      BFD_RELOC_32_PCREL, (asymbol **) imp_sym,
1032ed6a76a9Schristos 				      imp_index);
1033ed6a76a9Schristos 	}
1034ed6a76a9Schristos       else
1035ed6a76a9Schristos #endif
1036377e23a2Schristos 	pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
1037377e23a2Schristos 				    BFD_RELOC_32, (asymbol **) imp_sym,
1038377e23a2Schristos 				    imp_index);
1039377e23a2Schristos 
1040377e23a2Schristos       pe_ILF_save_relocs (& vars, text);
1041377e23a2Schristos       break;
1042377e23a2Schristos 
1043377e23a2Schristos     case IMPORT_DATA:
1044377e23a2Schristos       break;
1045377e23a2Schristos 
1046377e23a2Schristos     default:
1047377e23a2Schristos       /* XXX code not yet written.  */
1048377e23a2Schristos       abort ();
1049377e23a2Schristos     }
1050377e23a2Schristos 
1051377e23a2Schristos   /* Initialise the bfd.  */
1052377e23a2Schristos   memset (& internal_f, 0, sizeof (internal_f));
1053377e23a2Schristos 
1054377e23a2Schristos   internal_f.f_magic  = magic;
1055377e23a2Schristos   internal_f.f_symptr = 0;
1056377e23a2Schristos   internal_f.f_nsyms  = 0;
1057377e23a2Schristos   internal_f.f_flags  = F_AR32WR | F_LNNO; /* XXX is this correct ?  */
1058377e23a2Schristos 
1059377e23a2Schristos   if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
1060377e23a2Schristos       || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
1061377e23a2Schristos     goto error_return;
1062377e23a2Schristos 
1063377e23a2Schristos   if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
1064377e23a2Schristos     goto error_return;
1065377e23a2Schristos 
1066377e23a2Schristos   coff_data (abfd)->pe = 1;
1067377e23a2Schristos #ifdef THUMBPEMAGIC
1068377e23a2Schristos   if (vars.magic == THUMBPEMAGIC)
1069377e23a2Schristos     /* Stop some linker warnings about thumb code not supporting interworking.  */
1070377e23a2Schristos     coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
1071377e23a2Schristos #endif
1072377e23a2Schristos 
1073377e23a2Schristos   /* Switch from file contents to memory contents.  */
1074377e23a2Schristos   bfd_cache_close (abfd);
1075377e23a2Schristos 
1076377e23a2Schristos   abfd->iostream = (void *) vars.bim;
1077377e23a2Schristos   abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
1078377e23a2Schristos   abfd->iovec = &_bfd_memory_iovec;
1079377e23a2Schristos   abfd->where = 0;
1080377e23a2Schristos   abfd->origin = 0;
1081377e23a2Schristos   obj_sym_filepos (abfd) = 0;
1082377e23a2Schristos 
1083377e23a2Schristos   /* Now create a symbol describing the imported value.  */
1084377e23a2Schristos   switch (import_type)
1085377e23a2Schristos     {
1086377e23a2Schristos     case IMPORT_CODE:
1087377e23a2Schristos       pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
1088377e23a2Schristos 			    BSF_NOT_AT_END | BSF_FUNCTION);
1089377e23a2Schristos 
1090377e23a2Schristos       break;
1091377e23a2Schristos 
1092377e23a2Schristos     case IMPORT_DATA:
1093377e23a2Schristos       /* Nothing to do here.  */
1094377e23a2Schristos       break;
1095377e23a2Schristos 
1096377e23a2Schristos     default:
1097377e23a2Schristos       /* XXX code not yet written.  */
1098377e23a2Schristos       abort ();
1099377e23a2Schristos     }
1100377e23a2Schristos 
1101c03b94e9Schristos   /* Create an import symbol for the DLL, without the .dll suffix.  */
1102c03b94e9Schristos   ptr = (bfd_byte *) strrchr (source_dll, '.');
1103c03b94e9Schristos   if (ptr)
1104c03b94e9Schristos     * ptr = 0;
1105c03b94e9Schristos   pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
1106c03b94e9Schristos   if (ptr)
1107c03b94e9Schristos     * ptr = '.';
1108c03b94e9Schristos 
1109377e23a2Schristos   /* Point the bfd at the symbol table.  */
1110377e23a2Schristos   obj_symbols (abfd) = vars.sym_cache;
1111*1424dfb3Schristos   abfd->symcount = vars.sym_index;
1112377e23a2Schristos 
1113377e23a2Schristos   obj_raw_syments (abfd) = vars.native_syms;
1114377e23a2Schristos   obj_raw_syment_count (abfd) = vars.sym_index;
1115377e23a2Schristos 
1116377e23a2Schristos   obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1117377e23a2Schristos   obj_coff_keep_syms (abfd) = TRUE;
1118377e23a2Schristos 
1119377e23a2Schristos   obj_convert (abfd) = vars.sym_table;
1120377e23a2Schristos   obj_conv_table_size (abfd) = vars.sym_index;
1121377e23a2Schristos 
1122377e23a2Schristos   obj_coff_strings (abfd) = vars.string_table;
1123377e23a2Schristos   obj_coff_keep_strings (abfd) = TRUE;
1124377e23a2Schristos 
1125377e23a2Schristos   abfd->flags |= HAS_SYMS;
1126377e23a2Schristos 
1127377e23a2Schristos   return TRUE;
1128377e23a2Schristos 
1129377e23a2Schristos  error_return:
1130377e23a2Schristos   free (vars.bim->buffer);
1131377e23a2Schristos   free (vars.bim);
1132377e23a2Schristos   return FALSE;
1133377e23a2Schristos }
1134377e23a2Schristos 
1135377e23a2Schristos /* We have detected a Image Library Format archive element.
1136377e23a2Schristos    Decode the element and return the appropriate target.  */
1137377e23a2Schristos 
1138*1424dfb3Schristos static bfd_cleanup
pe_ILF_object_p(bfd * abfd)1139377e23a2Schristos pe_ILF_object_p (bfd * abfd)
1140377e23a2Schristos {
11415e098073Schristos   bfd_byte	  buffer[14];
1142377e23a2Schristos   bfd_byte *	  ptr;
1143377e23a2Schristos   char *	  symbol_name;
1144377e23a2Schristos   char *	  source_dll;
1145377e23a2Schristos   unsigned int	  machine;
1146377e23a2Schristos   bfd_size_type	  size;
1147377e23a2Schristos   unsigned int	  ordinal;
1148377e23a2Schristos   unsigned int	  types;
1149377e23a2Schristos   unsigned int	  magic;
1150377e23a2Schristos 
11515e098073Schristos   /* Upon entry the first six bytes of the ILF header have
1152377e23a2Schristos       already been read.  Now read the rest of the header.  */
11535e098073Schristos   if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14)
1154377e23a2Schristos     return NULL;
1155377e23a2Schristos 
1156377e23a2Schristos   ptr = buffer;
1157377e23a2Schristos 
1158377e23a2Schristos   machine = H_GET_16 (abfd, ptr);
1159377e23a2Schristos   ptr += 2;
1160377e23a2Schristos 
1161377e23a2Schristos   /* Check that the machine type is recognised.  */
1162377e23a2Schristos   magic = 0;
1163377e23a2Schristos 
1164377e23a2Schristos   switch (machine)
1165377e23a2Schristos     {
1166377e23a2Schristos     case IMAGE_FILE_MACHINE_UNKNOWN:
1167377e23a2Schristos     case IMAGE_FILE_MACHINE_ALPHA:
1168377e23a2Schristos     case IMAGE_FILE_MACHINE_ALPHA64:
1169377e23a2Schristos     case IMAGE_FILE_MACHINE_IA64:
1170377e23a2Schristos       break;
1171377e23a2Schristos 
1172377e23a2Schristos     case IMAGE_FILE_MACHINE_I386:
1173377e23a2Schristos #ifdef I386MAGIC
1174377e23a2Schristos       magic = I386MAGIC;
1175377e23a2Schristos #endif
1176377e23a2Schristos       break;
1177377e23a2Schristos 
1178377e23a2Schristos     case IMAGE_FILE_MACHINE_AMD64:
1179377e23a2Schristos #ifdef AMD64MAGIC
1180377e23a2Schristos       magic = AMD64MAGIC;
1181377e23a2Schristos #endif
1182377e23a2Schristos       break;
1183377e23a2Schristos 
1184377e23a2Schristos     case IMAGE_FILE_MACHINE_R3000:
1185377e23a2Schristos     case IMAGE_FILE_MACHINE_R4000:
1186377e23a2Schristos     case IMAGE_FILE_MACHINE_R10000:
1187377e23a2Schristos 
1188377e23a2Schristos     case IMAGE_FILE_MACHINE_MIPS16:
1189377e23a2Schristos     case IMAGE_FILE_MACHINE_MIPSFPU:
1190377e23a2Schristos     case IMAGE_FILE_MACHINE_MIPSFPU16:
1191377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
1192377e23a2Schristos       magic = MIPS_ARCH_MAGIC_WINCE;
1193377e23a2Schristos #endif
1194377e23a2Schristos       break;
1195377e23a2Schristos 
1196377e23a2Schristos     case IMAGE_FILE_MACHINE_SH3:
1197377e23a2Schristos     case IMAGE_FILE_MACHINE_SH4:
1198377e23a2Schristos #ifdef SH_ARCH_MAGIC_WINCE
1199377e23a2Schristos       magic = SH_ARCH_MAGIC_WINCE;
1200377e23a2Schristos #endif
1201377e23a2Schristos       break;
1202377e23a2Schristos 
1203377e23a2Schristos     case IMAGE_FILE_MACHINE_ARM:
1204377e23a2Schristos #ifdef ARMPEMAGIC
1205377e23a2Schristos       magic = ARMPEMAGIC;
1206377e23a2Schristos #endif
1207377e23a2Schristos       break;
1208377e23a2Schristos 
1209377e23a2Schristos     case IMAGE_FILE_MACHINE_THUMB:
1210377e23a2Schristos #ifdef THUMBPEMAGIC
1211377e23a2Schristos       {
1212377e23a2Schristos 	extern const bfd_target TARGET_LITTLE_SYM;
1213377e23a2Schristos 
1214377e23a2Schristos 	if (abfd->xvec == & TARGET_LITTLE_SYM)
1215377e23a2Schristos 	  magic = THUMBPEMAGIC;
1216377e23a2Schristos       }
1217377e23a2Schristos #endif
1218377e23a2Schristos       break;
1219377e23a2Schristos 
1220377e23a2Schristos     case IMAGE_FILE_MACHINE_POWERPC:
1221377e23a2Schristos       /* We no longer support PowerPC.  */
1222377e23a2Schristos     default:
1223377e23a2Schristos       _bfd_error_handler
12241c468f90Schristos 	/* xgettext:c-format */
122507163879Schristos 	(_("%pB: unrecognised machine type (0x%x)"
1226377e23a2Schristos 	   " in Import Library Format archive"),
1227377e23a2Schristos 	 abfd, machine);
1228377e23a2Schristos       bfd_set_error (bfd_error_malformed_archive);
1229377e23a2Schristos 
1230377e23a2Schristos       return NULL;
1231377e23a2Schristos       break;
1232377e23a2Schristos     }
1233377e23a2Schristos 
1234377e23a2Schristos   if (magic == 0)
1235377e23a2Schristos     {
1236377e23a2Schristos       _bfd_error_handler
12371c468f90Schristos 	/* xgettext:c-format */
123807163879Schristos 	(_("%pB: recognised but unhandled machine type (0x%x)"
1239377e23a2Schristos 	   " in Import Library Format archive"),
1240377e23a2Schristos 	 abfd, machine);
1241377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1242377e23a2Schristos 
1243377e23a2Schristos       return NULL;
1244377e23a2Schristos     }
1245377e23a2Schristos 
1246377e23a2Schristos   /* We do not bother to check the date.
1247377e23a2Schristos      date = H_GET_32 (abfd, ptr);  */
1248377e23a2Schristos   ptr += 4;
1249377e23a2Schristos 
1250377e23a2Schristos   size = H_GET_32 (abfd, ptr);
1251377e23a2Schristos   ptr += 4;
1252377e23a2Schristos 
1253377e23a2Schristos   if (size == 0)
1254377e23a2Schristos     {
1255377e23a2Schristos       _bfd_error_handler
125607163879Schristos 	(_("%pB: size field is zero in Import Library Format header"), abfd);
1257377e23a2Schristos       bfd_set_error (bfd_error_malformed_archive);
1258377e23a2Schristos 
1259377e23a2Schristos       return NULL;
1260377e23a2Schristos     }
1261377e23a2Schristos 
1262377e23a2Schristos   ordinal = H_GET_16 (abfd, ptr);
1263377e23a2Schristos   ptr += 2;
1264377e23a2Schristos 
1265377e23a2Schristos   types = H_GET_16 (abfd, ptr);
1266377e23a2Schristos   /* ptr += 2; */
1267377e23a2Schristos 
1268377e23a2Schristos   /* Now read in the two strings that follow.  */
1269*1424dfb3Schristos   ptr = (bfd_byte *) _bfd_alloc_and_read (abfd, size, size);
1270377e23a2Schristos   if (ptr == NULL)
1271377e23a2Schristos     return NULL;
1272377e23a2Schristos 
1273377e23a2Schristos   symbol_name = (char *) ptr;
12741c468f90Schristos   /* See PR 20905 for an example of where the strnlen is necessary.  */
12751c468f90Schristos   source_dll  = symbol_name + strnlen (symbol_name, size - 1) + 1;
1276377e23a2Schristos 
1277377e23a2Schristos   /* Verify that the strings are null terminated.  */
1278377e23a2Schristos   if (ptr[size - 1] != 0
1279377e23a2Schristos       || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
1280377e23a2Schristos     {
1281377e23a2Schristos       _bfd_error_handler
128207163879Schristos 	(_("%pB: string not null terminated in ILF object file"), abfd);
1283377e23a2Schristos       bfd_set_error (bfd_error_malformed_archive);
1284377e23a2Schristos       bfd_release (abfd, ptr);
1285377e23a2Schristos       return NULL;
1286377e23a2Schristos     }
1287377e23a2Schristos 
1288377e23a2Schristos   /* Now construct the bfd.  */
1289377e23a2Schristos   if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
1290377e23a2Schristos 			    source_dll, ordinal, types))
1291377e23a2Schristos     {
1292377e23a2Schristos       bfd_release (abfd, ptr);
1293377e23a2Schristos       return NULL;
1294377e23a2Schristos     }
1295377e23a2Schristos 
1296*1424dfb3Schristos   return _bfd_no_cleanup;
1297377e23a2Schristos }
1298377e23a2Schristos 
1299ed6a76a9Schristos static void
pe_bfd_read_buildid(bfd * abfd)1300ed6a76a9Schristos pe_bfd_read_buildid (bfd *abfd)
1301ed6a76a9Schristos {
1302ed6a76a9Schristos   pe_data_type *pe = pe_data (abfd);
1303ed6a76a9Schristos   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1304ed6a76a9Schristos   asection *section;
1305ed6a76a9Schristos   bfd_byte *data = 0;
1306ed6a76a9Schristos   bfd_size_type dataoff;
1307ed6a76a9Schristos   unsigned int i;
1308ed6a76a9Schristos   bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
1309ed6a76a9Schristos   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
1310ed6a76a9Schristos 
1311ed6a76a9Schristos   if (size == 0)
1312ed6a76a9Schristos     return;
1313ed6a76a9Schristos 
1314ed6a76a9Schristos   addr += extra->ImageBase;
1315ed6a76a9Schristos 
13161c468f90Schristos   /* Search for the section containing the DebugDirectory.  */
1317ed6a76a9Schristos   for (section = abfd->sections; section != NULL; section = section->next)
1318ed6a76a9Schristos     {
1319ed6a76a9Schristos       if ((addr >= section->vma) && (addr < (section->vma + section->size)))
1320ed6a76a9Schristos 	break;
1321ed6a76a9Schristos     }
1322ed6a76a9Schristos 
1323ed6a76a9Schristos   if (section == NULL)
1324ed6a76a9Schristos     return;
13251c468f90Schristos 
13261c468f90Schristos   if (!(section->flags & SEC_HAS_CONTENTS))
1327ed6a76a9Schristos     return;
1328ed6a76a9Schristos 
1329ed6a76a9Schristos   dataoff = addr - section->vma;
1330ed6a76a9Schristos 
133107163879Schristos   /* PR 20605 and 22373: Make sure that the data is really there.
133207163879Schristos      Note - since we are dealing with unsigned quantities we have
133307163879Schristos      to be careful to check for potential overflows.  */
133407163879Schristos   if (dataoff >= section->size
133507163879Schristos       || size > section->size - dataoff)
13361c468f90Schristos     {
133707163879Schristos       _bfd_error_handler
133807163879Schristos 	(_("%pB: error: debug data ends beyond end of debug directory"),
13391c468f90Schristos 	 abfd);
13401c468f90Schristos       return;
13411c468f90Schristos     }
13421c468f90Schristos 
1343ed6a76a9Schristos   /* Read the whole section. */
1344ed6a76a9Schristos   if (!bfd_malloc_and_get_section (abfd, section, &data))
1345ed6a76a9Schristos     {
1346ed6a76a9Schristos       free (data);
1347ed6a76a9Schristos       return;
1348ed6a76a9Schristos     }
1349ed6a76a9Schristos 
1350ed6a76a9Schristos   /* Search for a CodeView entry in the DebugDirectory */
1351ed6a76a9Schristos   for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
1352ed6a76a9Schristos     {
1353ed6a76a9Schristos       struct external_IMAGE_DEBUG_DIRECTORY *ext
1354ed6a76a9Schristos 	= &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
1355ed6a76a9Schristos       struct internal_IMAGE_DEBUG_DIRECTORY idd;
1356ed6a76a9Schristos 
1357ed6a76a9Schristos       _bfd_XXi_swap_debugdir_in (abfd, ext, &idd);
1358ed6a76a9Schristos 
1359ed6a76a9Schristos       if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
1360ed6a76a9Schristos 	{
1361ed6a76a9Schristos 	  char buffer[256 + 1];
1362ed6a76a9Schristos 	  CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
1363ed6a76a9Schristos 
1364ed6a76a9Schristos 	  /*
1365ed6a76a9Schristos 	    The debug entry doesn't have to have to be in a section, in which
1366ed6a76a9Schristos 	    case AddressOfRawData is 0, so always use PointerToRawData.
1367ed6a76a9Schristos 	  */
1368ed6a76a9Schristos 	  if (_bfd_XXi_slurp_codeview_record (abfd,
1369ed6a76a9Schristos 					      (file_ptr) idd.PointerToRawData,
1370ed6a76a9Schristos 					      idd.SizeOfData, cvinfo))
1371ed6a76a9Schristos 	    {
1372ed6a76a9Schristos 	      struct bfd_build_id* build_id = bfd_alloc (abfd,
1373ed6a76a9Schristos 			 sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
1374ed6a76a9Schristos 	      if (build_id)
1375ed6a76a9Schristos 		{
1376ed6a76a9Schristos 		  build_id->size = cvinfo->SignatureLength;
1377ed6a76a9Schristos 		  memcpy(build_id->data,  cvinfo->Signature,
1378ed6a76a9Schristos 			 cvinfo->SignatureLength);
1379ed6a76a9Schristos 		  abfd->build_id = build_id;
1380ed6a76a9Schristos 		}
1381ed6a76a9Schristos 	    }
1382ed6a76a9Schristos 	  break;
1383ed6a76a9Schristos 	}
1384ed6a76a9Schristos     }
1385*1424dfb3Schristos 
1386*1424dfb3Schristos   free (data);
1387ed6a76a9Schristos }
1388ed6a76a9Schristos 
1389*1424dfb3Schristos static bfd_cleanup
pe_bfd_object_p(bfd * abfd)1390377e23a2Schristos pe_bfd_object_p (bfd * abfd)
1391377e23a2Schristos {
13925e098073Schristos   bfd_byte buffer[6];
139307163879Schristos   struct external_DOS_hdr dos_hdr;
1394377e23a2Schristos   struct external_PEI_IMAGE_hdr image_hdr;
13957af5a897Schristos   struct internal_filehdr internal_f;
13967af5a897Schristos   struct internal_aouthdr internal_a;
1397*1424dfb3Schristos   bfd_size_type opt_hdr_size;
1398377e23a2Schristos   file_ptr offset;
1399*1424dfb3Schristos   bfd_cleanup result;
1400377e23a2Schristos 
1401377e23a2Schristos   /* Detect if this a Microsoft Import Library Format element.  */
14025e098073Schristos   /* First read the beginning of the header.  */
1403377e23a2Schristos   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
14045e098073Schristos       || bfd_bread (buffer, (bfd_size_type) 6, abfd) != 6)
1405377e23a2Schristos     {
1406377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1407377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1408377e23a2Schristos       return NULL;
1409377e23a2Schristos     }
1410377e23a2Schristos 
14115e098073Schristos   /* Then check the magic and the version (only 0 is supported).  */
14125e098073Schristos   if (H_GET_32 (abfd, buffer) == 0xffff0000
14135e098073Schristos       && H_GET_16 (abfd, buffer + 4) == 0)
1414377e23a2Schristos     return pe_ILF_object_p (abfd);
1415377e23a2Schristos 
1416377e23a2Schristos   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1417377e23a2Schristos       || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
1418377e23a2Schristos 	 != sizeof (dos_hdr))
1419377e23a2Schristos     {
1420377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1421377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1422377e23a2Schristos       return NULL;
1423377e23a2Schristos     }
1424377e23a2Schristos 
1425377e23a2Schristos   /* There are really two magic numbers involved; the magic number
1426377e23a2Schristos      that says this is a NT executable (PEI) and the magic number that
142707163879Schristos      determines the architecture.  The former is IMAGE_DOS_SIGNATURE, stored in
1428377e23a2Schristos      the e_magic field.  The latter is stored in the f_magic field.
1429377e23a2Schristos      If the NT magic number isn't valid, the architecture magic number
1430377e23a2Schristos      could be mimicked by some other field (specifically, the number
1431377e23a2Schristos      of relocs in section 3).  Since this routine can only be called
1432377e23a2Schristos      correctly for a PEI file, check the e_magic number here, and, if
1433377e23a2Schristos      it doesn't match, clobber the f_magic number so that we don't get
1434377e23a2Schristos      a false match.  */
143507163879Schristos   if (H_GET_16 (abfd, dos_hdr.e_magic) != IMAGE_DOS_SIGNATURE)
1436377e23a2Schristos     {
1437377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1438377e23a2Schristos       return NULL;
1439377e23a2Schristos     }
1440377e23a2Schristos 
1441377e23a2Schristos   offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
1442377e23a2Schristos   if (bfd_seek (abfd, offset, SEEK_SET) != 0
1443377e23a2Schristos       || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
1444377e23a2Schristos 	  != sizeof (image_hdr)))
1445377e23a2Schristos     {
1446377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1447377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1448377e23a2Schristos       return NULL;
1449377e23a2Schristos     }
1450377e23a2Schristos 
1451377e23a2Schristos   if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
1452377e23a2Schristos     {
1453377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1454377e23a2Schristos       return NULL;
1455377e23a2Schristos     }
1456377e23a2Schristos 
14577af5a897Schristos   /* Swap file header, so that we get the location for calling
14587af5a897Schristos      real_object_p.  */
14595e098073Schristos   bfd_coff_swap_filehdr_in (abfd, &image_hdr, &internal_f);
14607af5a897Schristos 
14617af5a897Schristos   if (! bfd_coff_bad_format_hook (abfd, &internal_f)
14627af5a897Schristos       || internal_f.f_opthdr > bfd_coff_aoutsz (abfd))
1463377e23a2Schristos     {
1464377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1465377e23a2Schristos       return NULL;
1466377e23a2Schristos     }
1467377e23a2Schristos 
1468*1424dfb3Schristos   memcpy (internal_f.pe.dos_message, dos_hdr.dos_message,
1469*1424dfb3Schristos 	  sizeof (internal_f.pe.dos_message));
1470*1424dfb3Schristos 
14717af5a897Schristos   /* Read the optional header, which has variable size.  */
14727af5a897Schristos   opt_hdr_size = internal_f.f_opthdr;
14737af5a897Schristos 
14747af5a897Schristos   if (opt_hdr_size != 0)
14757af5a897Schristos     {
14765e098073Schristos       bfd_size_type amt = opt_hdr_size;
14775e098073Schristos       void * opthdr;
14787af5a897Schristos 
14795e098073Schristos       /* PR 17521 file: 230-131433-0.004.  */
14805e098073Schristos       if (amt < sizeof (PEAOUTHDR))
14815e098073Schristos 	amt = sizeof (PEAOUTHDR);
14825e098073Schristos 
1483*1424dfb3Schristos       opthdr = _bfd_alloc_and_read (abfd, amt, opt_hdr_size);
14847af5a897Schristos       if (opthdr == NULL)
14857af5a897Schristos 	return NULL;
1486*1424dfb3Schristos       if (amt > opt_hdr_size)
1487*1424dfb3Schristos 	memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
14887af5a897Schristos 
1489ed6a76a9Schristos       bfd_set_error (bfd_error_no_error);
14905e098073Schristos       bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
1491ed6a76a9Schristos       if (bfd_get_error () != bfd_error_no_error)
1492ed6a76a9Schristos 	return NULL;
14937af5a897Schristos     }
14947af5a897Schristos 
1495ed6a76a9Schristos 
1496ed6a76a9Schristos   result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
14977af5a897Schristos 			       (opt_hdr_size != 0
14987af5a897Schristos 				? &internal_a
14997af5a897Schristos 				: (struct internal_aouthdr *) NULL));
1500ed6a76a9Schristos 
1501ed6a76a9Schristos 
1502ed6a76a9Schristos   if (result)
1503ed6a76a9Schristos     {
1504ed6a76a9Schristos       /* Now the whole header has been processed, see if there is a build-id */
1505ed6a76a9Schristos       pe_bfd_read_buildid(abfd);
1506ed6a76a9Schristos     }
1507ed6a76a9Schristos 
1508ed6a76a9Schristos   return result;
1509377e23a2Schristos }
1510377e23a2Schristos 
1511377e23a2Schristos #define coff_object_p pe_bfd_object_p
1512377e23a2Schristos #endif /* COFF_IMAGE_WITH_PE */
1513