1 /* Support for the generic parts of PE/PEI, for BFD.
2 Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3 Written by Cygnus Solutions.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 Most of this hacked by Steve Chamberlain,
25 PE/PEI rearrangement (and code added): Donn Terry
29 /* Hey look, some documentation [and in a place you expect to find it]!
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.
36 "Peering Inside the PE: A Tour of the Win32 Portable Executable
37 File Format", MSJ 1994, Volume 9.
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
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.
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.
60 static boolean (*pe_saved_coff_bfd_print_private_bfd_data)
61 PARAMS ((bfd *, PTR)) =
62 #ifndef coff_bfd_print_private_bfd_data
65 coff_bfd_print_private_bfd_data;
66 #undef coff_bfd_print_private_bfd_data
69 static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR));
70 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
73 static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
74 PARAMS ((bfd *, bfd *)) =
75 #ifndef coff_bfd_copy_private_bfd_data
78 coff_bfd_copy_private_bfd_data;
79 #undef coff_bfd_copy_private_bfd_data
82 static boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
83 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
85 #define coff_mkobject pe_mkobject
86 #define coff_mkobject_hook pe_mkobject_hook
88 static void coff_swap_reloc_in PARAMS ((bfd *, PTR, PTR));
89 static unsigned int coff_swap_reloc_out PARAMS ((bfd *, PTR, PTR));
90 static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR));
91 static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR));
92 static boolean pe_mkobject PARAMS ((bfd *));
93 static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR));
95 /**********************************************************************/
98 coff_swap_reloc_in (abfd, src, dst)
103 RELOC *reloc_src = (RELOC *) src;
104 struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
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);
109 reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
111 #ifdef SWAP_IN_RELOC_OFFSET
112 reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
113 (bfd_byte *) reloc_src->r_offset);
119 coff_swap_reloc_out (abfd, src, dst)
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);
129 bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
132 #ifdef SWAP_OUT_RELOC_OFFSET
133 SWAP_OUT_RELOC_OFFSET(abfd,
135 (bfd_byte *) reloc_dst->r_offset);
137 #ifdef SWAP_OUT_RELOC_EXTRA
138 SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
145 coff_swap_filehdr_in (abfd, src, dst)
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);
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);
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
171 if (bfd_h_get_16 (abfd, (bfd_byte *) filehdr_src->e_magic) != DOSMAGIC)
172 filehdr_dst->f_magic = -1;
175 /* Other people's tools sometimes generate headers with an nsyms but
177 if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
179 filehdr_dst->f_nsyms = 0;
180 filehdr_dst->f_flags |= F_LSYMS;
183 filehdr_dst->f_opthdr = bfd_h_get_16(abfd,
184 (bfd_byte *)filehdr_src-> f_opthdr);
187 #ifdef COFF_IMAGE_WITH_PE
188 #define coff_swap_filehdr_out _bfd_pei_only_swap_filehdr_out
190 #define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
195 coff_swap_scnhdr_in (abfd, ext, in)
200 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
201 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
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);
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);
218 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
219 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
221 if (scnhdr_int->s_vaddr != 0)
223 scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
224 scnhdr_int->s_vaddr &= 0xffffffff;
227 /* If this section holds uninitialized data, use the virtual size
228 (stored in s_paddr) instead of the physical size. */
229 if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
231 scnhdr_int->s_size = scnhdr_int->s_paddr;
232 /* This code used to set scnhdr_int->s_paddr to 0. However,
233 coff_set_alignment_hook stores s_paddr in virt_size, which
234 only works if it correctly holds the virtual size of the
244 abfd->tdata.pe_obj_data =
245 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
247 if (abfd->tdata.pe_obj_data == 0)
254 /* in_reloc_p is architecture dependent. */
255 pe->in_reloc_p = in_reloc_p;
259 /* Create the COFF backend specific information. */
261 pe_mkobject_hook (abfd, filehdr, aouthdr)
264 PTR aouthdr ATTRIBUTE_UNUSED;
266 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
269 if (pe_mkobject (abfd) == false)
273 pe->coff.sym_filepos = internal_f->f_symptr;
274 /* These members communicate important constants about the symbol
275 table to GDB's symbol-reading code. These `constants'
276 unfortunately vary among coff implementations... */
277 pe->coff.local_n_btmask = N_BTMASK;
278 pe->coff.local_n_btshft = N_BTSHFT;
279 pe->coff.local_n_tmask = N_TMASK;
280 pe->coff.local_n_tshift = N_TSHIFT;
281 pe->coff.local_symesz = SYMESZ;
282 pe->coff.local_auxesz = AUXESZ;
283 pe->coff.local_linesz = LINESZ;
285 pe->coff.timestamp = internal_f->f_timdat;
287 obj_raw_syment_count (abfd) =
288 obj_conv_table_size (abfd) =
291 pe->real_flags = internal_f->f_flags;
293 if ((internal_f->f_flags & F_DLL) != 0)
296 if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
297 abfd->flags |= HAS_DEBUG;
299 #ifdef COFF_IMAGE_WITH_PE
301 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
305 if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
306 coff_data (abfd) ->flags = 0;
313 pe_print_private_bfd_data (abfd, vfile)
317 FILE *file = (FILE *) vfile;
319 if (!_bfd_pe_print_private_bfd_data_common (abfd, vfile))
322 if (pe_saved_coff_bfd_print_private_bfd_data != NULL)
326 return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
332 /* Copy any private info we understand from the input bfd
333 to the output bfd. */
336 pe_bfd_copy_private_bfd_data (ibfd, obfd)
339 if (!_bfd_pe_bfd_copy_private_bfd_data_common (ibfd, obfd))
342 if (pe_saved_coff_bfd_copy_private_bfd_data)
343 return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
348 #define coff_bfd_copy_private_section_data \
349 _bfd_pe_bfd_copy_private_section_data
351 #define coff_get_symbol_info _bfd_pe_get_symbol_info