xref: /netbsd/external/gpl3/gdb/dist/bfd/peicode.h (revision 48596154)
1377e23a2Schristos /* Support for the generic parts of PE/PEI, for BFD.
2377e23a2Schristos    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3*48596154Schristos    2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4*48596154Schristos    Free Software Foundation, Inc.
5377e23a2Schristos    Written by Cygnus Solutions.
6377e23a2Schristos 
7377e23a2Schristos    This file is part of BFD, the Binary File Descriptor library.
8377e23a2Schristos 
9377e23a2Schristos    This program is free software; you can redistribute it and/or modify
10377e23a2Schristos    it under the terms of the GNU General Public License as published by
11377e23a2Schristos    the Free Software Foundation; either version 3 of the License, or
12377e23a2Schristos    (at your option) any later version.
13377e23a2Schristos 
14377e23a2Schristos    This program is distributed in the hope that it will be useful,
15377e23a2Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
16377e23a2Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17377e23a2Schristos    GNU General Public License for more details.
18377e23a2Schristos 
19377e23a2Schristos    You should have received a copy of the GNU General Public License
20377e23a2Schristos    along with this program; if not, write to the Free Software
21377e23a2Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22377e23a2Schristos    MA 02110-1301, USA.  */
23377e23a2Schristos 
24377e23a2Schristos 
25377e23a2Schristos /* Most of this hacked by  Steve Chamberlain,
26377e23a2Schristos 			sac@cygnus.com
27377e23a2Schristos 
28377e23a2Schristos    PE/PEI rearrangement (and code added): Donn Terry
29377e23a2Schristos                                        Softway Systems, Inc.  */
30377e23a2Schristos 
31377e23a2Schristos /* Hey look, some documentation [and in a place you expect to find it]!
32377e23a2Schristos 
33377e23a2Schristos    The main reference for the pei format is "Microsoft Portable Executable
34377e23a2Schristos    and Common Object File Format Specification 4.1".  Get it if you need to
35377e23a2Schristos    do some serious hacking on this code.
36377e23a2Schristos 
37377e23a2Schristos    Another reference:
38377e23a2Schristos    "Peering Inside the PE: A Tour of the Win32 Portable Executable
39377e23a2Schristos    File Format", MSJ 1994, Volume 9.
40377e23a2Schristos 
41377e23a2Schristos    The *sole* difference between the pe format and the pei format is that the
42377e23a2Schristos    latter has an MSDOS 2.0 .exe header on the front that prints the message
43377e23a2Schristos    "This app must be run under Windows." (or some such).
44377e23a2Schristos    (FIXME: Whether that statement is *really* true or not is unknown.
45377e23a2Schristos    Are there more subtle differences between pe and pei formats?
46377e23a2Schristos    For now assume there aren't.  If you find one, then for God sakes
47377e23a2Schristos    document it here!)
48377e23a2Schristos 
49377e23a2Schristos    The Microsoft docs use the word "image" instead of "executable" because
50377e23a2Schristos    the former can also refer to a DLL (shared library).  Confusion can arise
51377e23a2Schristos    because the `i' in `pei' also refers to "image".  The `pe' format can
52377e23a2Schristos    also create images (i.e. executables), it's just that to run on a win32
53377e23a2Schristos    system you need to use the pei format.
54377e23a2Schristos 
55377e23a2Schristos    FIXME: Please add more docs here so the next poor fool that has to hack
56377e23a2Schristos    on this code has a chance of getting something accomplished without
57377e23a2Schristos    wasting too much time.  */
58377e23a2Schristos 
59377e23a2Schristos #include "libpei.h"
60377e23a2Schristos 
61377e23a2Schristos static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
62377e23a2Schristos #ifndef coff_bfd_print_private_bfd_data
63377e23a2Schristos      NULL;
64377e23a2Schristos #else
65377e23a2Schristos      coff_bfd_print_private_bfd_data;
66377e23a2Schristos #undef coff_bfd_print_private_bfd_data
67377e23a2Schristos #endif
68377e23a2Schristos 
69377e23a2Schristos static bfd_boolean                      pe_print_private_bfd_data (bfd *, void *);
70377e23a2Schristos #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
71377e23a2Schristos 
72377e23a2Schristos static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
73377e23a2Schristos #ifndef coff_bfd_copy_private_bfd_data
74377e23a2Schristos      NULL;
75377e23a2Schristos #else
76377e23a2Schristos      coff_bfd_copy_private_bfd_data;
77377e23a2Schristos #undef coff_bfd_copy_private_bfd_data
78377e23a2Schristos #endif
79377e23a2Schristos 
80377e23a2Schristos static bfd_boolean                     pe_bfd_copy_private_bfd_data (bfd *, bfd *);
81377e23a2Schristos #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
82377e23a2Schristos 
83377e23a2Schristos #define coff_mkobject      pe_mkobject
84377e23a2Schristos #define coff_mkobject_hook pe_mkobject_hook
85377e23a2Schristos 
86377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
87377e23a2Schristos /* This structure contains static variables used by the ILF code.  */
88377e23a2Schristos typedef asection * asection_ptr;
89377e23a2Schristos 
90377e23a2Schristos typedef struct
91377e23a2Schristos {
92377e23a2Schristos   bfd *			abfd;
93377e23a2Schristos   bfd_byte *		data;
94377e23a2Schristos   struct bfd_in_memory * bim;
95377e23a2Schristos   unsigned short        magic;
96377e23a2Schristos 
97377e23a2Schristos   arelent *		reltab;
98377e23a2Schristos   unsigned int 		relcount;
99377e23a2Schristos 
100377e23a2Schristos   coff_symbol_type * 	sym_cache;
101377e23a2Schristos   coff_symbol_type * 	sym_ptr;
102377e23a2Schristos   unsigned int       	sym_index;
103377e23a2Schristos 
104377e23a2Schristos   unsigned int * 	sym_table;
105377e23a2Schristos   unsigned int * 	table_ptr;
106377e23a2Schristos 
107377e23a2Schristos   combined_entry_type * native_syms;
108377e23a2Schristos   combined_entry_type * native_ptr;
109377e23a2Schristos 
110377e23a2Schristos   coff_symbol_type **	sym_ptr_table;
111377e23a2Schristos   coff_symbol_type **	sym_ptr_ptr;
112377e23a2Schristos 
113377e23a2Schristos   unsigned int		sec_index;
114377e23a2Schristos 
115377e23a2Schristos   char *                string_table;
116377e23a2Schristos   char *                string_ptr;
117377e23a2Schristos   char *		end_string_ptr;
118377e23a2Schristos 
119377e23a2Schristos   SYMENT *              esym_table;
120377e23a2Schristos   SYMENT *              esym_ptr;
121377e23a2Schristos 
122377e23a2Schristos   struct internal_reloc * int_reltab;
123377e23a2Schristos }
124377e23a2Schristos pe_ILF_vars;
125377e23a2Schristos #endif /* COFF_IMAGE_WITH_PE */
126377e23a2Schristos 
127377e23a2Schristos #ifndef NO_COFF_RELOCS
128377e23a2Schristos static void
129377e23a2Schristos coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
130377e23a2Schristos {
131377e23a2Schristos   RELOC *reloc_src = (RELOC *) src;
132377e23a2Schristos   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
133377e23a2Schristos 
134377e23a2Schristos   reloc_dst->r_vaddr  = H_GET_32 (abfd, reloc_src->r_vaddr);
135377e23a2Schristos   reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
136377e23a2Schristos   reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
137377e23a2Schristos #ifdef SWAP_IN_RELOC_OFFSET
138377e23a2Schristos   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
139377e23a2Schristos #endif
140377e23a2Schristos }
141377e23a2Schristos 
142377e23a2Schristos static unsigned int
143377e23a2Schristos coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
144377e23a2Schristos {
145377e23a2Schristos   struct internal_reloc *reloc_src = (struct internal_reloc *) src;
146377e23a2Schristos   struct external_reloc *reloc_dst = (struct external_reloc *) dst;
147377e23a2Schristos 
148377e23a2Schristos   H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
149377e23a2Schristos   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
150377e23a2Schristos   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
151377e23a2Schristos 
152377e23a2Schristos #ifdef SWAP_OUT_RELOC_OFFSET
153377e23a2Schristos   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
154377e23a2Schristos #endif
155377e23a2Schristos #ifdef SWAP_OUT_RELOC_EXTRA
156377e23a2Schristos   SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
157377e23a2Schristos #endif
158377e23a2Schristos   return RELSZ;
159377e23a2Schristos }
160377e23a2Schristos #endif /* not NO_COFF_RELOCS */
161377e23a2Schristos 
162377e23a2Schristos static void
163377e23a2Schristos coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
164377e23a2Schristos {
165377e23a2Schristos   FILHDR *filehdr_src = (FILHDR *) src;
166377e23a2Schristos   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
167377e23a2Schristos 
168377e23a2Schristos   filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
169377e23a2Schristos   filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
170377e23a2Schristos   filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
171377e23a2Schristos   filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
172377e23a2Schristos   filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
173377e23a2Schristos   filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr);
174377e23a2Schristos 
175377e23a2Schristos   /* Other people's tools sometimes generate headers with an nsyms but
176377e23a2Schristos      a zero symptr.  */
177377e23a2Schristos   if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
178377e23a2Schristos     {
179377e23a2Schristos       filehdr_dst->f_nsyms = 0;
180377e23a2Schristos       filehdr_dst->f_flags |= F_LSYMS;
181377e23a2Schristos     }
182377e23a2Schristos 
183377e23a2Schristos   filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr);
184377e23a2Schristos }
185377e23a2Schristos 
186377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
187377e23a2Schristos # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
188377e23a2Schristos #elif defined COFF_WITH_pex64
189377e23a2Schristos # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
190377e23a2Schristos #elif defined COFF_WITH_pep
191377e23a2Schristos # define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
192377e23a2Schristos #else
193377e23a2Schristos # define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
194377e23a2Schristos #endif
195377e23a2Schristos 
196377e23a2Schristos static void
197377e23a2Schristos coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
198377e23a2Schristos {
199377e23a2Schristos   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
200377e23a2Schristos   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
201377e23a2Schristos 
202377e23a2Schristos   memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
203377e23a2Schristos 
204377e23a2Schristos   scnhdr_int->s_vaddr   = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
205377e23a2Schristos   scnhdr_int->s_paddr   = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
206377e23a2Schristos   scnhdr_int->s_size    = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
207377e23a2Schristos   scnhdr_int->s_scnptr  = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
208377e23a2Schristos   scnhdr_int->s_relptr  = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
209377e23a2Schristos   scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
210377e23a2Schristos   scnhdr_int->s_flags   = H_GET_32 (abfd, scnhdr_ext->s_flags);
211377e23a2Schristos 
212377e23a2Schristos   /* MS handles overflow of line numbers by carrying into the reloc
213377e23a2Schristos      field (it appears).  Since it's supposed to be zero for PE
214377e23a2Schristos      *IMAGE* format, that's safe.  This is still a bit iffy.  */
215377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
216377e23a2Schristos   scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
217377e23a2Schristos 			 + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
218377e23a2Schristos   scnhdr_int->s_nreloc = 0;
219377e23a2Schristos #else
220377e23a2Schristos   scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
221377e23a2Schristos   scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
222377e23a2Schristos #endif
223377e23a2Schristos 
224377e23a2Schristos   if (scnhdr_int->s_vaddr != 0)
225377e23a2Schristos     {
226377e23a2Schristos       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
227377e23a2Schristos       /* Do not cut upper 32-bits for 64-bit vma.  */
228377e23a2Schristos #ifndef COFF_WITH_pex64
229377e23a2Schristos       scnhdr_int->s_vaddr &= 0xffffffff;
230377e23a2Schristos #endif
231377e23a2Schristos     }
232377e23a2Schristos 
233377e23a2Schristos #ifndef COFF_NO_HACK_SCNHDR_SIZE
234377e23a2Schristos   /* If this section holds uninitialized data and is from an object file
235377e23a2Schristos      or from an executable image that has not initialized the field,
236377e23a2Schristos      or if the image is an executable file and the physical size is padded,
237377e23a2Schristos      use the virtual size (stored in s_paddr) instead.  */
238377e23a2Schristos   if (scnhdr_int->s_paddr > 0
239377e23a2Schristos       && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
240377e23a2Schristos 	   && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
241377e23a2Schristos           || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
242377e23a2Schristos   /* This code used to set scnhdr_int->s_paddr to 0.  However,
243377e23a2Schristos      coff_set_alignment_hook stores s_paddr in virt_size, which
244377e23a2Schristos      only works if it correctly holds the virtual size of the
245377e23a2Schristos      section.  */
246377e23a2Schristos     scnhdr_int->s_size = scnhdr_int->s_paddr;
247377e23a2Schristos #endif
248377e23a2Schristos }
249377e23a2Schristos 
250377e23a2Schristos static bfd_boolean
251377e23a2Schristos pe_mkobject (bfd * abfd)
252377e23a2Schristos {
253377e23a2Schristos   pe_data_type *pe;
254377e23a2Schristos   bfd_size_type amt = sizeof (pe_data_type);
255377e23a2Schristos 
256377e23a2Schristos   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
257377e23a2Schristos 
258377e23a2Schristos   if (abfd->tdata.pe_obj_data == 0)
259377e23a2Schristos     return FALSE;
260377e23a2Schristos 
261377e23a2Schristos   pe = pe_data (abfd);
262377e23a2Schristos 
263377e23a2Schristos   pe->coff.pe = 1;
264377e23a2Schristos 
265377e23a2Schristos   /* in_reloc_p is architecture dependent.  */
266377e23a2Schristos   pe->in_reloc_p = in_reloc_p;
267377e23a2Schristos 
268377e23a2Schristos   return TRUE;
269377e23a2Schristos }
270377e23a2Schristos 
271377e23a2Schristos /* Create the COFF backend specific information.  */
272377e23a2Schristos 
273377e23a2Schristos static void *
274377e23a2Schristos pe_mkobject_hook (bfd * abfd,
275377e23a2Schristos 		  void * filehdr,
276377e23a2Schristos 		  void * aouthdr ATTRIBUTE_UNUSED)
277377e23a2Schristos {
278377e23a2Schristos   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
279377e23a2Schristos   pe_data_type *pe;
280377e23a2Schristos 
281377e23a2Schristos   if (! pe_mkobject (abfd))
282377e23a2Schristos     return NULL;
283377e23a2Schristos 
284377e23a2Schristos   pe = pe_data (abfd);
285377e23a2Schristos   pe->coff.sym_filepos = internal_f->f_symptr;
286377e23a2Schristos   /* These members communicate important constants about the symbol
287377e23a2Schristos      table to GDB's symbol-reading code.  These `constants'
288377e23a2Schristos      unfortunately vary among coff implementations...  */
289377e23a2Schristos   pe->coff.local_n_btmask = N_BTMASK;
290377e23a2Schristos   pe->coff.local_n_btshft = N_BTSHFT;
291377e23a2Schristos   pe->coff.local_n_tmask = N_TMASK;
292377e23a2Schristos   pe->coff.local_n_tshift = N_TSHIFT;
293377e23a2Schristos   pe->coff.local_symesz = SYMESZ;
294377e23a2Schristos   pe->coff.local_auxesz = AUXESZ;
295377e23a2Schristos   pe->coff.local_linesz = LINESZ;
296377e23a2Schristos 
297377e23a2Schristos   pe->coff.timestamp = internal_f->f_timdat;
298377e23a2Schristos 
299377e23a2Schristos   obj_raw_syment_count (abfd) =
300377e23a2Schristos     obj_conv_table_size (abfd) =
301377e23a2Schristos       internal_f->f_nsyms;
302377e23a2Schristos 
303377e23a2Schristos   pe->real_flags = internal_f->f_flags;
304377e23a2Schristos 
305377e23a2Schristos   if ((internal_f->f_flags & F_DLL) != 0)
306377e23a2Schristos     pe->dll = 1;
307377e23a2Schristos 
308377e23a2Schristos   if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
309377e23a2Schristos     abfd->flags |= HAS_DEBUG;
310377e23a2Schristos 
311377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
312377e23a2Schristos   if (aouthdr)
313377e23a2Schristos     pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe;
314377e23a2Schristos #endif
315377e23a2Schristos 
316377e23a2Schristos #ifdef ARM
317377e23a2Schristos   if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
318377e23a2Schristos     coff_data (abfd) ->flags = 0;
319377e23a2Schristos #endif
320377e23a2Schristos 
321377e23a2Schristos   return (void *) pe;
322377e23a2Schristos }
323377e23a2Schristos 
324377e23a2Schristos static bfd_boolean
325377e23a2Schristos pe_print_private_bfd_data (bfd *abfd, void * vfile)
326377e23a2Schristos {
327377e23a2Schristos   FILE *file = (FILE *) vfile;
328377e23a2Schristos 
329377e23a2Schristos   if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
330377e23a2Schristos     return FALSE;
331377e23a2Schristos 
332377e23a2Schristos   if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
333377e23a2Schristos     return TRUE;
334377e23a2Schristos 
335377e23a2Schristos   fputc ('\n', file);
336377e23a2Schristos 
337377e23a2Schristos   return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
338377e23a2Schristos }
339377e23a2Schristos 
340377e23a2Schristos /* Copy any private info we understand from the input bfd
341377e23a2Schristos    to the output bfd.  */
342377e23a2Schristos 
343377e23a2Schristos static bfd_boolean
344377e23a2Schristos pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
345377e23a2Schristos {
346377e23a2Schristos   /* PR binutils/716: Copy the large address aware flag.
347377e23a2Schristos      XXX: Should we be copying other flags or other fields in the pe_data()
348377e23a2Schristos      structure ?  */
349377e23a2Schristos   if (pe_data (obfd) != NULL
350377e23a2Schristos       && pe_data (ibfd) != NULL
351377e23a2Schristos       && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
352377e23a2Schristos     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
353377e23a2Schristos 
354377e23a2Schristos   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
355377e23a2Schristos     return FALSE;
356377e23a2Schristos 
357377e23a2Schristos   if (pe_saved_coff_bfd_copy_private_bfd_data)
358377e23a2Schristos     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
359377e23a2Schristos 
360377e23a2Schristos   return TRUE;
361377e23a2Schristos }
362377e23a2Schristos 
363377e23a2Schristos #define coff_bfd_copy_private_section_data \
364377e23a2Schristos   _bfd_XX_bfd_copy_private_section_data
365377e23a2Schristos 
366377e23a2Schristos #define coff_get_symbol_info _bfd_XX_get_symbol_info
367377e23a2Schristos 
368377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE
369377e23a2Schristos 
370377e23a2Schristos /* Code to handle Microsoft's Image Library Format.
371377e23a2Schristos    Also known as LINK6 format.
372377e23a2Schristos    Documentation about this format can be found at:
373377e23a2Schristos 
374377e23a2Schristos    http://msdn.microsoft.com/library/specs/pecoff_section8.htm  */
375377e23a2Schristos 
376377e23a2Schristos /* The following constants specify the sizes of the various data
377377e23a2Schristos    structures that we have to create in order to build a bfd describing
378377e23a2Schristos    an ILF object file.  The final "+ 1" in the definitions of SIZEOF_IDATA6
379377e23a2Schristos    and SIZEOF_IDATA7 below is to allow for the possibility that we might
380377e23a2Schristos    need a padding byte in order to ensure 16 bit alignment for the section's
381377e23a2Schristos    contents.
382377e23a2Schristos 
383377e23a2Schristos    The value for SIZEOF_ILF_STRINGS is computed as follows:
384377e23a2Schristos 
385377e23a2Schristos       There will be NUM_ILF_SECTIONS section symbols.  Allow 9 characters
386377e23a2Schristos       per symbol for their names (longest section name is .idata$x).
387377e23a2Schristos 
388377e23a2Schristos       There will be two symbols for the imported value, one the symbol name
389377e23a2Schristos       and one with _imp__ prefixed.  Allowing for the terminating nul's this
390377e23a2Schristos       is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
391377e23a2Schristos 
392377e23a2Schristos       The strings in the string table must start STRING__SIZE_SIZE bytes into
393377e23a2Schristos       the table in order to for the string lookup code in coffgen/coffcode to
394377e23a2Schristos       work.  */
395377e23a2Schristos #define NUM_ILF_RELOCS		8
396377e23a2Schristos #define NUM_ILF_SECTIONS        6
397377e23a2Schristos #define NUM_ILF_SYMS 		(2 + NUM_ILF_SECTIONS)
398377e23a2Schristos 
399377e23a2Schristos #define SIZEOF_ILF_SYMS		 (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
400377e23a2Schristos #define SIZEOF_ILF_SYM_TABLE	 (NUM_ILF_SYMS * sizeof (* vars.sym_table))
401377e23a2Schristos #define SIZEOF_ILF_NATIVE_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.native_syms))
402377e23a2Schristos #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
403377e23a2Schristos #define SIZEOF_ILF_EXT_SYMS	 (NUM_ILF_SYMS * sizeof (* vars.esym_table))
404377e23a2Schristos #define SIZEOF_ILF_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.reltab))
405377e23a2Schristos #define SIZEOF_ILF_INT_RELOCS	 (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
406377e23a2Schristos #define SIZEOF_ILF_STRINGS	 (strlen (symbol_name) * 2 + 8 \
407377e23a2Schristos 					+ 21 + strlen (source_dll) \
408377e23a2Schristos 					+ NUM_ILF_SECTIONS * 9 \
409377e23a2Schristos 					+ STRING_SIZE_SIZE)
410377e23a2Schristos #define SIZEOF_IDATA2		(5 * 4)
411377e23a2Schristos 
412377e23a2Schristos /* For PEx64 idata4 & 5 have thumb size of 8 bytes.  */
413377e23a2Schristos #ifdef COFF_WITH_pex64
414377e23a2Schristos #define SIZEOF_IDATA4		(2 * 4)
415377e23a2Schristos #define SIZEOF_IDATA5		(2 * 4)
416377e23a2Schristos #else
417377e23a2Schristos #define SIZEOF_IDATA4		(1 * 4)
418377e23a2Schristos #define SIZEOF_IDATA5		(1 * 4)
419377e23a2Schristos #endif
420377e23a2Schristos 
421377e23a2Schristos #define SIZEOF_IDATA6		(2 + strlen (symbol_name) + 1 + 1)
422377e23a2Schristos #define SIZEOF_IDATA7		(strlen (source_dll) + 1 + 1)
423377e23a2Schristos #define SIZEOF_ILF_SECTIONS     (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
424377e23a2Schristos 
425377e23a2Schristos #define ILF_DATA_SIZE				\
426377e23a2Schristos     + SIZEOF_ILF_SYMS				\
427377e23a2Schristos     + SIZEOF_ILF_SYM_TABLE			\
428377e23a2Schristos     + SIZEOF_ILF_NATIVE_SYMS			\
429377e23a2Schristos     + SIZEOF_ILF_SYM_PTR_TABLE			\
430377e23a2Schristos     + SIZEOF_ILF_EXT_SYMS			\
431377e23a2Schristos     + SIZEOF_ILF_RELOCS				\
432377e23a2Schristos     + SIZEOF_ILF_INT_RELOCS			\
433377e23a2Schristos     + SIZEOF_ILF_STRINGS			\
434377e23a2Schristos     + SIZEOF_IDATA2				\
435377e23a2Schristos     + SIZEOF_IDATA4				\
436377e23a2Schristos     + SIZEOF_IDATA5				\
437377e23a2Schristos     + SIZEOF_IDATA6				\
438377e23a2Schristos     + SIZEOF_IDATA7				\
439377e23a2Schristos     + SIZEOF_ILF_SECTIONS			\
440377e23a2Schristos     + MAX_TEXT_SECTION_SIZE
441377e23a2Schristos 
442377e23a2Schristos /* Create an empty relocation against the given symbol.  */
443377e23a2Schristos 
444377e23a2Schristos static void
445377e23a2Schristos pe_ILF_make_a_symbol_reloc (pe_ILF_vars *               vars,
446377e23a2Schristos 			    bfd_vma                     address,
447377e23a2Schristos 			    bfd_reloc_code_real_type    reloc,
448377e23a2Schristos 			    struct bfd_symbol **  	sym,
449377e23a2Schristos 			    unsigned int                sym_index)
450377e23a2Schristos {
451377e23a2Schristos   arelent * entry;
452377e23a2Schristos   struct internal_reloc * internal;
453377e23a2Schristos 
454377e23a2Schristos   entry = vars->reltab + vars->relcount;
455377e23a2Schristos   internal = vars->int_reltab + vars->relcount;
456377e23a2Schristos 
457377e23a2Schristos   entry->address     = address;
458377e23a2Schristos   entry->addend      = 0;
459377e23a2Schristos   entry->howto       = bfd_reloc_type_lookup (vars->abfd, reloc);
460377e23a2Schristos   entry->sym_ptr_ptr = sym;
461377e23a2Schristos 
462377e23a2Schristos   internal->r_vaddr  = address;
463377e23a2Schristos   internal->r_symndx = sym_index;
464377e23a2Schristos   internal->r_type   = entry->howto->type;
465377e23a2Schristos 
466377e23a2Schristos   vars->relcount ++;
467377e23a2Schristos 
468377e23a2Schristos   BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
469377e23a2Schristos }
470377e23a2Schristos 
471377e23a2Schristos /* Create an empty relocation against the given section.  */
472377e23a2Schristos 
473377e23a2Schristos static void
474377e23a2Schristos pe_ILF_make_a_reloc (pe_ILF_vars *             vars,
475377e23a2Schristos 		     bfd_vma                   address,
476377e23a2Schristos 		     bfd_reloc_code_real_type  reloc,
477377e23a2Schristos 		     asection_ptr              sec)
478377e23a2Schristos {
479377e23a2Schristos   pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
480377e23a2Schristos 			      coff_section_data (vars->abfd, sec)->i);
481377e23a2Schristos }
482377e23a2Schristos 
483377e23a2Schristos /* Move the queued relocs into the given section.  */
484377e23a2Schristos 
485377e23a2Schristos static void
486377e23a2Schristos pe_ILF_save_relocs (pe_ILF_vars * vars,
487377e23a2Schristos 		    asection_ptr  sec)
488377e23a2Schristos {
489377e23a2Schristos   /* Make sure that there is somewhere to store the internal relocs.  */
490377e23a2Schristos   if (coff_section_data (vars->abfd, sec) == NULL)
491377e23a2Schristos     /* We should probably return an error indication here.  */
492377e23a2Schristos     abort ();
493377e23a2Schristos 
494377e23a2Schristos   coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
495377e23a2Schristos   coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
496377e23a2Schristos 
497377e23a2Schristos   sec->relocation  = vars->reltab;
498377e23a2Schristos   sec->reloc_count = vars->relcount;
499377e23a2Schristos   sec->flags      |= SEC_RELOC;
500377e23a2Schristos 
501377e23a2Schristos   vars->reltab     += vars->relcount;
502377e23a2Schristos   vars->int_reltab += vars->relcount;
503377e23a2Schristos   vars->relcount   = 0;
504377e23a2Schristos 
505377e23a2Schristos   BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
506377e23a2Schristos }
507377e23a2Schristos 
508377e23a2Schristos /* Create a global symbol and add it to the relevant tables.  */
509377e23a2Schristos 
510377e23a2Schristos static void
511377e23a2Schristos pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
512377e23a2Schristos 		      const char *   prefix,
513377e23a2Schristos 		      const char *   symbol_name,
514377e23a2Schristos 		      asection_ptr   section,
515377e23a2Schristos 		      flagword       extra_flags)
516377e23a2Schristos {
517377e23a2Schristos   coff_symbol_type * sym;
518377e23a2Schristos   combined_entry_type * ent;
519377e23a2Schristos   SYMENT * esym;
520377e23a2Schristos   unsigned short sclass;
521377e23a2Schristos 
522377e23a2Schristos   if (extra_flags & BSF_LOCAL)
523377e23a2Schristos     sclass = C_STAT;
524377e23a2Schristos   else
525377e23a2Schristos     sclass = C_EXT;
526377e23a2Schristos 
527377e23a2Schristos #ifdef THUMBPEMAGIC
528377e23a2Schristos   if (vars->magic == THUMBPEMAGIC)
529377e23a2Schristos     {
530377e23a2Schristos       if (extra_flags & BSF_FUNCTION)
531377e23a2Schristos 	sclass = C_THUMBEXTFUNC;
532377e23a2Schristos       else if (extra_flags & BSF_LOCAL)
533377e23a2Schristos 	sclass = C_THUMBSTAT;
534377e23a2Schristos       else
535377e23a2Schristos 	sclass = C_THUMBEXT;
536377e23a2Schristos     }
537377e23a2Schristos #endif
538377e23a2Schristos 
539377e23a2Schristos   BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
540377e23a2Schristos 
541377e23a2Schristos   sym = vars->sym_ptr;
542377e23a2Schristos   ent = vars->native_ptr;
543377e23a2Schristos   esym = vars->esym_ptr;
544377e23a2Schristos 
545377e23a2Schristos   /* Copy the symbol's name into the string table.  */
546377e23a2Schristos   sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
547377e23a2Schristos 
548377e23a2Schristos   if (section == NULL)
549*48596154Schristos     section = bfd_und_section_ptr;
550377e23a2Schristos 
551377e23a2Schristos   /* Initialise the external symbol.  */
552377e23a2Schristos   H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
553377e23a2Schristos 	    esym->e.e.e_offset);
554377e23a2Schristos   H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
555377e23a2Schristos   esym->e_sclass[0] = sclass;
556377e23a2Schristos 
557377e23a2Schristos   /* The following initialisations are unnecessary - the memory is
558377e23a2Schristos      zero initialised.  They are just kept here as reminders.  */
559377e23a2Schristos 
560377e23a2Schristos   /* Initialise the internal symbol structure.  */
561377e23a2Schristos   ent->u.syment.n_sclass          = sclass;
562377e23a2Schristos   ent->u.syment.n_scnum           = section->target_index;
563377e23a2Schristos   ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
564377e23a2Schristos 
565377e23a2Schristos   sym->symbol.the_bfd = vars->abfd;
566377e23a2Schristos   sym->symbol.name    = vars->string_ptr;
567377e23a2Schristos   sym->symbol.flags   = BSF_EXPORT | BSF_GLOBAL | extra_flags;
568377e23a2Schristos   sym->symbol.section = section;
569377e23a2Schristos   sym->native         = ent;
570377e23a2Schristos 
571377e23a2Schristos   * vars->table_ptr = vars->sym_index;
572377e23a2Schristos   * vars->sym_ptr_ptr = sym;
573377e23a2Schristos 
574377e23a2Schristos   /* Adjust pointers for the next symbol.  */
575377e23a2Schristos   vars->sym_index ++;
576377e23a2Schristos   vars->sym_ptr ++;
577377e23a2Schristos   vars->sym_ptr_ptr ++;
578377e23a2Schristos   vars->table_ptr ++;
579377e23a2Schristos   vars->native_ptr ++;
580377e23a2Schristos   vars->esym_ptr ++;
581377e23a2Schristos   vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
582377e23a2Schristos 
583377e23a2Schristos   BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
584377e23a2Schristos }
585377e23a2Schristos 
586377e23a2Schristos /* Create a section.  */
587377e23a2Schristos 
588377e23a2Schristos static asection_ptr
589377e23a2Schristos pe_ILF_make_a_section (pe_ILF_vars * vars,
590377e23a2Schristos 		       const char *  name,
591377e23a2Schristos 		       unsigned int  size,
592377e23a2Schristos 		       flagword      extra_flags)
593377e23a2Schristos {
594377e23a2Schristos   asection_ptr sec;
595377e23a2Schristos   flagword     flags;
596377e23a2Schristos 
597377e23a2Schristos   sec = bfd_make_section_old_way (vars->abfd, name);
598377e23a2Schristos   if (sec == NULL)
599377e23a2Schristos     return NULL;
600377e23a2Schristos 
601377e23a2Schristos   flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
602377e23a2Schristos 
603377e23a2Schristos   bfd_set_section_flags (vars->abfd, sec, flags | extra_flags);
604377e23a2Schristos 
605377e23a2Schristos   bfd_set_section_alignment (vars->abfd, sec, 2);
606377e23a2Schristos 
607377e23a2Schristos   /* Check that we will not run out of space.  */
608377e23a2Schristos   BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
609377e23a2Schristos 
610377e23a2Schristos   /* Set the section size and contents.  The actual
611377e23a2Schristos      contents are filled in by our parent.  */
612377e23a2Schristos   bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size);
613377e23a2Schristos   sec->contents = vars->data;
614377e23a2Schristos   sec->target_index = vars->sec_index ++;
615377e23a2Schristos 
616377e23a2Schristos   /* Advance data pointer in the vars structure.  */
617377e23a2Schristos   vars->data += size;
618377e23a2Schristos 
619377e23a2Schristos   /* Skip the padding byte if it was not needed.
620377e23a2Schristos      The logic here is that if the string length is odd,
621377e23a2Schristos      then the entire string length, including the null byte,
622377e23a2Schristos      is even and so the extra, padding byte, is not needed.  */
623377e23a2Schristos   if (size & 1)
624377e23a2Schristos     vars->data --;
625377e23a2Schristos 
626377e23a2Schristos   /* Create a coff_section_tdata structure for our use.  */
627377e23a2Schristos   sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
628377e23a2Schristos   vars->data += sizeof (struct coff_section_tdata);
629377e23a2Schristos 
630377e23a2Schristos   BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
631377e23a2Schristos 
632377e23a2Schristos   /* Create a symbol to refer to this section.  */
633377e23a2Schristos   pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
634377e23a2Schristos 
635377e23a2Schristos   /* Cache the index to the symbol in the coff_section_data structure.  */
636377e23a2Schristos   coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
637377e23a2Schristos 
638377e23a2Schristos   return sec;
639377e23a2Schristos }
640377e23a2Schristos 
641377e23a2Schristos /* This structure contains the code that goes into the .text section
642377e23a2Schristos    in order to perform a jump into the DLL lookup table.  The entries
643377e23a2Schristos    in the table are index by the magic number used to represent the
644377e23a2Schristos    machine type in the PE file.  The contents of the data[] arrays in
645377e23a2Schristos    these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
646377e23a2Schristos    The SIZE field says how many bytes in the DATA array are actually
647377e23a2Schristos    used.  The OFFSET field says where in the data array the address
648377e23a2Schristos    of the .idata$5 section should be placed.  */
649377e23a2Schristos #define MAX_TEXT_SECTION_SIZE 32
650377e23a2Schristos 
651377e23a2Schristos typedef struct
652377e23a2Schristos {
653377e23a2Schristos   unsigned short magic;
654377e23a2Schristos   unsigned char  data[MAX_TEXT_SECTION_SIZE];
655377e23a2Schristos   unsigned int   size;
656377e23a2Schristos   unsigned int   offset;
657377e23a2Schristos }
658377e23a2Schristos jump_table;
659377e23a2Schristos 
660377e23a2Schristos static jump_table jtab[] =
661377e23a2Schristos {
662377e23a2Schristos #ifdef I386MAGIC
663377e23a2Schristos   { I386MAGIC,
664377e23a2Schristos     { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
665377e23a2Schristos     8, 2
666377e23a2Schristos   },
667377e23a2Schristos #endif
668377e23a2Schristos 
669377e23a2Schristos #ifdef AMD64MAGIC
670377e23a2Schristos   { AMD64MAGIC,
671377e23a2Schristos     { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
672377e23a2Schristos     8, 2
673377e23a2Schristos   },
674377e23a2Schristos #endif
675377e23a2Schristos 
676377e23a2Schristos #ifdef  MC68MAGIC
677377e23a2Schristos   { MC68MAGIC,
678377e23a2Schristos     { /* XXX fill me in */ },
679377e23a2Schristos     0, 0
680377e23a2Schristos   },
681377e23a2Schristos #endif
682377e23a2Schristos 
683377e23a2Schristos #ifdef  MIPS_ARCH_MAGIC_WINCE
684377e23a2Schristos   { MIPS_ARCH_MAGIC_WINCE,
685377e23a2Schristos     { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
686377e23a2Schristos       0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
687377e23a2Schristos     16, 0
688377e23a2Schristos   },
689377e23a2Schristos #endif
690377e23a2Schristos 
691377e23a2Schristos #ifdef  SH_ARCH_MAGIC_WINCE
692377e23a2Schristos   { SH_ARCH_MAGIC_WINCE,
693377e23a2Schristos     { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
694377e23a2Schristos       0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
695377e23a2Schristos     12, 8
696377e23a2Schristos   },
697377e23a2Schristos #endif
698377e23a2Schristos 
699377e23a2Schristos #ifdef  ARMPEMAGIC
700377e23a2Schristos   { ARMPEMAGIC,
701377e23a2Schristos     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
702377e23a2Schristos       0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
703377e23a2Schristos     12, 8
704377e23a2Schristos   },
705377e23a2Schristos #endif
706377e23a2Schristos 
707377e23a2Schristos #ifdef  THUMBPEMAGIC
708377e23a2Schristos   { THUMBPEMAGIC,
709377e23a2Schristos     { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
710377e23a2Schristos       0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
711377e23a2Schristos     16, 12
712377e23a2Schristos   },
713377e23a2Schristos #endif
714377e23a2Schristos   { 0, { 0 }, 0, 0 }
715377e23a2Schristos };
716377e23a2Schristos 
717377e23a2Schristos #ifndef NUM_ENTRIES
718377e23a2Schristos #define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
719377e23a2Schristos #endif
720377e23a2Schristos 
721377e23a2Schristos /* Build a full BFD from the information supplied in a ILF object.  */
722377e23a2Schristos 
723377e23a2Schristos static bfd_boolean
724377e23a2Schristos pe_ILF_build_a_bfd (bfd *           abfd,
725377e23a2Schristos 		    unsigned int    magic,
726377e23a2Schristos 		    char *          symbol_name,
727377e23a2Schristos 		    char *          source_dll,
728377e23a2Schristos 		    unsigned int    ordinal,
729377e23a2Schristos 		    unsigned int    types)
730377e23a2Schristos {
731377e23a2Schristos   bfd_byte *               ptr;
732377e23a2Schristos   pe_ILF_vars              vars;
733377e23a2Schristos   struct internal_filehdr  internal_f;
734377e23a2Schristos   unsigned int             import_type;
735377e23a2Schristos   unsigned int             import_name_type;
736377e23a2Schristos   asection_ptr             id4, id5, id6 = NULL, text = NULL;
737377e23a2Schristos   coff_symbol_type **      imp_sym;
738377e23a2Schristos   unsigned int             imp_index;
739377e23a2Schristos 
740377e23a2Schristos   /* Decode and verify the types field of the ILF structure.  */
741377e23a2Schristos   import_type = types & 0x3;
742377e23a2Schristos   import_name_type = (types & 0x1c) >> 2;
743377e23a2Schristos 
744377e23a2Schristos   switch (import_type)
745377e23a2Schristos     {
746377e23a2Schristos     case IMPORT_CODE:
747377e23a2Schristos     case IMPORT_DATA:
748377e23a2Schristos       break;
749377e23a2Schristos 
750377e23a2Schristos     case IMPORT_CONST:
751377e23a2Schristos       /* XXX code yet to be written.  */
752377e23a2Schristos       _bfd_error_handler (_("%B: Unhandled import type; %x"),
753377e23a2Schristos 			  abfd, import_type);
754377e23a2Schristos       return FALSE;
755377e23a2Schristos 
756377e23a2Schristos     default:
757377e23a2Schristos       _bfd_error_handler (_("%B: Unrecognised import type; %x"),
758377e23a2Schristos 			  abfd, import_type);
759377e23a2Schristos       return FALSE;
760377e23a2Schristos     }
761377e23a2Schristos 
762377e23a2Schristos   switch (import_name_type)
763377e23a2Schristos     {
764377e23a2Schristos     case IMPORT_ORDINAL:
765377e23a2Schristos     case IMPORT_NAME:
766377e23a2Schristos     case IMPORT_NAME_NOPREFIX:
767377e23a2Schristos     case IMPORT_NAME_UNDECORATE:
768377e23a2Schristos       break;
769377e23a2Schristos 
770377e23a2Schristos     default:
771377e23a2Schristos       _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
772377e23a2Schristos 			  abfd, import_name_type);
773377e23a2Schristos       return FALSE;
774377e23a2Schristos     }
775377e23a2Schristos 
776377e23a2Schristos   /* Initialise local variables.
777377e23a2Schristos 
778377e23a2Schristos      Note these are kept in a structure rather than being
779377e23a2Schristos      declared as statics since bfd frowns on global variables.
780377e23a2Schristos 
781377e23a2Schristos      We are going to construct the contents of the BFD in memory,
782377e23a2Schristos      so allocate all the space that we will need right now.  */
783377e23a2Schristos   vars.bim
784377e23a2Schristos     = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
785377e23a2Schristos   if (vars.bim == NULL)
786377e23a2Schristos     return FALSE;
787377e23a2Schristos 
788377e23a2Schristos   ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
789377e23a2Schristos   vars.bim->buffer = ptr;
790377e23a2Schristos   vars.bim->size   = ILF_DATA_SIZE;
791377e23a2Schristos   if (ptr == NULL)
792377e23a2Schristos     goto error_return;
793377e23a2Schristos 
794377e23a2Schristos   /* Initialise the pointers to regions of the memory and the
795377e23a2Schristos      other contents of the pe_ILF_vars structure as well.  */
796377e23a2Schristos   vars.sym_cache = (coff_symbol_type *) ptr;
797377e23a2Schristos   vars.sym_ptr   = (coff_symbol_type *) ptr;
798377e23a2Schristos   vars.sym_index = 0;
799377e23a2Schristos   ptr += SIZEOF_ILF_SYMS;
800377e23a2Schristos 
801377e23a2Schristos   vars.sym_table = (unsigned int *) ptr;
802377e23a2Schristos   vars.table_ptr = (unsigned int *) ptr;
803377e23a2Schristos   ptr += SIZEOF_ILF_SYM_TABLE;
804377e23a2Schristos 
805377e23a2Schristos   vars.native_syms = (combined_entry_type *) ptr;
806377e23a2Schristos   vars.native_ptr  = (combined_entry_type *) ptr;
807377e23a2Schristos   ptr += SIZEOF_ILF_NATIVE_SYMS;
808377e23a2Schristos 
809377e23a2Schristos   vars.sym_ptr_table = (coff_symbol_type **) ptr;
810377e23a2Schristos   vars.sym_ptr_ptr   = (coff_symbol_type **) ptr;
811377e23a2Schristos   ptr += SIZEOF_ILF_SYM_PTR_TABLE;
812377e23a2Schristos 
813377e23a2Schristos   vars.esym_table = (SYMENT *) ptr;
814377e23a2Schristos   vars.esym_ptr   = (SYMENT *) ptr;
815377e23a2Schristos   ptr += SIZEOF_ILF_EXT_SYMS;
816377e23a2Schristos 
817377e23a2Schristos   vars.reltab   = (arelent *) ptr;
818377e23a2Schristos   vars.relcount = 0;
819377e23a2Schristos   ptr += SIZEOF_ILF_RELOCS;
820377e23a2Schristos 
821377e23a2Schristos   vars.int_reltab  = (struct internal_reloc *) ptr;
822377e23a2Schristos   ptr += SIZEOF_ILF_INT_RELOCS;
823377e23a2Schristos 
824377e23a2Schristos   vars.string_table = (char *) ptr;
825377e23a2Schristos   vars.string_ptr   = (char *) ptr + STRING_SIZE_SIZE;
826377e23a2Schristos   ptr += SIZEOF_ILF_STRINGS;
827377e23a2Schristos   vars.end_string_ptr = (char *) ptr;
828377e23a2Schristos 
829377e23a2Schristos   /* The remaining space in bim->buffer is used
830377e23a2Schristos      by the pe_ILF_make_a_section() function.  */
831377e23a2Schristos   vars.data = ptr;
832377e23a2Schristos   vars.abfd = abfd;
833377e23a2Schristos   vars.sec_index = 0;
834377e23a2Schristos   vars.magic = magic;
835377e23a2Schristos 
836377e23a2Schristos   /* Create the initial .idata$<n> sections:
837377e23a2Schristos      [.idata$2:  Import Directory Table -- not needed]
838377e23a2Schristos      .idata$4:  Import Lookup Table
839377e23a2Schristos      .idata$5:  Import Address Table
840377e23a2Schristos 
841377e23a2Schristos      Note we do not create a .idata$3 section as this is
842377e23a2Schristos      created for us by the linker script.  */
843377e23a2Schristos   id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
844377e23a2Schristos   id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
845377e23a2Schristos   if (id4 == NULL || id5 == NULL)
846377e23a2Schristos     goto error_return;
847377e23a2Schristos 
848377e23a2Schristos   /* Fill in the contents of these sections.  */
849377e23a2Schristos   if (import_name_type == IMPORT_ORDINAL)
850377e23a2Schristos     {
851377e23a2Schristos       if (ordinal == 0)
852377e23a2Schristos 	/* XXX - treat as IMPORT_NAME ??? */
853377e23a2Schristos 	abort ();
854377e23a2Schristos 
855377e23a2Schristos #ifdef COFF_WITH_pex64
856377e23a2Schristos       ((unsigned int *) id4->contents)[0] = ordinal;
857377e23a2Schristos       ((unsigned int *) id4->contents)[1] = 0x80000000;
858377e23a2Schristos       ((unsigned int *) id5->contents)[0] = ordinal;
859377e23a2Schristos       ((unsigned int *) id5->contents)[1] = 0x80000000;
860377e23a2Schristos #else
861377e23a2Schristos       * (unsigned int *) id4->contents = ordinal | 0x80000000;
862377e23a2Schristos       * (unsigned int *) id5->contents = ordinal | 0x80000000;
863377e23a2Schristos #endif
864377e23a2Schristos     }
865377e23a2Schristos   else
866377e23a2Schristos     {
867377e23a2Schristos       char * symbol;
868377e23a2Schristos       unsigned int len;
869377e23a2Schristos 
870377e23a2Schristos       /* Create .idata$6 - the Hint Name Table.  */
871377e23a2Schristos       id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
872377e23a2Schristos       if (id6 == NULL)
873377e23a2Schristos 	goto error_return;
874377e23a2Schristos 
875377e23a2Schristos       /* If necessary, trim the import symbol name.  */
876377e23a2Schristos       symbol = symbol_name;
877377e23a2Schristos 
878377e23a2Schristos       /* As used by MS compiler, '_', '@', and '?' are alternative
879377e23a2Schristos 	 forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
880377e23a2Schristos 	 '@' used for fastcall (in C),  '_' everywhere else.  Only one
881377e23a2Schristos 	 of these is used for a symbol.  We strip this leading char for
882377e23a2Schristos 	 IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
883377e23a2Schristos 	 PE COFF 6.0 spec (section 8.3, Import Name Type).  */
884377e23a2Schristos 
885377e23a2Schristos       if (import_name_type != IMPORT_NAME)
886377e23a2Schristos 	{
887377e23a2Schristos 	  char c = symbol[0];
888*48596154Schristos 
889*48596154Schristos 	  /* Check that we don't remove for targets with empty
890*48596154Schristos 	     USER_LABEL_PREFIX the leading underscore.  */
891*48596154Schristos 	  if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
892*48596154Schristos 	      || c == '@' || c == '?')
893377e23a2Schristos 	    symbol++;
894377e23a2Schristos 	}
895377e23a2Schristos 
896377e23a2Schristos       len = strlen (symbol);
897377e23a2Schristos       if (import_name_type == IMPORT_NAME_UNDECORATE)
898377e23a2Schristos 	{
899377e23a2Schristos 	  /* Truncate at the first '@'.  */
900377e23a2Schristos 	  char *at = strchr (symbol, '@');
901377e23a2Schristos 
902377e23a2Schristos 	  if (at != NULL)
903377e23a2Schristos 	    len = at - symbol;
904377e23a2Schristos 	}
905377e23a2Schristos 
906377e23a2Schristos       id6->contents[0] = ordinal & 0xff;
907377e23a2Schristos       id6->contents[1] = ordinal >> 8;
908377e23a2Schristos 
909377e23a2Schristos       memcpy ((char *) id6->contents + 2, symbol, len);
910377e23a2Schristos       id6->contents[len + 2] = '\0';
911377e23a2Schristos     }
912377e23a2Schristos 
913377e23a2Schristos   if (import_name_type != IMPORT_ORDINAL)
914377e23a2Schristos     {
915377e23a2Schristos       pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
916377e23a2Schristos       pe_ILF_save_relocs (&vars, id4);
917377e23a2Schristos 
918377e23a2Schristos       pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
919377e23a2Schristos       pe_ILF_save_relocs (&vars, id5);
920377e23a2Schristos     }
921377e23a2Schristos 
922377e23a2Schristos   /* Create extra sections depending upon the type of import we are dealing with.  */
923377e23a2Schristos   switch (import_type)
924377e23a2Schristos     {
925377e23a2Schristos       int i;
926377e23a2Schristos 
927377e23a2Schristos     case IMPORT_CODE:
928377e23a2Schristos       /* Create a .text section.
929377e23a2Schristos 	 First we need to look up its contents in the jump table.  */
930377e23a2Schristos       for (i = NUM_ENTRIES (jtab); i--;)
931377e23a2Schristos 	{
932377e23a2Schristos 	  if (jtab[i].size == 0)
933377e23a2Schristos 	    continue;
934377e23a2Schristos 	  if (jtab[i].magic == magic)
935377e23a2Schristos 	    break;
936377e23a2Schristos 	}
937377e23a2Schristos       /* If we did not find a matching entry something is wrong.  */
938377e23a2Schristos       if (i < 0)
939377e23a2Schristos 	abort ();
940377e23a2Schristos 
941377e23a2Schristos       /* Create the .text section.  */
942377e23a2Schristos       text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
943377e23a2Schristos       if (text == NULL)
944377e23a2Schristos 	goto error_return;
945377e23a2Schristos 
946377e23a2Schristos       /* Copy in the jump code.  */
947377e23a2Schristos       memcpy (text->contents, jtab[i].data, jtab[i].size);
948377e23a2Schristos 
949377e23a2Schristos       /* Create an import symbol.  */
950377e23a2Schristos       pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
951377e23a2Schristos       imp_sym   = vars.sym_ptr_ptr - 1;
952377e23a2Schristos       imp_index = vars.sym_index - 1;
953377e23a2Schristos 
954377e23a2Schristos       /* Create a reloc for the data in the text section.  */
955377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
956377e23a2Schristos       if (magic == MIPS_ARCH_MAGIC_WINCE)
957377e23a2Schristos 	{
958377e23a2Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
959377e23a2Schristos 				      (struct bfd_symbol **) imp_sym,
960377e23a2Schristos 				      imp_index);
961377e23a2Schristos 	  pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
962377e23a2Schristos 	  pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
963377e23a2Schristos 				      (struct bfd_symbol **) imp_sym,
964377e23a2Schristos 				      imp_index);
965377e23a2Schristos 	}
966377e23a2Schristos       else
967377e23a2Schristos #endif
968377e23a2Schristos 	pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
969377e23a2Schristos 				    BFD_RELOC_32, (asymbol **) imp_sym,
970377e23a2Schristos 				    imp_index);
971377e23a2Schristos 
972377e23a2Schristos       pe_ILF_save_relocs (& vars, text);
973377e23a2Schristos       break;
974377e23a2Schristos 
975377e23a2Schristos     case IMPORT_DATA:
976377e23a2Schristos       break;
977377e23a2Schristos 
978377e23a2Schristos     default:
979377e23a2Schristos       /* XXX code not yet written.  */
980377e23a2Schristos       abort ();
981377e23a2Schristos     }
982377e23a2Schristos 
983377e23a2Schristos   /* Initialise the bfd.  */
984377e23a2Schristos   memset (& internal_f, 0, sizeof (internal_f));
985377e23a2Schristos 
986377e23a2Schristos   internal_f.f_magic  = magic;
987377e23a2Schristos   internal_f.f_symptr = 0;
988377e23a2Schristos   internal_f.f_nsyms  = 0;
989377e23a2Schristos   internal_f.f_flags  = F_AR32WR | F_LNNO; /* XXX is this correct ?  */
990377e23a2Schristos 
991377e23a2Schristos   if (   ! bfd_set_start_address (abfd, (bfd_vma) 0)
992377e23a2Schristos       || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
993377e23a2Schristos     goto error_return;
994377e23a2Schristos 
995377e23a2Schristos   if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
996377e23a2Schristos     goto error_return;
997377e23a2Schristos 
998377e23a2Schristos   coff_data (abfd)->pe = 1;
999377e23a2Schristos #ifdef THUMBPEMAGIC
1000377e23a2Schristos   if (vars.magic == THUMBPEMAGIC)
1001377e23a2Schristos     /* Stop some linker warnings about thumb code not supporting interworking.  */
1002377e23a2Schristos     coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
1003377e23a2Schristos #endif
1004377e23a2Schristos 
1005377e23a2Schristos   /* Switch from file contents to memory contents.  */
1006377e23a2Schristos   bfd_cache_close (abfd);
1007377e23a2Schristos 
1008377e23a2Schristos   abfd->iostream = (void *) vars.bim;
1009377e23a2Schristos   abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
1010377e23a2Schristos   abfd->iovec = &_bfd_memory_iovec;
1011377e23a2Schristos   abfd->where = 0;
1012377e23a2Schristos   abfd->origin = 0;
1013377e23a2Schristos   obj_sym_filepos (abfd) = 0;
1014377e23a2Schristos 
1015377e23a2Schristos   /* Now create a symbol describing the imported value.  */
1016377e23a2Schristos   switch (import_type)
1017377e23a2Schristos     {
1018377e23a2Schristos     case IMPORT_CODE:
1019377e23a2Schristos       pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
1020377e23a2Schristos 			    BSF_NOT_AT_END | BSF_FUNCTION);
1021377e23a2Schristos 
1022377e23a2Schristos       /* Create an import symbol for the DLL, without the
1023377e23a2Schristos        .dll suffix.  */
1024377e23a2Schristos       ptr = (bfd_byte *) strrchr (source_dll, '.');
1025377e23a2Schristos       if (ptr)
1026377e23a2Schristos 	* ptr = 0;
1027377e23a2Schristos       pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
1028377e23a2Schristos       if (ptr)
1029377e23a2Schristos 	* ptr = '.';
1030377e23a2Schristos       break;
1031377e23a2Schristos 
1032377e23a2Schristos     case IMPORT_DATA:
1033377e23a2Schristos       /* Nothing to do here.  */
1034377e23a2Schristos       break;
1035377e23a2Schristos 
1036377e23a2Schristos     default:
1037377e23a2Schristos       /* XXX code not yet written.  */
1038377e23a2Schristos       abort ();
1039377e23a2Schristos     }
1040377e23a2Schristos 
1041377e23a2Schristos   /* Point the bfd at the symbol table.  */
1042377e23a2Schristos   obj_symbols (abfd) = vars.sym_cache;
1043377e23a2Schristos   bfd_get_symcount (abfd) = vars.sym_index;
1044377e23a2Schristos 
1045377e23a2Schristos   obj_raw_syments (abfd) = vars.native_syms;
1046377e23a2Schristos   obj_raw_syment_count (abfd) = vars.sym_index;
1047377e23a2Schristos 
1048377e23a2Schristos   obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1049377e23a2Schristos   obj_coff_keep_syms (abfd) = TRUE;
1050377e23a2Schristos 
1051377e23a2Schristos   obj_convert (abfd) = vars.sym_table;
1052377e23a2Schristos   obj_conv_table_size (abfd) = vars.sym_index;
1053377e23a2Schristos 
1054377e23a2Schristos   obj_coff_strings (abfd) = vars.string_table;
1055377e23a2Schristos   obj_coff_keep_strings (abfd) = TRUE;
1056377e23a2Schristos 
1057377e23a2Schristos   abfd->flags |= HAS_SYMS;
1058377e23a2Schristos 
1059377e23a2Schristos   return TRUE;
1060377e23a2Schristos 
1061377e23a2Schristos  error_return:
1062377e23a2Schristos   if (vars.bim->buffer != NULL)
1063377e23a2Schristos     free (vars.bim->buffer);
1064377e23a2Schristos   free (vars.bim);
1065377e23a2Schristos   return FALSE;
1066377e23a2Schristos }
1067377e23a2Schristos 
1068377e23a2Schristos /* We have detected a Image Library Format archive element.
1069377e23a2Schristos    Decode the element and return the appropriate target.  */
1070377e23a2Schristos 
1071377e23a2Schristos static const bfd_target *
1072377e23a2Schristos pe_ILF_object_p (bfd * abfd)
1073377e23a2Schristos {
1074377e23a2Schristos   bfd_byte        buffer[16];
1075377e23a2Schristos   bfd_byte *      ptr;
1076377e23a2Schristos   char *          symbol_name;
1077377e23a2Schristos   char *          source_dll;
1078377e23a2Schristos   unsigned int    machine;
1079377e23a2Schristos   bfd_size_type   size;
1080377e23a2Schristos   unsigned int    ordinal;
1081377e23a2Schristos   unsigned int    types;
1082377e23a2Schristos   unsigned int    magic;
1083377e23a2Schristos 
1084377e23a2Schristos   /* Upon entry the first four buyes of the ILF header have
1085377e23a2Schristos       already been read.  Now read the rest of the header.  */
1086377e23a2Schristos   if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16)
1087377e23a2Schristos     return NULL;
1088377e23a2Schristos 
1089377e23a2Schristos   ptr = buffer;
1090377e23a2Schristos 
1091377e23a2Schristos   /*  We do not bother to check the version number.
1092377e23a2Schristos       version = H_GET_16 (abfd, ptr);  */
1093377e23a2Schristos   ptr += 2;
1094377e23a2Schristos 
1095377e23a2Schristos   machine = H_GET_16 (abfd, ptr);
1096377e23a2Schristos   ptr += 2;
1097377e23a2Schristos 
1098377e23a2Schristos   /* Check that the machine type is recognised.  */
1099377e23a2Schristos   magic = 0;
1100377e23a2Schristos 
1101377e23a2Schristos   switch (machine)
1102377e23a2Schristos     {
1103377e23a2Schristos     case IMAGE_FILE_MACHINE_UNKNOWN:
1104377e23a2Schristos     case IMAGE_FILE_MACHINE_ALPHA:
1105377e23a2Schristos     case IMAGE_FILE_MACHINE_ALPHA64:
1106377e23a2Schristos     case IMAGE_FILE_MACHINE_IA64:
1107377e23a2Schristos       break;
1108377e23a2Schristos 
1109377e23a2Schristos     case IMAGE_FILE_MACHINE_I386:
1110377e23a2Schristos #ifdef I386MAGIC
1111377e23a2Schristos       magic = I386MAGIC;
1112377e23a2Schristos #endif
1113377e23a2Schristos       break;
1114377e23a2Schristos 
1115377e23a2Schristos     case IMAGE_FILE_MACHINE_AMD64:
1116377e23a2Schristos #ifdef AMD64MAGIC
1117377e23a2Schristos       magic = AMD64MAGIC;
1118377e23a2Schristos #endif
1119377e23a2Schristos       break;
1120377e23a2Schristos 
1121377e23a2Schristos     case IMAGE_FILE_MACHINE_M68K:
1122377e23a2Schristos #ifdef MC68AGIC
1123377e23a2Schristos       magic = MC68MAGIC;
1124377e23a2Schristos #endif
1125377e23a2Schristos       break;
1126377e23a2Schristos 
1127377e23a2Schristos     case IMAGE_FILE_MACHINE_R3000:
1128377e23a2Schristos     case IMAGE_FILE_MACHINE_R4000:
1129377e23a2Schristos     case IMAGE_FILE_MACHINE_R10000:
1130377e23a2Schristos 
1131377e23a2Schristos     case IMAGE_FILE_MACHINE_MIPS16:
1132377e23a2Schristos     case IMAGE_FILE_MACHINE_MIPSFPU:
1133377e23a2Schristos     case IMAGE_FILE_MACHINE_MIPSFPU16:
1134377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
1135377e23a2Schristos       magic = MIPS_ARCH_MAGIC_WINCE;
1136377e23a2Schristos #endif
1137377e23a2Schristos       break;
1138377e23a2Schristos 
1139377e23a2Schristos     case IMAGE_FILE_MACHINE_SH3:
1140377e23a2Schristos     case IMAGE_FILE_MACHINE_SH4:
1141377e23a2Schristos #ifdef SH_ARCH_MAGIC_WINCE
1142377e23a2Schristos       magic = SH_ARCH_MAGIC_WINCE;
1143377e23a2Schristos #endif
1144377e23a2Schristos       break;
1145377e23a2Schristos 
1146377e23a2Schristos     case IMAGE_FILE_MACHINE_ARM:
1147377e23a2Schristos #ifdef ARMPEMAGIC
1148377e23a2Schristos       magic = ARMPEMAGIC;
1149377e23a2Schristos #endif
1150377e23a2Schristos       break;
1151377e23a2Schristos 
1152377e23a2Schristos     case IMAGE_FILE_MACHINE_THUMB:
1153377e23a2Schristos #ifdef THUMBPEMAGIC
1154377e23a2Schristos       {
1155377e23a2Schristos 	extern const bfd_target TARGET_LITTLE_SYM;
1156377e23a2Schristos 
1157377e23a2Schristos 	if (abfd->xvec == & TARGET_LITTLE_SYM)
1158377e23a2Schristos 	  magic = THUMBPEMAGIC;
1159377e23a2Schristos       }
1160377e23a2Schristos #endif
1161377e23a2Schristos       break;
1162377e23a2Schristos 
1163377e23a2Schristos     case IMAGE_FILE_MACHINE_POWERPC:
1164377e23a2Schristos       /* We no longer support PowerPC.  */
1165377e23a2Schristos     default:
1166377e23a2Schristos       _bfd_error_handler
1167377e23a2Schristos 	(_("%B: Unrecognised machine type (0x%x)"
1168377e23a2Schristos 	   " in Import Library Format archive"),
1169377e23a2Schristos 	 abfd, machine);
1170377e23a2Schristos       bfd_set_error (bfd_error_malformed_archive);
1171377e23a2Schristos 
1172377e23a2Schristos       return NULL;
1173377e23a2Schristos       break;
1174377e23a2Schristos     }
1175377e23a2Schristos 
1176377e23a2Schristos   if (magic == 0)
1177377e23a2Schristos     {
1178377e23a2Schristos       _bfd_error_handler
1179377e23a2Schristos 	(_("%B: Recognised but unhandled machine type (0x%x)"
1180377e23a2Schristos 	   " in Import Library Format archive"),
1181377e23a2Schristos 	 abfd, machine);
1182377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1183377e23a2Schristos 
1184377e23a2Schristos       return NULL;
1185377e23a2Schristos     }
1186377e23a2Schristos 
1187377e23a2Schristos   /* We do not bother to check the date.
1188377e23a2Schristos      date = H_GET_32 (abfd, ptr);  */
1189377e23a2Schristos   ptr += 4;
1190377e23a2Schristos 
1191377e23a2Schristos   size = H_GET_32 (abfd, ptr);
1192377e23a2Schristos   ptr += 4;
1193377e23a2Schristos 
1194377e23a2Schristos   if (size == 0)
1195377e23a2Schristos     {
1196377e23a2Schristos       _bfd_error_handler
1197377e23a2Schristos 	(_("%B: size field is zero in Import Library Format header"), abfd);
1198377e23a2Schristos       bfd_set_error (bfd_error_malformed_archive);
1199377e23a2Schristos 
1200377e23a2Schristos       return NULL;
1201377e23a2Schristos     }
1202377e23a2Schristos 
1203377e23a2Schristos   ordinal = H_GET_16 (abfd, ptr);
1204377e23a2Schristos   ptr += 2;
1205377e23a2Schristos 
1206377e23a2Schristos   types = H_GET_16 (abfd, ptr);
1207377e23a2Schristos   /* ptr += 2; */
1208377e23a2Schristos 
1209377e23a2Schristos   /* Now read in the two strings that follow.  */
1210377e23a2Schristos   ptr = (bfd_byte *) bfd_alloc (abfd, size);
1211377e23a2Schristos   if (ptr == NULL)
1212377e23a2Schristos     return NULL;
1213377e23a2Schristos 
1214377e23a2Schristos   if (bfd_bread (ptr, size, abfd) != size)
1215377e23a2Schristos     {
1216377e23a2Schristos       bfd_release (abfd, ptr);
1217377e23a2Schristos       return NULL;
1218377e23a2Schristos     }
1219377e23a2Schristos 
1220377e23a2Schristos   symbol_name = (char *) ptr;
1221377e23a2Schristos   source_dll  = symbol_name + strlen (symbol_name) + 1;
1222377e23a2Schristos 
1223377e23a2Schristos   /* Verify that the strings are null terminated.  */
1224377e23a2Schristos   if (ptr[size - 1] != 0
1225377e23a2Schristos       || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
1226377e23a2Schristos     {
1227377e23a2Schristos       _bfd_error_handler
1228377e23a2Schristos 	(_("%B: string not null terminated in ILF object file."), abfd);
1229377e23a2Schristos       bfd_set_error (bfd_error_malformed_archive);
1230377e23a2Schristos       bfd_release (abfd, ptr);
1231377e23a2Schristos       return NULL;
1232377e23a2Schristos     }
1233377e23a2Schristos 
1234377e23a2Schristos   /* Now construct the bfd.  */
1235377e23a2Schristos   if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
1236377e23a2Schristos 			    source_dll, ordinal, types))
1237377e23a2Schristos     {
1238377e23a2Schristos       bfd_release (abfd, ptr);
1239377e23a2Schristos       return NULL;
1240377e23a2Schristos     }
1241377e23a2Schristos 
1242377e23a2Schristos   return abfd->xvec;
1243377e23a2Schristos }
1244377e23a2Schristos 
1245377e23a2Schristos static const bfd_target *
1246377e23a2Schristos pe_bfd_object_p (bfd * abfd)
1247377e23a2Schristos {
1248377e23a2Schristos   bfd_byte buffer[4];
1249377e23a2Schristos   struct external_PEI_DOS_hdr dos_hdr;
1250377e23a2Schristos   struct external_PEI_IMAGE_hdr image_hdr;
1251377e23a2Schristos   file_ptr offset;
1252377e23a2Schristos 
1253377e23a2Schristos   /* Detect if this a Microsoft Import Library Format element.  */
1254377e23a2Schristos   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1255377e23a2Schristos       || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4)
1256377e23a2Schristos     {
1257377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1258377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1259377e23a2Schristos       return NULL;
1260377e23a2Schristos     }
1261377e23a2Schristos 
1262377e23a2Schristos   if (H_GET_32 (abfd, buffer) == 0xffff0000)
1263377e23a2Schristos     return pe_ILF_object_p (abfd);
1264377e23a2Schristos 
1265377e23a2Schristos   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
1266377e23a2Schristos       || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
1267377e23a2Schristos 	 != sizeof (dos_hdr))
1268377e23a2Schristos     {
1269377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1270377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1271377e23a2Schristos       return NULL;
1272377e23a2Schristos     }
1273377e23a2Schristos 
1274377e23a2Schristos   /* There are really two magic numbers involved; the magic number
1275377e23a2Schristos      that says this is a NT executable (PEI) and the magic number that
1276377e23a2Schristos      determines the architecture.  The former is DOSMAGIC, stored in
1277377e23a2Schristos      the e_magic field.  The latter is stored in the f_magic field.
1278377e23a2Schristos      If the NT magic number isn't valid, the architecture magic number
1279377e23a2Schristos      could be mimicked by some other field (specifically, the number
1280377e23a2Schristos      of relocs in section 3).  Since this routine can only be called
1281377e23a2Schristos      correctly for a PEI file, check the e_magic number here, and, if
1282377e23a2Schristos      it doesn't match, clobber the f_magic number so that we don't get
1283377e23a2Schristos      a false match.  */
1284377e23a2Schristos   if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
1285377e23a2Schristos     {
1286377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1287377e23a2Schristos       return NULL;
1288377e23a2Schristos     }
1289377e23a2Schristos 
1290377e23a2Schristos   offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
1291377e23a2Schristos   if (bfd_seek (abfd, offset, SEEK_SET) != 0
1292377e23a2Schristos       || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
1293377e23a2Schristos 	  != sizeof (image_hdr)))
1294377e23a2Schristos     {
1295377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1296377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1297377e23a2Schristos       return NULL;
1298377e23a2Schristos     }
1299377e23a2Schristos 
1300377e23a2Schristos   if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
1301377e23a2Schristos     {
1302377e23a2Schristos       bfd_set_error (bfd_error_wrong_format);
1303377e23a2Schristos       return NULL;
1304377e23a2Schristos     }
1305377e23a2Schristos 
1306377e23a2Schristos   /* Here is the hack.  coff_object_p wants to read filhsz bytes to
1307377e23a2Schristos      pick up the COFF header for PE, see "struct external_PEI_filehdr"
1308377e23a2Schristos      in include/coff/pe.h.  We adjust so that that will work. */
1309377e23a2Schristos   if (bfd_seek (abfd, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0)
1310377e23a2Schristos     {
1311377e23a2Schristos       if (bfd_get_error () != bfd_error_system_call)
1312377e23a2Schristos 	bfd_set_error (bfd_error_wrong_format);
1313377e23a2Schristos       return NULL;
1314377e23a2Schristos     }
1315377e23a2Schristos 
1316377e23a2Schristos   return coff_object_p (abfd);
1317377e23a2Schristos }
1318377e23a2Schristos 
1319377e23a2Schristos #define coff_object_p pe_bfd_object_p
1320377e23a2Schristos #endif /* COFF_IMAGE_WITH_PE */
1321