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