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