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