OSDN Git Service

1999-09-11 Donn Terry <donn@interix.com>
[pf3gnuchains/pf3gnuchains3x.git] / bfd / peigen.c
1 /* Support for the generic parts of PE/PEI; the common executable parts.
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 "bfd.h"
59 #include "sysdep.h"
60 #include "libbfd.h"
61 #include "coff/internal.h"
62
63 /* NOTE: it's strange to be including an architecture specific header
64    in what's supposed to be general (to PE/PEI) code.  However, that's
65    where the definitions are, and they don't vary per architecture
66    within PE/PEI, so we get them from there.  FIXME: The lack of
67    variance is an assumption which may prove to be incorrect if new
68    PE/PEI targets are created.  */
69 #include "coff/i386.h"
70
71 #include "coff/pe.h"
72 #include "libcoff.h"
73 #include "libpei.h"
74
75 /* FIXME: This file has various tests of POWERPC_LE_PE.  Those tests
76    worked when the code was in peicode.h, but no longer work now that
77    the code is in peigen.c.  PowerPC NT is said to be dead.  If
78    anybody wants to revive the code, you will have to figure out how
79    to handle those issues.  */
80
81 boolean in_reloc_p PARAMS((bfd *, reloc_howto_type *));
82
83 /**********************************************************************/
84
85 void
86 _bfd_pei_swap_sym_in (abfd, ext1, in1)
87      bfd *abfd;
88      PTR ext1;
89      PTR in1;
90 {
91   SYMENT *ext = (SYMENT *)ext1;
92   struct internal_syment      *in = (struct internal_syment *)in1;
93
94   if( ext->e.e_name[0] == 0) {
95     in->_n._n_n._n_zeroes = 0;
96     in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
97   }
98   else {
99     memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
100   }
101
102   in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
103   in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
104   if (sizeof(ext->e_type) == 2){
105     in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
106   }
107   else {
108     in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
109   }
110   in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
111   in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
112
113 #ifndef STRICT_PE_FORMAT
114   /* This is for Gnu-created DLLs */
115
116   /* The section symbols for the .idata$ sections have class 0x68
117      (C_SECTION), which MS documentation indicates is a section
118      symbol.  Unfortunately, the value field in the symbol is simply a
119      copy of the .idata section's flags rather than something useful.
120      When these symbols are encountered, change the value to 0 so that
121      they will be handled somewhat correctly in the bfd code.  */
122   if (in->n_sclass == C_SECTION)
123     {
124       in->n_value = 0x0;
125
126 #if 0
127       /* FIXME: This is clearly wrong.  The problem seems to be that
128          undefined C_SECTION symbols appear in the first object of a
129          MS generated .lib file, and the symbols are not defined
130          anywhere.  */
131       in->n_scnum = 1;
132
133       /* I have tried setting the class to 3 and using the following
134          to set the section number.  This will put the address of the
135          pointer to the string kernel32.dll at addresses 0 and 0x10
136          off start of idata section which is not correct */
137       /*    if (strcmp (in->_n._n_name, ".idata$4") == 0) */
138       /*      in->n_scnum = 3; */
139       /*    else */
140       /*      in->n_scnum = 2; */
141 #else
142       /* Create synthetic empty sections as needed.  DJ */
143       if (in->n_scnum == 0)
144         {
145           asection *sec;
146           for (sec=abfd->sections; sec; sec=sec->next)
147             {
148               if (strcmp (sec->name, in->n_name) == 0)
149                 {
150                   in->n_scnum = sec->target_index;
151                   break;
152                 }
153             }
154         }
155       if (in->n_scnum == 0)
156         {
157           int unused_section_number = 0;
158           asection *sec;
159           char *name;
160           for (sec=abfd->sections; sec; sec=sec->next)
161             if (unused_section_number <= sec->target_index)
162               unused_section_number = sec->target_index+1;
163
164           name = bfd_alloc (abfd, strlen (in->n_name) + 10);
165           if (name == NULL)
166             return;
167           strcpy (name, in->n_name);
168           sec = bfd_make_section_anyway (abfd, name);
169
170           sec->vma = 0;
171           sec->lma = 0;
172           sec->_cooked_size = 0;
173           sec->_raw_size = 0;
174           sec->filepos = 0;
175           sec->rel_filepos = 0;
176           sec->reloc_count = 0;
177           sec->line_filepos = 0;
178           sec->lineno_count = 0;
179           sec->userdata = NULL;
180           sec->next = (asection *) NULL;
181           sec->flags = 0;
182           sec->alignment_power = 2;
183           sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
184
185           sec->target_index = unused_section_number;
186
187           in->n_scnum = unused_section_number;
188         }
189       in->n_sclass = C_STAT;
190 #endif
191     }
192 #endif
193
194 #ifdef coff_swap_sym_in_hook
195   /* This won't work in peigen.c, but since it's for PPC PE, it's not
196      worth fixing. */
197   coff_swap_sym_in_hook(abfd, ext1, in1);
198 #endif
199 }
200
201 unsigned int
202 _bfd_pei_swap_sym_out (abfd, inp, extp)
203      bfd       *abfd;
204      PTR        inp;
205      PTR        extp;
206 {
207   struct internal_syment *in = (struct internal_syment *)inp;
208   SYMENT *ext =(SYMENT *)extp;
209   if(in->_n._n_name[0] == 0) {
210     bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
211     bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *)  ext->e.e.e_offset);
212   }
213   else {
214     memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
215   }
216
217   bfd_h_put_32(abfd,  in->n_value , (bfd_byte *) ext->e_value);
218   bfd_h_put_16(abfd,  in->n_scnum , (bfd_byte *) ext->e_scnum);
219   if (sizeof(ext->e_type) == 2)
220     {
221       bfd_h_put_16(abfd,  in->n_type , (bfd_byte *) ext->e_type);
222     }
223   else
224     {
225       bfd_h_put_32(abfd,  in->n_type , (bfd_byte *) ext->e_type);
226     }
227   bfd_h_put_8(abfd,  in->n_sclass , ext->e_sclass);
228   bfd_h_put_8(abfd,  in->n_numaux , ext->e_numaux);
229
230   return SYMESZ;
231 }
232
233 void
234 _bfd_pei_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
235      bfd            *abfd;
236      PTR             ext1;
237      int             type;
238      int             class;
239      int             indx ATTRIBUTE_UNUSED;
240      int             numaux ATTRIBUTE_UNUSED;
241      PTR             in1;
242 {
243   AUXENT    *ext = (AUXENT *)ext1;
244   union internal_auxent *in = (union internal_auxent *)in1;
245
246   switch (class) {
247   case C_FILE:
248     if (ext->x_file.x_fname[0] == 0) {
249       in->x_file.x_n.x_zeroes = 0;
250       in->x_file.x_n.x_offset =
251         bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
252     } else {
253       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
254     }
255     return;
256
257
258   case C_STAT:
259   case C_LEAFSTAT:
260   case C_HIDDEN:
261     if (type == T_NULL) {
262       in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
263       in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
264       in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
265       in->x_scn.x_checksum = bfd_h_get_32 (abfd,
266                                            (bfd_byte *) ext->x_scn.x_checksum);
267       in->x_scn.x_associated =
268         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);
269       in->x_scn.x_comdat = bfd_h_get_8 (abfd,
270                                         (bfd_byte *) ext->x_scn.x_comdat);
271       return;
272     }
273     break;
274   }
275
276   in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
277   in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
278
279   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
280     {
281       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
282       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
283     }
284   else
285     {
286       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
287         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
288       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
289         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
290       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
291         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
292       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
293         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
294     }
295
296   if (ISFCN(type)) {
297     in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
298   }
299   else {
300     in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
301     in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
302   }
303 }
304
305 unsigned int
306 _bfd_pei_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
307      bfd  *abfd;
308      PTR   inp;
309      int   type;
310      int   class;
311      int   indx ATTRIBUTE_UNUSED;
312      int   numaux ATTRIBUTE_UNUSED;
313      PTR   extp;
314 {
315   union internal_auxent *in = (union internal_auxent *)inp;
316   AUXENT *ext = (AUXENT *)extp;
317
318   memset((PTR)ext, 0, AUXESZ);
319   switch (class) {
320   case C_FILE:
321     if (in->x_file.x_fname[0] == 0) {
322       bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
323       bfd_h_put_32(abfd,
324               in->x_file.x_n.x_offset,
325               (bfd_byte *) ext->x_file.x_n.x_offset);
326     }
327     else {
328       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
329     }
330     return AUXESZ;
331
332
333   case C_STAT:
334   case C_LEAFSTAT:
335   case C_HIDDEN:
336     if (type == T_NULL) {
337       PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
338       PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
339       PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
340       bfd_h_put_32 (abfd, in->x_scn.x_checksum,
341                     (bfd_byte *) ext->x_scn.x_checksum);
342       bfd_h_put_16 (abfd, in->x_scn.x_associated,
343                     (bfd_byte *) ext->x_scn.x_associated);
344       bfd_h_put_8 (abfd, in->x_scn.x_comdat,
345                    (bfd_byte *) ext->x_scn.x_comdat);
346       return AUXESZ;
347     }
348     break;
349   }
350
351   bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
352   bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
353
354   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
355     {
356       PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
357       PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
358     }
359   else
360     {
361       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
362                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
363       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
364                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
365       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
366                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
367       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
368                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
369     }
370
371   if (ISFCN (type))
372     bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
373              (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
374   else
375     {
376       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
377       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
378     }
379
380   return AUXESZ;
381 }
382
383 void
384 _bfd_pei_swap_lineno_in (abfd, ext1, in1)
385      bfd *abfd;
386      PTR ext1;
387      PTR in1;
388 {
389   LINENO *ext = (LINENO *)ext1;
390   struct internal_lineno      *in = (struct internal_lineno *)in1;
391
392   in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
393   in->l_lnno = GET_LINENO_LNNO(abfd, ext);
394 }
395
396 unsigned int
397 _bfd_pei_swap_lineno_out (abfd, inp, outp)
398      bfd       *abfd;
399      PTR        inp;
400      PTR        outp;
401 {
402   struct internal_lineno *in = (struct internal_lineno *)inp;
403   struct external_lineno *ext = (struct external_lineno *)outp;
404   bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
405           ext->l_addr.l_symndx);
406
407   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
408   return LINESZ;
409 }
410
411 void
412 _bfd_pei_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
413      bfd *abfd;
414      PTR aouthdr_ext1;
415      PTR aouthdr_int1;
416 {
417   struct internal_extra_pe_aouthdr *a;
418   PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
419   AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
420   struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
421
422   aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
423   aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
424   aouthdr_int->tsize =
425     GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
426   aouthdr_int->dsize =
427     GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
428   aouthdr_int->bsize =
429     GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
430   aouthdr_int->entry =
431     GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
432   aouthdr_int->text_start =
433     GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
434   aouthdr_int->data_start =
435     GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
436
437   a = &aouthdr_int->pe;
438   a->ImageBase = bfd_h_get_32 (abfd, (bfd_byte *)src->ImageBase);
439   a->SectionAlignment = bfd_h_get_32 (abfd, (bfd_byte *)src->SectionAlignment);
440   a->FileAlignment = bfd_h_get_32 (abfd, (bfd_byte *)src->FileAlignment);
441   a->MajorOperatingSystemVersion =
442     bfd_h_get_16 (abfd, (bfd_byte *)src->MajorOperatingSystemVersion);
443   a->MinorOperatingSystemVersion =
444     bfd_h_get_16 (abfd, (bfd_byte *)src->MinorOperatingSystemVersion);
445   a->MajorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MajorImageVersion);
446   a->MinorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MinorImageVersion);
447   a->MajorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MajorSubsystemVersion);
448   a->MinorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MinorSubsystemVersion);
449   a->Reserved1 = bfd_h_get_32 (abfd, (bfd_byte *)src->Reserved1);
450   a->SizeOfImage = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfImage);
451   a->SizeOfHeaders = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeaders);
452   a->CheckSum = bfd_h_get_32 (abfd, (bfd_byte *)src->CheckSum);
453   a->Subsystem = bfd_h_get_16 (abfd, (bfd_byte *)src->Subsystem);
454   a->DllCharacteristics = bfd_h_get_16 (abfd, (bfd_byte *)src->DllCharacteristics);
455   a->SizeOfStackReserve = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfStackReserve);
456   a->SizeOfStackCommit = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfStackCommit);
457   a->SizeOfHeapReserve = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeapReserve);
458   a->SizeOfHeapCommit = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeapCommit);
459   a->LoaderFlags = bfd_h_get_32 (abfd, (bfd_byte *)src->LoaderFlags);
460   a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, (bfd_byte *)src->NumberOfRvaAndSizes);
461
462   {
463     int idx;
464     for (idx=0; idx < 16; idx++)
465       {
466         a->DataDirectory[idx].VirtualAddress =
467           bfd_h_get_32 (abfd, (bfd_byte *)src->DataDirectory[idx][0]);
468         a->DataDirectory[idx].Size =
469           bfd_h_get_32 (abfd, (bfd_byte *)src->DataDirectory[idx][1]);
470       }
471   }
472
473   if (aouthdr_int->entry)
474     {
475       aouthdr_int->entry += a->ImageBase;
476       aouthdr_int->entry &= 0xffffffff;
477     }
478   if (aouthdr_int->tsize) 
479     {
480       aouthdr_int->text_start += a->ImageBase;
481       aouthdr_int->text_start &= 0xffffffff;
482     }
483   if (aouthdr_int->dsize) 
484     {
485       aouthdr_int->data_start += a->ImageBase;
486       aouthdr_int->data_start &= 0xffffffff;
487     }
488
489 #ifdef POWERPC_LE_PE
490   /* These three fields are normally set up by ppc_relocate_section.
491      In the case of reading a file in, we can pick them up from the
492      DataDirectory.  */
493   first_thunk_address = a->DataDirectory[12].VirtualAddress ;
494   thunk_size = a->DataDirectory[12].Size;
495   import_table_size = a->DataDirectory[1].Size;
496 #endif
497
498 }
499
500 static void add_data_entry (abfd, aout, idx, name, base)
501      bfd *abfd;
502      struct internal_extra_pe_aouthdr *aout;
503      int idx;
504      char *name;
505      bfd_vma base;
506 {
507   asection *sec = bfd_get_section_by_name (abfd, name);
508
509   /* add import directory information if it exists */
510   if ((sec != NULL)
511       && (coff_section_data (abfd, sec) != NULL)
512       && (pei_section_data (abfd, sec) != NULL))
513     {
514       aout->DataDirectory[idx].VirtualAddress = (sec->vma - base) & 0xffffffff;
515       aout->DataDirectory[idx].Size = pei_section_data (abfd, sec)->virt_size;
516       sec->flags |= SEC_DATA;
517     }
518 }
519
520 unsigned int
521 _bfd_pei_swap_aouthdr_out (abfd, in, out)
522      bfd       *abfd;
523      PTR        in;
524      PTR        out;
525 {
526   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
527   struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
528   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
529
530   bfd_vma sa = extra->SectionAlignment;
531   bfd_vma fa = extra->FileAlignment;
532   bfd_vma ib = extra->ImageBase ;
533
534   if (aouthdr_in->tsize) 
535     {
536       aouthdr_in->text_start -= ib;
537       aouthdr_in->text_start &= 0xffffffff;
538     }
539   if (aouthdr_in->dsize) 
540     {
541       aouthdr_in->data_start -= ib;
542       aouthdr_in->data_start &= 0xffffffff;
543     }
544   if (aouthdr_in->entry) 
545     {
546       aouthdr_in->entry -= ib;
547       aouthdr_in->entry &= 0xffffffff;
548     }
549
550 #define FA(x)  (((x) + fa -1 ) & (- fa))
551 #define SA(x)  (((x) + sa -1 ) & (- sa))
552
553   /* We like to have the sizes aligned */
554
555   aouthdr_in->bsize = FA (aouthdr_in->bsize);
556
557
558   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
559
560   /* first null out all data directory entries .. */
561   memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
562
563   add_data_entry (abfd, extra, 0, ".edata", ib);
564   add_data_entry (abfd, extra, 1, ".idata", ib);
565   add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
566
567 #ifdef POWERPC_LE_PE
568   /* FIXME: do other PE platforms use this? */
569   add_data_entry (abfd, extra, 3, ".pdata" ,ib);
570 #endif
571
572   add_data_entry (abfd, extra, 5, ".reloc", ib);
573
574 #ifdef POWERPC_LE_PE
575   /* On the PPC NT system, this field is set up as follows. It is not
576      an "officially" reserved field, so it currently has no title.
577      first_thunk_address is idata$5, and the thunk_size is the size of
578      the idata$5 chunk of the idata section.  */
579   extra->DataDirectory[12].VirtualAddress = first_thunk_address;
580   extra->DataDirectory[12].Size = thunk_size;
581
582   /* On the PPC NT system, the size of the directory entry is not the
583      size of the entire section. It's actually offset to the end of
584      the idata$3 component of the idata section. This is the size of
585      the entire import table. (also known as the start of idata$4).  */
586   extra->DataDirectory[1].Size = import_table_size;
587 #endif
588
589   {
590     asection *sec;
591     bfd_vma dsize= 0;
592     bfd_vma isize = SA(abfd->sections->filepos);
593     bfd_vma tsize= 0;
594
595     for (sec = abfd->sections; sec; sec = sec->next)
596       {
597         int rounded = FA(sec->_raw_size);
598
599         if (sec->flags & SEC_DATA)
600           dsize += rounded;
601         if (sec->flags & SEC_CODE)
602           tsize += rounded;
603         isize += SA(rounded);
604       }
605
606     aouthdr_in->dsize = dsize;
607     aouthdr_in->tsize = tsize;
608     extra->SizeOfImage = isize;
609   }
610
611   extra->SizeOfHeaders = abfd->sections->filepos;
612   bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
613
614 #ifdef POWERPC_LE_PE
615   /* this little piece of magic sets the "linker version" field to 2.60 */
616   bfd_h_put_16(abfd, 2  + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
617 #else
618   /* this little piece of magic sets the "linker version" field to 2.55 */
619   bfd_h_put_16(abfd, 2  + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
620 #endif
621
622   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
623   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
624   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
625   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
626   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
627                           (bfd_byte *) aouthdr_out->standard.text_start);
628
629   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
630                           (bfd_byte *) aouthdr_out->standard.data_start);
631
632
633   bfd_h_put_32 (abfd, extra->ImageBase,
634                 (bfd_byte *) aouthdr_out->ImageBase);
635   bfd_h_put_32 (abfd, extra->SectionAlignment,
636                 (bfd_byte *) aouthdr_out->SectionAlignment);
637   bfd_h_put_32 (abfd, extra->FileAlignment,
638                 (bfd_byte *) aouthdr_out->FileAlignment);
639   bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
640                 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
641   bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
642                 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
643   bfd_h_put_16 (abfd, extra->MajorImageVersion,
644                 (bfd_byte *) aouthdr_out->MajorImageVersion);
645   bfd_h_put_16 (abfd, extra->MinorImageVersion,
646                 (bfd_byte *) aouthdr_out->MinorImageVersion);
647   bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
648                 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
649   bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
650                 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
651   bfd_h_put_32 (abfd, extra->Reserved1,
652                 (bfd_byte *) aouthdr_out->Reserved1);
653   bfd_h_put_32 (abfd, extra->SizeOfImage,
654                 (bfd_byte *) aouthdr_out->SizeOfImage);
655   bfd_h_put_32 (abfd, extra->SizeOfHeaders,
656                 (bfd_byte *) aouthdr_out->SizeOfHeaders);
657   bfd_h_put_32 (abfd, extra->CheckSum,
658                 (bfd_byte *) aouthdr_out->CheckSum);
659   bfd_h_put_16 (abfd, extra->Subsystem,
660                 (bfd_byte *) aouthdr_out->Subsystem);
661   bfd_h_put_16 (abfd, extra->DllCharacteristics,
662                 (bfd_byte *) aouthdr_out->DllCharacteristics);
663   bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
664                 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
665   bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
666                 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
667   bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
668                 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
669   bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
670                 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
671   bfd_h_put_32 (abfd, extra->LoaderFlags,
672                 (bfd_byte *) aouthdr_out->LoaderFlags);
673   bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
674                 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
675   {
676     int idx;
677     for (idx=0; idx < 16; idx++)
678       {
679         bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
680                       (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
681         bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
682                       (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
683       }
684   }
685
686   return AOUTSZ;
687 }
688
689 unsigned int
690 _bfd_pei_only_swap_filehdr_out (abfd, in, out)
691      bfd       *abfd;
692      PTR        in;
693      PTR        out;
694 {
695   int idx;
696   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
697   struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *)out;
698
699   if (pe_data (abfd)->has_reloc_section)
700     filehdr_in->f_flags &= ~F_RELFLG;
701
702   if (pe_data (abfd)->dll)
703     filehdr_in->f_flags |= F_DLL;
704
705   filehdr_in->pe.e_magic    = DOSMAGIC;
706   filehdr_in->pe.e_cblp     = 0x90;
707   filehdr_in->pe.e_cp       = 0x3;
708   filehdr_in->pe.e_crlc     = 0x0;
709   filehdr_in->pe.e_cparhdr  = 0x4;
710   filehdr_in->pe.e_minalloc = 0x0;
711   filehdr_in->pe.e_maxalloc = 0xffff;
712   filehdr_in->pe.e_ss       = 0x0;
713   filehdr_in->pe.e_sp       = 0xb8;
714   filehdr_in->pe.e_csum     = 0x0;
715   filehdr_in->pe.e_ip       = 0x0;
716   filehdr_in->pe.e_cs       = 0x0;
717   filehdr_in->pe.e_lfarlc   = 0x40;
718   filehdr_in->pe.e_ovno     = 0x0;
719
720   for (idx=0; idx < 4; idx++)
721     filehdr_in->pe.e_res[idx] = 0x0;
722
723   filehdr_in->pe.e_oemid   = 0x0;
724   filehdr_in->pe.e_oeminfo = 0x0;
725
726   for (idx=0; idx < 10; idx++)
727     filehdr_in->pe.e_res2[idx] = 0x0;
728
729   filehdr_in->pe.e_lfanew = 0x80;
730
731   /* this next collection of data are mostly just characters.  It appears
732      to be constant within the headers put on NT exes */
733   filehdr_in->pe.dos_message[0]  = 0x0eba1f0e;
734   filehdr_in->pe.dos_message[1]  = 0xcd09b400;
735   filehdr_in->pe.dos_message[2]  = 0x4c01b821;
736   filehdr_in->pe.dos_message[3]  = 0x685421cd;
737   filehdr_in->pe.dos_message[4]  = 0x70207369;
738   filehdr_in->pe.dos_message[5]  = 0x72676f72;
739   filehdr_in->pe.dos_message[6]  = 0x63206d61;
740   filehdr_in->pe.dos_message[7]  = 0x6f6e6e61;
741   filehdr_in->pe.dos_message[8]  = 0x65622074;
742   filehdr_in->pe.dos_message[9]  = 0x6e757220;
743   filehdr_in->pe.dos_message[10] = 0x206e6920;
744   filehdr_in->pe.dos_message[11] = 0x20534f44;
745   filehdr_in->pe.dos_message[12] = 0x65646f6d;
746   filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
747   filehdr_in->pe.dos_message[14] = 0x24;
748   filehdr_in->pe.dos_message[15] = 0x0;
749   filehdr_in->pe.nt_signature = NT_SIGNATURE;
750
751
752
753   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
754   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
755
756   bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat);
757   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
758                       (bfd_byte *) filehdr_out->f_symptr);
759   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
760   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
761   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
762
763   /* put in extra dos header stuff.  This data remains essentially
764      constant, it just has to be tacked on to the beginning of all exes
765      for NT */
766   bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic);
767   bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp);
768   bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp);
769   bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc);
770   bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr,
771                (bfd_byte *) filehdr_out->e_cparhdr);
772   bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc,
773                (bfd_byte *) filehdr_out->e_minalloc);
774   bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc,
775                (bfd_byte *) filehdr_out->e_maxalloc);
776   bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss);
777   bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp);
778   bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum);
779   bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip);
780   bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs);
781   bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
782   bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno);
783   {
784     int idx;
785     for (idx=0; idx < 4; idx++)
786       bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx],
787                    (bfd_byte *) filehdr_out->e_res[idx]);
788   }
789   bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid);
790   bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo,
791                (bfd_byte *) filehdr_out->e_oeminfo);
792   {
793     int idx;
794     for (idx=0; idx < 10; idx++)
795       bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx],
796                    (bfd_byte *) filehdr_out->e_res2[idx]);
797   }
798   bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
799
800   {
801     int idx;
802     for (idx=0; idx < 16; idx++)
803       bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx],
804                    (bfd_byte *) filehdr_out->dos_message[idx]);
805   }
806
807   /* also put in the NT signature */
808   bfd_h_put_32(abfd, filehdr_in->pe.nt_signature,
809                (bfd_byte *) filehdr_out->nt_signature);
810
811
812
813
814   return FILHSZ;
815 }
816
817 unsigned int
818 _bfd_pe_only_swap_filehdr_out (abfd, in, out)
819      bfd       *abfd;
820      PTR        in;
821      PTR        out;
822 {
823   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
824   FILHDR *filehdr_out = (FILHDR *)out;
825
826   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
827   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
828   bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
829   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
830                       (bfd_byte *) filehdr_out->f_symptr);
831   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
832   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
833   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
834
835   return FILHSZ;
836 }
837
838 unsigned int
839 _bfd_pei_swap_scnhdr_out (abfd, in, out)
840      bfd       *abfd;
841      PTR        in;
842      PTR        out;
843 {
844   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
845   SCNHDR *scnhdr_ext = (SCNHDR *)out;
846   unsigned int ret = SCNHSZ;
847   bfd_vma ps;
848   bfd_vma ss;
849
850   memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
851
852   PUT_SCNHDR_VADDR (abfd,
853                     ((scnhdr_int->s_vaddr 
854                       - pe_data(abfd)->pe_opthdr.ImageBase)
855                      & 0xffffffff),
856                     (bfd_byte *) scnhdr_ext->s_vaddr);
857
858   /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
859      value except for the BSS section, its s_size should be 0 */
860
861
862   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
863     {
864       ps = scnhdr_int->s_size;
865       ss = 0;
866     }
867   else
868     {
869       ps = scnhdr_int->s_paddr;
870       ss = scnhdr_int->s_size;
871     }
872
873   PUT_SCNHDR_SIZE (abfd, ss,
874                    (bfd_byte *) scnhdr_ext->s_size);
875
876
877   PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
878
879   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
880                      (bfd_byte *) scnhdr_ext->s_scnptr);
881   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
882                      (bfd_byte *) scnhdr_ext->s_relptr);
883   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
884                       (bfd_byte *) scnhdr_ext->s_lnnoptr);
885
886   /* Extra flags must be set when dealing with NT.  All sections should also
887      have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
888      .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
889      sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
890      (this is especially important when dealing with the .idata section since
891      the addresses for routines from .dlls must be overwritten).  If .reloc
892      section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
893      (0x02000000).  Also, the resource data should also be read and
894      writable.  */
895
896   /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
897   /* FIXME: even worse, I don't see how to get the original alignment field*/
898   /*        back...                                                        */
899
900   /* FIXME: Basing this on section names is bogus.  Also, this should
901      be in sec_to_styp_flags.  */
902
903   {
904     int flags = scnhdr_int->s_flags;
905     if (strcmp (scnhdr_int->s_name, ".data")  == 0 ||
906         strcmp (scnhdr_int->s_name, ".CRT")   == 0 ||
907         strcmp (scnhdr_int->s_name, ".bss")   == 0)
908       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
909     else if (strcmp (scnhdr_int->s_name, ".text") == 0)
910       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
911     else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
912       flags = (SEC_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
913                | IMAGE_SCN_MEM_SHARED);
914     else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
915       flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;     
916     else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
917              || strcmp (scnhdr_int->s_name, ".edata") == 0)
918       flags =  IMAGE_SCN_MEM_READ | SEC_DATA;     
919     else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
920       flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
921                           IMAGE_SCN_MEM_READ ;
922     /* Remember this field is a max of 8 chars, so the null is _not_ there
923        for an 8 character name like ".reldata". (yep. Stupid bug) */
924     else if (strncmp (scnhdr_int->s_name, ".reldata", 8) == 0)
925       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
926                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
927     else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
928       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
929                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
930     else if (strncmp (scnhdr_int->s_name, ".drectve", 8) == 0)
931       flags =  IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
932     else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0)
933       flags |= (IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE
934                 | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ);
935     else if (strcmp (scnhdr_int->s_name, ".rsrc")  == 0)
936       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED;
937     else
938       {
939         flags |= IMAGE_SCN_MEM_READ;
940         if (! (flags & SEC_READONLY))
941           flags |= IMAGE_SCN_MEM_WRITE;
942         if (flags & SEC_SHARED)
943           flags |= IMAGE_SCN_MEM_SHARED;
944       }
945
946     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
947   }
948
949   if (scnhdr_int->s_nlnno <= 0xffff)
950     bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
951   else
952     {
953       (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
954                              bfd_get_filename (abfd),
955                              scnhdr_int->s_nlnno);
956       bfd_set_error (bfd_error_file_truncated);
957       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
958       ret = 0;
959     }
960   if (scnhdr_int->s_nreloc <= 0xffff)
961     bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
962   else
963     {
964       (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
965                              bfd_get_filename (abfd),
966                              scnhdr_int->s_nreloc);
967       bfd_set_error (bfd_error_file_truncated);
968       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
969       ret = 0;
970     }
971   return ret;
972 }
973
974 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
975 {
976   N_ ("Export Directory [.edata (or where ever we found it)]"),
977   N_ ("Import Directory [parts of .idata]"),
978   N_ ("Resource Directory [.rsrc]"),
979   N_ ("Exception Directory [.pdata]"),
980   N_ ("Security Directory"),
981   N_ ("Base Relocation Directory [.reloc]"),
982   N_ ("Debug Directory"),
983   N_ ("Description Directory"),
984   N_ ("Special Directory"),
985   N_ ("Thread Storage Directory [.tls]"),
986   N_ ("Load Configuration Directory"),
987   N_ ("Bound Import Directory"),
988   N_ ("Import Address Table Directory"),
989   N_ ("Reserved"),
990   N_ ("Reserved"),
991   N_ ("Reserved")
992 };
993
994 /**********************************************************************/
995 #ifdef POWERPC_LE_PE
996 /* The code for the PPC really falls in the "architecture dependent"
997    category.  However, it's not clear that anyone will ever care, so
998    we're ignoring the issue for now; if/when PPC matters, some of this
999    may need to go into peicode.h, or arguments passed to enable the
1000    PPC- specific code.  */
1001 #endif
1002
1003 /**********************************************************************/
1004 static boolean
1005 pe_print_idata(abfd, vfile)
1006      bfd *abfd;
1007      PTR vfile;
1008 {
1009   FILE *file = (FILE *) vfile;
1010   bfd_byte *data = 0;
1011   asection *section = bfd_get_section_by_name (abfd, ".idata");
1012   unsigned long adj;
1013
1014 #ifdef POWERPC_LE_PE
1015   asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1016 #endif
1017
1018   bfd_size_type datasize;
1019   bfd_size_type dataoff;
1020   bfd_size_type secsize;
1021   bfd_size_type i;
1022   bfd_size_type start, stop;
1023   int onaline = 20;
1024
1025   pe_data_type *pe = pe_data (abfd);
1026   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1027
1028   if (section != NULL)
1029     {
1030       datasize = bfd_section_size (abfd, section);
1031       dataoff = 0;
1032
1033       if (datasize == 0)
1034         return true;
1035     }
1036   else
1037     {
1038       bfd_vma addr, size;
1039
1040       addr = extra->DataDirectory[1].VirtualAddress;
1041       size = extra->DataDirectory[1].Size;
1042
1043       if (addr == 0 || size == 0)
1044         return true;
1045
1046       for (section = abfd->sections; section != NULL; section = section->next)
1047         {
1048           if (section->vma - extra->ImageBase <= addr
1049               && ((section->vma - extra->ImageBase
1050                    + bfd_section_size (abfd, section))
1051                   >= addr + size))
1052             break;
1053         }
1054       if (section == NULL)
1055         return true;
1056
1057       /* For some reason the import table size is not reliable.  The
1058          import data will extend past the indicated size, and before
1059          the indicated address.  */
1060       dataoff = addr - (section->vma - extra->ImageBase);
1061       datasize = size;
1062     }
1063
1064 #ifdef POWERPC_LE_PE
1065   if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1066     {
1067       /* The toc address can be found by taking the starting address,
1068          which on the PPC locates a function descriptor. The
1069          descriptor consists of the function code starting address
1070          followed by the address of the toc. The starting address we
1071          get from the bfd, and the descriptor is supposed to be in the
1072          .reldata section.  */
1073
1074       bfd_vma loadable_toc_address;
1075       bfd_vma toc_address;
1076       bfd_vma start_address;
1077       bfd_byte *data = 0;
1078       int offset;
1079       data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1080                                                                  rel_section));
1081       if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1082         return false;
1083
1084       datasize = bfd_section_size (abfd, rel_section);
1085   
1086       bfd_get_section_contents (abfd,
1087                                 rel_section,
1088                                 (PTR) data, 0,
1089                                 bfd_section_size (abfd, rel_section));
1090
1091       offset = abfd->start_address - rel_section->vma;
1092
1093       start_address = bfd_get_32(abfd, data+offset);
1094       loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1095       toc_address = loadable_toc_address - 32768;
1096
1097       fprintf(file,
1098               _("\nFunction descriptor located at the start address: %04lx\n"),
1099               (unsigned long int) (abfd->start_address));
1100       fprintf (file,
1101                _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
1102                start_address, loadable_toc_address, toc_address);
1103     }
1104   else
1105     {
1106       fprintf(file,
1107               _("\nNo reldata section! Function descriptor not decoded.\n"));
1108     }
1109 #endif
1110
1111   fprintf(file,
1112           _("\nThe Import Tables (interpreted .idata section contents)\n"));
1113   fprintf(file,
1114           _(" vma:            Hint    Time      Forward  DLL       First\n"));
1115   fprintf(file,
1116           _("                 Table   Stamp     Chain    Name      Thunk\n"));
1117
1118   secsize = bfd_section_size (abfd, section);
1119   data = (bfd_byte *) bfd_malloc (secsize);
1120   if (data == NULL && secsize != 0)
1121     return false;
1122
1123   if (! bfd_get_section_contents (abfd, section, (PTR) data, 0, secsize))
1124     return false;
1125
1126   adj = (extra->ImageBase - section->vma) & 0xffffffff;
1127
1128   start = dataoff;
1129   stop = dataoff + datasize;
1130   for (i = start; i < stop; i += onaline)
1131     {
1132       bfd_vma hint_addr;
1133       bfd_vma time_stamp;
1134       bfd_vma forward_chain;
1135       bfd_vma dll_name;
1136       bfd_vma first_thunk;
1137       int idx = 0;
1138       bfd_size_type j;
1139       char *dll;
1140
1141       fprintf (file,
1142                " %08lx\t",
1143                (unsigned long int) (i + section->vma + dataoff));
1144       
1145       if (i+20 > stop)
1146         {
1147           /* check stuff */
1148           ;
1149         }
1150       
1151       hint_addr = bfd_get_32(abfd, data+i);
1152       time_stamp = bfd_get_32(abfd, data+i+4);
1153       forward_chain = bfd_get_32(abfd, data+i+8);
1154       dll_name = bfd_get_32(abfd, data+i+12);
1155       first_thunk = bfd_get_32(abfd, data+i+16);
1156       
1157       fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1158               hint_addr,
1159               time_stamp,
1160               forward_chain,
1161               dll_name,
1162               first_thunk);
1163
1164       if (hint_addr == 0 && first_thunk == 0)
1165         break;
1166
1167       /* the image base is present in the section->vma */
1168       dll = (char *) data + dll_name + adj;
1169       fprintf(file, _("\n\tDLL Name: %s\n"), dll);
1170
1171       if (hint_addr != 0)
1172         {
1173           fprintf (file, _("\tvma:  Hint/Ord Member-Name\n"));
1174
1175           idx = hint_addr + adj;
1176
1177           for (j = 0; j < stop; j += 4)
1178             {
1179               unsigned long member = bfd_get_32 (abfd, data + idx + j);
1180
1181               if (member == 0)
1182                 break;
1183               if (member & 0x80000000)
1184                 fprintf (file, "\t%04lx\t %4lu", member,
1185                          member & 0x7fffffff);
1186               else
1187                 {
1188                   int ordinal;
1189                   char *member_name;
1190
1191                   ordinal = bfd_get_16 (abfd, data + member + adj);
1192                   member_name = (char *) data + member + adj + 2;
1193                   fprintf (file, "\t%04lx\t %4d  %s",
1194                            member, ordinal, member_name);
1195                 }
1196
1197               /* If the time stamp is not zero, the import address
1198                  table holds actual addresses.  */
1199               if (time_stamp != 0
1200                   && first_thunk != 0
1201                   && first_thunk != hint_addr)
1202                 fprintf (file, "\t%04lx",
1203                          bfd_get_32 (abfd, data + first_thunk + adj + j));
1204
1205               fprintf (file, "\n");
1206             }
1207         }
1208
1209       if (hint_addr != first_thunk && time_stamp == 0)
1210         {
1211           int differ = 0;
1212           int idx2;
1213
1214           idx2 = first_thunk + adj;
1215
1216           for (j=0;j<stop;j+=4)
1217             {
1218               int ordinal;
1219               char *member_name;
1220               bfd_vma hint_member = 0;
1221               bfd_vma iat_member;
1222
1223               if (hint_addr != 0)
1224                 hint_member = bfd_get_32 (abfd, data + idx + j);
1225               iat_member = bfd_get_32 (abfd, data + idx2 + j);
1226
1227               if (hint_addr == 0 && iat_member == 0)
1228                 break;
1229
1230               if (hint_addr == 0 || hint_member != iat_member)
1231                 {
1232                   if (differ == 0)
1233                     {
1234                       fprintf (file,
1235                                _("\tThe Import Address Table (difference found)\n"));
1236                       fprintf(file, _("\tvma:  Hint/Ord Member-Name\n"));
1237                       differ = 1;
1238                     }
1239                   if (iat_member == 0)
1240                     {
1241                       fprintf(file,
1242                               _("\t>>> Ran out of IAT members!\n"));
1243                     }
1244                   else
1245                     {
1246                       ordinal = bfd_get_16(abfd,
1247                                            data + iat_member + adj);
1248                       member_name = (char *) data + iat_member + adj + 2;
1249                       fprintf(file, "\t%04lx\t %4d  %s\n",
1250                               iat_member, ordinal, member_name);
1251                     }
1252                 }
1253
1254               if (hint_addr != 0 && hint_member == 0)
1255                 break;
1256             }
1257           if (differ == 0)
1258             {
1259               fprintf(file,
1260                       _("\tThe Import Address Table is identical\n"));
1261             }
1262         }
1263
1264       fprintf(file, "\n");
1265
1266     }
1267
1268   free (data);
1269
1270   return true;
1271 }
1272
1273 static boolean
1274 pe_print_edata (abfd, vfile)
1275      bfd *abfd;
1276      PTR vfile;
1277 {
1278   FILE *file = (FILE *) vfile;
1279   bfd_byte *data = 0;
1280   asection *section = bfd_get_section_by_name (abfd, ".edata");
1281
1282   bfd_size_type datasize;
1283   bfd_size_type dataoff;
1284   bfd_size_type i;
1285
1286   int adj;
1287   struct EDT_type
1288     {
1289       long export_flags;             /* reserved - should be zero */
1290       long time_stamp;
1291       short major_ver;
1292       short minor_ver;
1293       bfd_vma name;                  /* rva - relative to image base */
1294       long base;                     /* ordinal base */
1295       unsigned long num_functions;   /* Number in the export address table */
1296       unsigned long num_names;       /* Number in the name pointer table */
1297       bfd_vma eat_addr;    /* rva to the export address table */
1298       bfd_vma npt_addr;        /* rva to the Export Name Pointer Table */
1299       bfd_vma ot_addr; /* rva to the Ordinal Table */
1300     } edt;
1301
1302   pe_data_type *pe = pe_data (abfd);
1303   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1304
1305   if (section != NULL)
1306     {
1307       datasize = bfd_section_size (abfd, section);
1308       dataoff = 0;
1309     }
1310   else
1311     {
1312       bfd_vma addr, size;
1313
1314       addr = extra->DataDirectory[0].VirtualAddress;
1315       size = extra->DataDirectory[0].Size;
1316
1317       if (addr == 0 || size == 0)
1318         return true;
1319
1320       for (section = abfd->sections; section != NULL; section = section->next)
1321         {
1322           if (section->vma - extra->ImageBase <= addr
1323               && ((section->vma - extra->ImageBase
1324                    + bfd_section_size (abfd, section))
1325                   >= addr + size))
1326             break;
1327         }
1328       if (section == NULL)
1329         return true;
1330
1331       datasize = size;
1332       dataoff = addr - (section->vma - extra->ImageBase);
1333     }
1334
1335   data = (bfd_byte *) bfd_malloc (datasize);
1336   if (data == NULL && datasize != 0)
1337     return false;
1338
1339   if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff,
1340                                   datasize))
1341     return false;
1342
1343   /* Go get Export Directory Table */
1344   edt.export_flags   = bfd_get_32(abfd, data+0);
1345   edt.time_stamp     = bfd_get_32(abfd, data+4);
1346   edt.major_ver      = bfd_get_16(abfd, data+8);
1347   edt.minor_ver      = bfd_get_16(abfd, data+10);
1348   edt.name           = bfd_get_32(abfd, data+12);
1349   edt.base           = bfd_get_32(abfd, data+16);
1350   edt.num_functions  = bfd_get_32(abfd, data+20);
1351   edt.num_names      = bfd_get_32(abfd, data+24);
1352   edt.eat_addr       = bfd_get_32(abfd, data+28);
1353   edt.npt_addr       = bfd_get_32(abfd, data+32);
1354   edt.ot_addr        = bfd_get_32(abfd, data+36);
1355
1356   adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff;
1357
1358   /* Dump the EDT first first */
1359   fprintf(file,
1360           _("\nThe Export Tables (interpreted .edata section contents)\n\n"));
1361
1362   fprintf(file,
1363           _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
1364
1365   fprintf(file,
1366           _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
1367
1368   fprintf(file,
1369           _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
1370
1371   fprintf (file,
1372            _("Name \t\t\t\t"));
1373   fprintf_vma (file, edt.name);
1374   fprintf (file,
1375            " %s\n", data + edt.name + adj);
1376
1377   fprintf(file,
1378           _("Ordinal Base \t\t\t%ld\n"), edt.base);
1379
1380   fprintf(file,
1381           _("Number in:\n"));
1382
1383   fprintf(file,
1384           _("\tExport Address Table \t\t%lx\n"),
1385           edt.num_functions);
1386
1387   fprintf(file,
1388           _("\t[Name Pointer/Ordinal] Table\t%lu\n"), edt.num_names);
1389
1390   fprintf(file,
1391           _("Table Addresses\n"));
1392
1393   fprintf (file,
1394            _("\tExport Address Table \t\t"));
1395   fprintf_vma (file, edt.eat_addr);
1396   fprintf (file, "\n");
1397
1398   fprintf (file,
1399           _("\tName Pointer Table \t\t"));
1400   fprintf_vma (file, edt.npt_addr);
1401   fprintf (file, "\n");
1402
1403   fprintf (file,
1404            _("\tOrdinal Table \t\t\t"));
1405   fprintf_vma (file, edt.ot_addr);
1406   fprintf (file, "\n");
1407
1408   
1409   /* The next table to find si the Export Address Table. It's basically
1410      a list of pointers that either locate a function in this dll, or
1411      forward the call to another dll. Something like:
1412       typedef union
1413       {
1414         long export_rva;
1415         long forwarder_rva;
1416       } export_address_table_entry;
1417   */
1418
1419   fprintf(file,
1420           _("\nExport Address Table -- Ordinal Base %ld\n"),
1421           edt.base);
1422
1423   for (i = 0; i < edt.num_functions; ++i)
1424     {
1425       bfd_vma eat_member = bfd_get_32 (abfd,
1426                                        data + edt.eat_addr + (i * 4) + adj);
1427       bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff;
1428       bfd_vma edata_start = bfd_get_section_vma (abfd,section) + dataoff;
1429       bfd_vma edata_end = edata_start + datasize;
1430
1431       if (eat_member == 0)
1432         continue;
1433
1434       if (edata_start < eat_actual && eat_actual < edata_end)
1435         {
1436           /* this rva is to a name (forwarding function) in our section */
1437           /* Should locate a function descriptor */
1438           fprintf(file,
1439                   "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1440                   (long) i, (long) (i + edt.base), eat_member,
1441                   "Forwarder RVA", data + eat_member + adj);
1442         }
1443       else
1444         {
1445           /* Should locate a function descriptor in the reldata section */
1446           fprintf(file,
1447                   "\t[%4ld] +base[%4ld] %04lx %s\n",
1448                   (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1449         }
1450     }
1451
1452   /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1453   /* Dump them in parallel for clarity */
1454   fprintf(file,
1455           _("\n[Ordinal/Name Pointer] Table\n"));
1456
1457   for (i = 0; i < edt.num_names; ++i)
1458     {
1459       bfd_vma name_ptr = bfd_get_32(abfd,
1460                                     data +
1461                                     edt.npt_addr
1462                                     + (i*4) + adj);
1463       
1464       char *name = (char *) data + name_ptr + adj;
1465
1466       bfd_vma ord = bfd_get_16(abfd,
1467                                     data +
1468                                     edt.ot_addr
1469                                     + (i*2) + adj);
1470       fprintf(file,
1471               "\t[%4ld] %s\n", (long) ord, name);
1472
1473     }
1474
1475   free (data);
1476
1477   return true;
1478 }
1479
1480 static boolean
1481 pe_print_pdata (abfd, vfile)
1482      bfd  *abfd;
1483      PTR vfile;
1484 {
1485   FILE *file = (FILE *) vfile;
1486   bfd_byte *data = 0;
1487   asection *section = bfd_get_section_by_name (abfd, ".pdata");
1488   bfd_size_type datasize = 0;
1489   bfd_size_type i;
1490   bfd_size_type start, stop;
1491   int onaline = 20;
1492
1493   if (section == 0)
1494     return true;
1495
1496   stop = bfd_section_size (abfd, section);
1497   if ((stop % onaline) != 0)
1498     fprintf (file, _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
1499              (long)stop, onaline);
1500
1501   fprintf(file,
1502           _("\nThe Function Table (interpreted .pdata section contents)\n"));
1503   fprintf(file,
1504           _(" vma:\t\tBegin    End      EH       EH       PrologEnd\n"));
1505   fprintf(file,
1506           _("     \t\tAddress  Address  Handler  Data     Address\n"));
1507
1508   if (bfd_section_size (abfd, section) == 0)
1509     return true;
1510
1511   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1512   datasize = bfd_section_size (abfd, section);
1513   if (data == NULL && datasize != 0)
1514     return false;
1515
1516   bfd_get_section_contents (abfd,
1517                             section,
1518                             (PTR) data, 0,
1519                             bfd_section_size (abfd, section));
1520
1521   start = 0;
1522
1523   for (i = start; i < stop; i += onaline)
1524     {
1525       bfd_vma begin_addr;
1526       bfd_vma end_addr;
1527       bfd_vma eh_handler;
1528       bfd_vma eh_data;
1529       bfd_vma prolog_end_addr;
1530
1531       if (i+20 > stop)
1532         break;
1533       
1534       begin_addr = bfd_get_32(abfd, data+i);
1535       end_addr = bfd_get_32(abfd, data+i+4);
1536       eh_handler = bfd_get_32(abfd, data+i+8);
1537       eh_data = bfd_get_32(abfd, data+i+12);
1538       prolog_end_addr = bfd_get_32(abfd, data+i+16);
1539       
1540       if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1541           && eh_data == 0 && prolog_end_addr == 0)
1542         {
1543           /* We are probably into the padding of the section now.  */
1544           break;
1545         }
1546
1547       fprintf (file,
1548                " %08lx\t",
1549                (unsigned long int) (i + section->vma));
1550
1551       fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1552               begin_addr,
1553               end_addr,
1554               eh_handler,
1555               eh_data,
1556               prolog_end_addr);
1557
1558 #ifdef POWERPC_LE_PE
1559       if (eh_handler == 0 && eh_data != 0)
1560         {
1561           /* Special bits here, although the meaning may */
1562           /* be a little mysterious. The only one I know */
1563           /* for sure is 0x03.                           */
1564           /* Code Significance                           */
1565           /* 0x00 None                                   */
1566           /* 0x01 Register Save Millicode                */
1567           /* 0x02 Register Restore Millicode             */
1568           /* 0x03 Glue Code Sequence                     */
1569           switch (eh_data)
1570             {
1571             case 0x01:
1572               fprintf(file, _(" Register save millicode"));
1573               break;
1574             case 0x02:
1575               fprintf(file, _(" Register restore millicode"));
1576               break;
1577             case 0x03:
1578               fprintf(file, _(" Glue code sequence"));
1579               break;
1580             default:
1581               break;
1582             }
1583         }
1584 #endif
1585       fprintf(file, "\n");
1586     }
1587
1588   free (data);
1589
1590   return true;
1591 }
1592
1593 static const char *tbl[6] =
1594 {
1595 "ABSOLUTE",
1596 "HIGH",
1597 "LOW",
1598 "HIGHLOW",
1599 "HIGHADJ",
1600 "MIPS_JMPADDR"
1601 };
1602
1603 static boolean
1604 pe_print_reloc (abfd, vfile)
1605      bfd *abfd;
1606      PTR vfile;
1607 {
1608   FILE *file = (FILE *) vfile;
1609   bfd_byte *data = 0;
1610   asection *section = bfd_get_section_by_name (abfd, ".reloc");
1611   bfd_size_type datasize = 0;
1612   bfd_size_type i;
1613   bfd_size_type start, stop;
1614
1615   if (section == 0)
1616     return true;
1617
1618   if (bfd_section_size (abfd, section) == 0)
1619     return true;
1620
1621   fprintf(file,
1622           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
1623
1624   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1625   datasize = bfd_section_size (abfd, section);
1626   if (data == NULL && datasize != 0)
1627     return false;
1628
1629   bfd_get_section_contents (abfd,
1630                             section,
1631                             (PTR) data, 0,
1632                             bfd_section_size (abfd, section));
1633
1634   start = 0;
1635
1636   stop = bfd_section_size (abfd, section);
1637
1638   for (i = start; i < stop;)
1639     {
1640       int j;
1641       bfd_vma virtual_address;
1642       long number, size;
1643
1644       /* The .reloc section is a sequence of blocks, with a header consisting
1645          of two 32 bit quantities, followed by a number of 16 bit entries */
1646
1647       virtual_address = bfd_get_32(abfd, data+i);
1648       size = bfd_get_32(abfd, data+i+4);
1649       number = (size - 8) / 2;
1650
1651       if (size == 0)
1652         {
1653           break;
1654         }
1655
1656       fprintf (file,
1657                _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
1658                virtual_address, size, size, number);
1659
1660       for (j = 0; j < number; ++j)
1661         {
1662           unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1663           int t =   (e & 0xF000) >> 12;
1664           int off = e & 0x0FFF;
1665
1666           if (t > 5) 
1667             abort();
1668
1669           fprintf(file,
1670                   _("\treloc %4d offset %4x [%4lx] %s\n"), 
1671                   j, off, (long) (off + virtual_address), tbl[t]);
1672
1673         }
1674       i += size;
1675     }
1676
1677   free (data);
1678
1679   return true;
1680 }
1681
1682 /* Print out the program headers.  */
1683
1684 boolean
1685 _bfd_pe_print_private_bfd_data_common (abfd, vfile)
1686      bfd *abfd;
1687      PTR vfile;
1688 {
1689   FILE *file = (FILE *) vfile;
1690   int j;
1691   pe_data_type *pe = pe_data (abfd);
1692   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1693
1694   /* The MS dumpbin program reportedly ands with 0xff0f before
1695      printing the characteristics field.  Not sure why.  No reason to
1696      emulate it here.  */
1697   fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
1698 #undef PF
1699 #define PF(x, y)    if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
1700   PF (F_RELFLG, "relocations stripped");
1701   PF (F_EXEC, "executable");
1702   PF (F_LNNO, "line numbers stripped");
1703   PF (F_LSYMS, "symbols stripped");
1704   PF (0x80, "little endian");
1705   PF (F_AR32WR, "32 bit words");
1706   PF (0x200, "debugging information removed");
1707   PF (0x1000, "system file");
1708   PF (F_DLL, "DLL");
1709   PF (0x8000, "big endian");
1710 #undef PF
1711
1712   fprintf (file,"\nImageBase\t\t");
1713   fprintf_vma (file, i->ImageBase);
1714   fprintf (file,"\nSectionAlignment\t");
1715   fprintf_vma (file, i->SectionAlignment);
1716   fprintf (file,"\nFileAlignment\t\t");
1717   fprintf_vma (file, i->FileAlignment);
1718   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1719   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1720   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1721   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1722   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1723   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1724   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1725   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1726   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1727   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1728   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1729   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1730   fprintf (file,"SizeOfStackReserve\t");
1731   fprintf_vma (file, i->SizeOfStackReserve);
1732   fprintf (file,"\nSizeOfStackCommit\t");
1733   fprintf_vma (file, i->SizeOfStackCommit);
1734   fprintf (file,"\nSizeOfHeapReserve\t");
1735   fprintf_vma (file, i->SizeOfHeapReserve);
1736   fprintf (file,"\nSizeOfHeapCommit\t");
1737   fprintf_vma (file, i->SizeOfHeapCommit);
1738   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1739   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1740
1741   fprintf (file,"\nThe Data Directory\n");
1742   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1743     {
1744       fprintf (file, "Entry %1x ", j);
1745       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1746       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1747       fprintf (file, "%s\n", dir_names[j]);
1748     }
1749
1750   pe_print_idata (abfd, vfile);
1751   pe_print_edata (abfd, vfile);
1752   pe_print_pdata (abfd, vfile);
1753   pe_print_reloc (abfd, vfile);
1754
1755   return true;
1756 }
1757
1758 /* Copy any private info we understand from the input bfd
1759    to the output bfd.  */
1760
1761 boolean
1762 _bfd_pe_bfd_copy_private_bfd_data_common (ibfd, obfd)
1763      bfd *ibfd, *obfd;
1764 {
1765   /* One day we may try to grok other private data.  */
1766   if (ibfd->xvec->flavour != bfd_target_coff_flavour
1767       || obfd->xvec->flavour != bfd_target_coff_flavour)
1768     return true;
1769
1770   pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1771   pe_data (obfd)->dll = pe_data (ibfd)->dll;
1772
1773   return true;
1774 }
1775
1776 /* Copy private section data. */
1777 boolean
1778 _bfd_pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
1779      bfd *ibfd;
1780      asection *isec;
1781      bfd *obfd;
1782      asection *osec;
1783 {
1784   if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
1785       || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
1786     return true;
1787
1788   if (coff_section_data (ibfd, isec) != NULL
1789       && pei_section_data (ibfd, isec) != NULL)
1790     {
1791       if (coff_section_data (obfd, osec) == NULL)
1792         {
1793           osec->used_by_bfd =
1794             (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
1795           if (osec->used_by_bfd == NULL)
1796             return false;
1797         }
1798       if (pei_section_data (obfd, osec) == NULL)
1799         {
1800           coff_section_data (obfd, osec)->tdata =
1801             (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
1802           if (coff_section_data (obfd, osec)->tdata == NULL)
1803             return false;
1804         }
1805       pei_section_data (obfd, osec)->virt_size =
1806         pei_section_data (ibfd, isec)->virt_size;
1807     }
1808
1809   return true;
1810 }
1811
1812 void
1813 _bfd_pe_get_symbol_info (abfd, symbol, ret)
1814      bfd *abfd;
1815      asymbol *symbol;
1816      symbol_info *ret;
1817 {
1818   coff_get_symbol_info (abfd, symbol, ret);
1819
1820   if (pe_data (abfd) != NULL
1821       && ((symbol->flags & BSF_DEBUGGING) == 0
1822           || (symbol->flags & BSF_DEBUGGING_RELOC) != 0)
1823       && ! bfd_is_abs_section (symbol->section))
1824     ret->value += pe_data (abfd)->pe_opthdr.ImageBase;
1825 }