Move PE format object file detection code into common place.
[platform/upstream/binutils.git] / bfd / peicode.h
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.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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.  */
20
21 /*
22 Most of this hacked by  Steve Chamberlain,
23                         sac@cygnus.com
24
25 PE/PEI rearrangement (and code added): Donn Terry
26                                        Softway Systems, Inc.
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
58 #include "libpei.h"
59
60 static boolean (*pe_saved_coff_bfd_print_private_bfd_data)
61     PARAMS ((bfd *, PTR)) =
62 #ifndef coff_bfd_print_private_bfd_data
63      NULL;
64 #else
65      coff_bfd_print_private_bfd_data;
66 #undef coff_bfd_print_private_bfd_data
67 #endif
68
69 static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR));
70 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
71
72
73 static 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
80 #endif
81
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
84
85 #define coff_mkobject      pe_mkobject
86 #define coff_mkobject_hook pe_mkobject_hook
87
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));
94
95 /**********************************************************************/
96
97 static void
98 coff_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
118 static unsigned int
119 coff_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
144 static void
145 coff_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
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
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
188 #define coff_swap_filehdr_out _bfd_pei_only_swap_filehdr_out
189 #else
190 #define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
191 #endif
192
193
194 static void
195 coff_swap_scnhdr_in (abfd, ext, in)
196      bfd            *abfd;
197      PTR             ext;
198      PTR             in;
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
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
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     }
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)
242     {
243       scnhdr_int->s_size = scnhdr_int->s_paddr;
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.  */
248     }
249 }
250
251 static boolean
252 pe_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;
265
266   /* in_reloc_p is architecture dependent.  */
267   pe->in_reloc_p = in_reloc_p;
268   return true;
269 }
270
271 /* Create the COFF backend specific information.  */
272 static PTR
273 pe_mkobject_hook (abfd, filehdr, aouthdr)
274      bfd * abfd;
275      PTR filehdr;
276      PTR aouthdr ATTRIBUTE_UNUSED;
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
297   pe->coff.timestamp = internal_f->f_timdat;
298
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
308   if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
309     abfd->flags |= HAS_DEBUG;
310
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
324 static boolean
325 pe_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;
333
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 }
343
344 /* Copy any private info we understand from the input bfd
345    to the output bfd.  */
346
347 static boolean
348 pe_bfd_copy_private_bfd_data (ibfd, obfd)
349      bfd *ibfd, *obfd;
350 {
351   if (!_bfd_pe_bfd_copy_private_bfd_data_common (ibfd, obfd))
352     return false;
353
354   if (pe_saved_coff_bfd_copy_private_bfd_data)
355     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
356
357   return true;
358 }
359
360 #define coff_bfd_copy_private_section_data \
361   _bfd_pe_bfd_copy_private_section_data
362
363 #define coff_get_symbol_info _bfd_pe_get_symbol_info
364
365 static const bfd_target *
366 pe_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