x86 indirect jump/call syntax fixes. Disassembly fix for lcall.
[deliverable/binutils-gdb.git] / bfd / peicode.h
CommitLineData
277d1b5e 1/* Support for the generic parts of PE/PEI, for BFD.
368d0860 2 Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
277d1b5e 3 Written by Cygnus Solutions.
252b5132
RH
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21/*
22Most of this hacked by Steve Chamberlain,
23 sac@cygnus.com
277d1b5e
ILT
24
25PE/PEI rearrangement (and code added): Donn Terry
26 Softway Systems, Inc.
252b5132
RH
27*/
28
29/* Hey look, some documentation [and in a place you expect to find it]!
30
31 The main reference for the pei format is "Microsoft Portable Executable
32 and Common Object File Format Specification 4.1". Get it if you need to
33 do some serious hacking on this code.
34
35 Another reference:
36 "Peering Inside the PE: A Tour of the Win32 Portable Executable
37 File Format", MSJ 1994, Volume 9.
38
39 The *sole* difference between the pe format and the pei format is that the
40 latter has an MSDOS 2.0 .exe header on the front that prints the message
41 "This app must be run under Windows." (or some such).
42 (FIXME: Whether that statement is *really* true or not is unknown.
43 Are there more subtle differences between pe and pei formats?
44 For now assume there aren't. If you find one, then for God sakes
45 document it here!)
46
47 The Microsoft docs use the word "image" instead of "executable" because
48 the former can also refer to a DLL (shared library). Confusion can arise
49 because the `i' in `pei' also refers to "image". The `pe' format can
50 also create images (i.e. executables), it's just that to run on a win32
51 system you need to use the pei format.
52
53 FIXME: Please add more docs here so the next poor fool that has to hack
54 on this code has a chance of getting something accomplished without
55 wasting too much time.
56*/
57
277d1b5e
ILT
58#include "libpei.h"
59
252b5132 60static boolean (*pe_saved_coff_bfd_print_private_bfd_data)
277d1b5e
ILT
61 PARAMS ((bfd *, PTR)) =
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
277d1b5e
ILT
69static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR));
70#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
252b5132 71
252b5132 72
277d1b5e
ILT
73static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
74 PARAMS ((bfd *, bfd *)) =
75#ifndef coff_bfd_copy_private_bfd_data
76 NULL;
77#else
78 coff_bfd_copy_private_bfd_data;
79#undef coff_bfd_copy_private_bfd_data
252b5132
RH
80#endif
81
277d1b5e
ILT
82static boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
83#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
252b5132 84
277d1b5e
ILT
85#define coff_mkobject pe_mkobject
86#define coff_mkobject_hook pe_mkobject_hook
252b5132
RH
87
88static void coff_swap_reloc_in PARAMS ((bfd *, PTR, PTR));
89static unsigned int coff_swap_reloc_out PARAMS ((bfd *, PTR, PTR));
90static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR));
252b5132 91static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR));
252b5132
RH
92static boolean pe_mkobject PARAMS ((bfd *));
93static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR));
252b5132
RH
94
95/**********************************************************************/
96
97static void
98coff_swap_reloc_in (abfd, src, dst)
99 bfd *abfd;
100 PTR src;
101 PTR dst;
102{
103 RELOC *reloc_src = (RELOC *) src;
104 struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
105
106 reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
107 reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
108
109 reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
110
111#ifdef SWAP_IN_RELOC_OFFSET
112 reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
113 (bfd_byte *) reloc_src->r_offset);
114#endif
115}
116
117
118static unsigned int
119coff_swap_reloc_out (abfd, src, dst)
120 bfd *abfd;
121 PTR src;
122 PTR dst;
123{
124 struct internal_reloc *reloc_src = (struct internal_reloc *)src;
125 struct external_reloc *reloc_dst = (struct external_reloc *)dst;
126 bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
127 bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
128
129 bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
130 reloc_dst->r_type);
131
132#ifdef SWAP_OUT_RELOC_OFFSET
133 SWAP_OUT_RELOC_OFFSET(abfd,
134 reloc_src->r_offset,
135 (bfd_byte *) reloc_dst->r_offset);
136#endif
137#ifdef SWAP_OUT_RELOC_EXTRA
138 SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
139#endif
140 return RELSZ;
141}
142
143
144static void
145coff_swap_filehdr_in (abfd, src, dst)
146 bfd *abfd;
147 PTR src;
148 PTR dst;
149{
150 FILHDR *filehdr_src = (FILHDR *) src;
151 struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
152 filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic);
153 filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns);
154 filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat);
155
156 filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
157 filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
158 filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr);
159
05bf877a
ILT
160#ifdef COFF_IMAGE_WITH_PE
161 /* There are really two magic numbers involved; the magic number
162 that says this is a NT executable (PEI) and the magic number that
163 determines the architecture. The former is DOSMAGIC, stored in
164 the e_magic field. The latter is stored in the f_magic field.
165 If the NT magic number isn't valid, the architecture magic number
166 could be mimicked by some other field (specifically, the number
167 of relocs in section 3). Since this routine can only be called
168 correctly for a PEI file, check the e_magic number here, and, if
169 it doesn't match, clobber the f_magic number so that we don't get
170 a false match. */
171 if (bfd_h_get_16 (abfd, (bfd_byte *) filehdr_src->e_magic) != DOSMAGIC)
172 filehdr_dst->f_magic = -1;
173#endif
174
252b5132
RH
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
183 filehdr_dst->f_opthdr = bfd_h_get_16(abfd,
184 (bfd_byte *)filehdr_src-> f_opthdr);
185}
186
187#ifdef COFF_IMAGE_WITH_PE
277d1b5e 188#define coff_swap_filehdr_out _bfd_pei_only_swap_filehdr_out
252b5132 189#else
277d1b5e 190#define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
252b5132 191#endif
252b5132 192
252b5132
RH
193
194static void
e166a60f
ILT
195coff_swap_scnhdr_in (abfd, ext, in)
196 bfd *abfd;
197 PTR ext;
198 PTR in;
252b5132
RH
199{
200 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
201 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
202
203 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
204 scnhdr_int->s_vaddr =
205 GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
206 scnhdr_int->s_paddr =
207 GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
208 scnhdr_int->s_size =
209 GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
210 scnhdr_int->s_scnptr =
211 GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
212 scnhdr_int->s_relptr =
213 GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
214 scnhdr_int->s_lnnoptr =
215 GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
216 scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
217
cb43721d
ILT
218 /* MS handles overflow of line numbers by carrying into the reloc
219 field (it appears). Since it's supposed to be zero for PE
220 *IMAGE* format, that's safe. This is still a bit iffy. */
221#ifdef COFF_IMAGE_WITH_PE
222 scnhdr_int->s_nlnno =
223 (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nlnno)
224 + (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nreloc) << 16));
225 scnhdr_int->s_nreloc = 0;
226#else
227 scnhdr_int->s_nreloc = bfd_h_get_16 (abfd,
228 (bfd_byte *) scnhdr_ext->s_nreloc);
229 scnhdr_int->s_nlnno = bfd_h_get_16 (abfd,
230 (bfd_byte *) scnhdr_ext->s_nlnno);
231#endif
252b5132
RH
232
233 if (scnhdr_int->s_vaddr != 0)
234 {
235 scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
236 scnhdr_int->s_vaddr &= 0xffffffff;
237 }
e166a60f
ILT
238
239 /* If this section holds uninitialized data, use the virtual size
240 (stored in s_paddr) instead of the physical size. */
241 if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
252b5132
RH
242 {
243 scnhdr_int->s_size = scnhdr_int->s_paddr;
e166a60f
ILT
244 /* This code used to set scnhdr_int->s_paddr to 0. However,
245 coff_set_alignment_hook stores s_paddr in virt_size, which
246 only works if it correctly holds the virtual size of the
247 section. */
252b5132
RH
248 }
249}
250
252b5132
RH
251static boolean
252pe_mkobject (abfd)
253 bfd * abfd;
254{
255 pe_data_type *pe;
256 abfd->tdata.pe_obj_data =
257 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
258
259 if (abfd->tdata.pe_obj_data == 0)
260 return false;
261
262 pe = pe_data (abfd);
263
264 pe->coff.pe = 1;
277d1b5e
ILT
265
266 /* in_reloc_p is architecture dependent. */
252b5132
RH
267 pe->in_reloc_p = in_reloc_p;
268 return true;
269}
270
271/* Create the COFF backend specific information. */
272static PTR
273pe_mkobject_hook (abfd, filehdr, aouthdr)
274 bfd * abfd;
275 PTR filehdr;
5f771d47 276 PTR aouthdr ATTRIBUTE_UNUSED;
252b5132
RH
277{
278 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
279 pe_data_type *pe;
280
281 if (pe_mkobject (abfd) == false)
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
RH
311#ifdef COFF_IMAGE_WITH_PE
312 if (aouthdr)
313 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
314#endif
315
316#ifdef ARM
317 if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
318 coff_data (abfd) ->flags = 0;
319#endif
320
321 return (PTR) pe;
322}
323
277d1b5e
ILT
324static boolean
325pe_print_private_bfd_data (abfd, vfile)
326 bfd *abfd;
327 PTR vfile;
328{
329 FILE *file = (FILE *) vfile;
330
331 if (!_bfd_pe_print_private_bfd_data_common (abfd, vfile))
332 return false;
252b5132 333
277d1b5e
ILT
334 if (pe_saved_coff_bfd_print_private_bfd_data != NULL)
335 {
336 fputc ('\n', file);
337
338 return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
339 }
340
341 return true;
342}
252b5132
RH
343
344/* Copy any private info we understand from the input bfd
345 to the output bfd. */
346
252b5132
RH
347static boolean
348pe_bfd_copy_private_bfd_data (ibfd, obfd)
349 bfd *ibfd, *obfd;
350{
277d1b5e
ILT
351 if (!_bfd_pe_bfd_copy_private_bfd_data_common (ibfd, obfd))
352 return false;
252b5132
RH
353
354 if (pe_saved_coff_bfd_copy_private_bfd_data)
355 return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
252b5132
RH
356
357 return true;
358}
359
277d1b5e
ILT
360#define coff_bfd_copy_private_section_data \
361 _bfd_pe_bfd_copy_private_section_data
7d2b58d6
ILT
362
363#define coff_get_symbol_info _bfd_pe_get_symbol_info
cb665cd3
NC
364
365static const bfd_target *
366pe_bfd_object_p (abfd)
367 bfd * abfd;
368{
369 /* We need to handle a PE image correctly. In PE images created by
370 the GNU linker, the offset to the COFF header is always the size.
371 However, this is not the case in images generated by other PE
372 linkers. The PE format stores a four byte offset to the PE
373 signature just before the COFF header at location 0x3c of the file.
374 We pick up that offset, verify that the PE signature is there, and
375 then set ourselves up to read in the COFF header. */
376 bfd_byte buffer[4];
377 file_ptr offset;
378 unsigned long signature;
379
380 /* Detect if this a Microsoft Import Library Format element. */
381 if (bfd_seek (abfd, 0x00, SEEK_SET) != 0
382 || bfd_read (buffer, 1, 4, abfd) != 4)
383 {
384 if (bfd_get_error () != bfd_error_system_call)
385 bfd_set_error (bfd_error_wrong_format);
386 return NULL;
387 }
388
389 signature = bfd_h_get_32 (abfd, buffer);
390
391 if (signature == 0xffff0000)
392 {
393 _bfd_error_handler (_("%s: Import Library Format archives are not currently supported"),
394 bfd_get_filename (abfd));
395 bfd_set_error (bfd_error_wrong_format);
396
397 return NULL;
398 }
399
400 if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
401 || bfd_read (buffer, 1, 4, abfd) != 4)
402 {
403 if (bfd_get_error () != bfd_error_system_call)
404 bfd_set_error (bfd_error_wrong_format);
405 return NULL;
406 }
407
408 offset = bfd_h_get_32 (abfd, buffer);
409
410 if (bfd_seek (abfd, offset, SEEK_SET) != 0
411 || bfd_read (buffer, 1, 4, abfd) != 4)
412 {
413 if (bfd_get_error () != bfd_error_system_call)
414 bfd_set_error (bfd_error_wrong_format);
415 return NULL;
416 }
417
418 signature = bfd_h_get_32 (abfd, buffer);
419
420 if (signature != 0x4550)
421 {
422 bfd_set_error (bfd_error_wrong_format);
423 return NULL;
424 }
425
426 /* Here is the hack. coff_object_p wants to read filhsz bytes to
427 pick up the COFF header. We adjust so that that will work. 20
428 is the size of the i386 COFF filehdr. */
429 if (bfd_seek (abfd,
430 (bfd_tell (abfd)
431 - bfd_coff_filhsz (abfd)
432 + 20),
433 SEEK_SET)
434 != 0)
435 {
436 if (bfd_get_error () != bfd_error_system_call)
437 bfd_set_error (bfd_error_wrong_format);
438 return NULL;
439 }
440
441 return coff_object_p (abfd);
442}
443
444#define coff_object_p pe_bfd_object_p
This page took 0.058221 seconds and 4 git commands to generate.