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