Remove (most of the) target dependent code from peicode.h
[external/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   "Export Directory [.edata (or where ever we found it)]",
1207   "Import Directory [parts of .idata]",
1208   "Resource Directory [.rsrc]",
1209   "Exception Directory [.pdata]",
1210   "Security Directory",
1211   "Base Relocation Directory [.reloc]",
1212   "Debug Directory",
1213   "Description Directory",
1214   "Special Directory",
1215   "Thread Storage Directory [.tls]",
1216   "Load Configuration Directory",
1217   "Bound Import Directory",
1218   "Import Address Table Directory",
1219   "Reserved",
1220   "Reserved",
1221   "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;
1359       int 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;
1442               bfd_vma iat_member;
1443
1444               if (time_stamp != 0)
1445                 {
1446                 }
1447
1448               if (hint_addr != 0)
1449                 hint_member = bfd_get_32 (abfd, data + idx + j);
1450               iat_member = bfd_get_32 (abfd, data + idx2 + j);
1451
1452               if (hint_addr == 0 && iat_member == 0)
1453                 break;
1454
1455               if (hint_addr == 0 || hint_member != iat_member)
1456                 {
1457                   if (differ == 0)
1458                     {
1459                       fprintf (file, 
1460                                "\tThe Import Address Table (difference found)\n");
1461                       fprintf(file, "\tvma:  Hint/Ord Member-Name\n");
1462                       differ = 1;
1463                     }
1464                   if (iat_member == 0)
1465                     {
1466                       fprintf(file,
1467                               "\t>>> Ran out of IAT members!\n");
1468                     }
1469                   else 
1470                     {
1471                       ordinal = bfd_get_16(abfd,
1472                                            data + iat_member + adj);
1473                       member_name = (char *) data + iat_member + adj + 2;
1474                       fprintf(file, "\t%04lx\t %4d  %s\n",
1475                               iat_member, ordinal, member_name);
1476                     }
1477                 }
1478
1479               if (hint_addr != 0 && hint_member == 0)
1480                 break;
1481             }
1482           if (differ == 0)
1483             {
1484               fprintf(file,
1485                       "\tThe Import Address Table is identical\n");
1486             }
1487         }
1488
1489       fprintf(file, "\n");
1490
1491     }
1492
1493   free (data);
1494
1495   return true;
1496 }
1497
1498 static boolean
1499 pe_print_edata (abfd, vfile)
1500      bfd *abfd;
1501      PTR vfile;
1502 {
1503   FILE *file = (FILE *) vfile;
1504   bfd_byte *data = 0;
1505   asection *section = bfd_get_section_by_name (abfd, ".edata");
1506
1507   bfd_size_type datasize;
1508   bfd_size_type dataoff;
1509   bfd_size_type i;
1510
1511   int adj;
1512   struct EDT_type 
1513     {
1514       long export_flags;             /* reserved - should be zero */
1515       long time_stamp;
1516       short major_ver;
1517       short minor_ver;
1518       bfd_vma name;                  /* rva - relative to image base */
1519       long base;                     /* ordinal base */
1520       long num_functions;        /* Number in the export address table */
1521       long num_names;            /* Number in the name pointer table */
1522       bfd_vma eat_addr;    /* rva to the export address table */
1523       bfd_vma npt_addr;        /* rva to the Export Name Pointer Table */
1524       bfd_vma ot_addr; /* rva to the Ordinal Table */
1525     } edt;
1526
1527   pe_data_type *pe = pe_data (abfd);
1528   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1529
1530   if (section != NULL)
1531     {
1532       datasize = bfd_section_size (abfd, section);
1533       dataoff = 0;
1534     }
1535   else
1536     {
1537       bfd_vma addr, size;
1538
1539       addr = extra->DataDirectory[0].VirtualAddress;
1540       size = extra->DataDirectory[0].Size;
1541
1542       if (addr == 0 || size == 0)
1543         return true;
1544
1545       for (section = abfd->sections; section != NULL; section = section->next)
1546         {
1547           if (section->vma - extra->ImageBase <= addr
1548               && ((section->vma - extra->ImageBase
1549                    + bfd_section_size (abfd, section))
1550                   >= addr + size))
1551             break;
1552         }
1553       if (section == NULL)
1554         return true;
1555
1556       datasize = size;
1557       dataoff = addr - (section->vma - extra->ImageBase);
1558     }
1559
1560   data = (bfd_byte *) bfd_malloc (datasize);
1561   if (data == NULL && datasize != 0)
1562     return false;
1563
1564   if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff,
1565                                   datasize))
1566     return false;
1567
1568   /* Go get Export Directory Table */
1569   edt.export_flags   = bfd_get_32(abfd, data+0); 
1570   edt.time_stamp     = bfd_get_32(abfd, data+4);
1571   edt.major_ver      = bfd_get_16(abfd, data+8);
1572   edt.minor_ver      = bfd_get_16(abfd, data+10);
1573   edt.name           = bfd_get_32(abfd, data+12);
1574   edt.base           = bfd_get_32(abfd, data+16);
1575   edt.num_functions  = bfd_get_32(abfd, data+20); 
1576   edt.num_names      = bfd_get_32(abfd, data+24); 
1577   edt.eat_addr       = bfd_get_32(abfd, data+28);
1578   edt.npt_addr       = bfd_get_32(abfd, data+32); 
1579   edt.ot_addr        = bfd_get_32(abfd, data+36);
1580
1581   adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff;
1582
1583
1584   /* Dump the EDT first first */
1585   fprintf(file,
1586           "\nThe Export Tables (interpreted .edata section contents)\n\n");
1587
1588   fprintf(file,
1589           "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1590
1591   fprintf(file,
1592           "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1593
1594   fprintf(file,
1595           "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1596
1597   fprintf (file,
1598            "Name \t\t\t\t");
1599   fprintf_vma (file, edt.name);
1600   fprintf (file,
1601            " %s\n", data + edt.name + adj);
1602
1603   fprintf(file,
1604           "Ordinal Base \t\t\t%ld\n", edt.base);
1605
1606   fprintf(file,
1607           "Number in:\n");
1608
1609   fprintf(file,
1610           "\tExport Address Table \t\t%lx\n",
1611           (unsigned long) edt.num_functions);
1612
1613   fprintf(file,
1614           "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1615
1616   fprintf(file,
1617           "Table Addresses\n");
1618
1619   fprintf (file,
1620            "\tExport Address Table \t\t");
1621   fprintf_vma (file, edt.eat_addr);
1622   fprintf (file, "\n");
1623
1624   fprintf (file,
1625           "\tName Pointer Table \t\t");
1626   fprintf_vma (file, edt.npt_addr);
1627   fprintf (file, "\n");
1628
1629   fprintf (file,
1630            "\tOrdinal Table \t\t\t");
1631   fprintf_vma (file, edt.ot_addr);
1632   fprintf (file, "\n");
1633
1634   
1635   /* The next table to find si the Export Address Table. It's basically
1636      a list of pointers that either locate a function in this dll, or
1637      forward the call to another dll. Something like:
1638       typedef union 
1639       {
1640         long export_rva;
1641         long forwarder_rva;
1642       } export_address_table_entry;
1643   */
1644
1645   fprintf(file,
1646           "\nExport Address Table -- Ordinal Base %ld\n",
1647           edt.base);
1648
1649   for (i = 0; i < edt.num_functions; ++i)
1650     {
1651       bfd_vma eat_member = bfd_get_32 (abfd, 
1652                                        data + edt.eat_addr + (i * 4) + adj);
1653       bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff;
1654       bfd_vma edata_start = bfd_get_section_vma (abfd,section) + dataoff;
1655       bfd_vma edata_end = edata_start + datasize;
1656
1657       if (eat_member == 0)
1658         continue;
1659
1660       if (edata_start < eat_actual && eat_actual < edata_end) 
1661         {
1662           /* this rva is to a name (forwarding function) in our section */
1663           /* Should locate a function descriptor */
1664           fprintf(file,
1665                   "\t[%4ld] +base[%4ld] %04lx %s -- %s\n", 
1666                   (long) i, (long) (i + edt.base), eat_member,
1667                   "Forwarder RVA", data + eat_member + adj);
1668         }
1669       else
1670         {
1671           /* Should locate a function descriptor in the reldata section */
1672           fprintf(file,
1673                   "\t[%4ld] +base[%4ld] %04lx %s\n", 
1674                   (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1675         }
1676     }
1677
1678   /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1679   /* Dump them in parallel for clarity */
1680   fprintf(file,
1681           "\n[Ordinal/Name Pointer] Table\n");
1682
1683   for (i = 0; i < edt.num_names; ++i)
1684     {
1685       bfd_vma name_ptr = bfd_get_32(abfd, 
1686                                     data + 
1687                                     edt.npt_addr
1688                                     + (i*4) + adj);
1689       
1690       char *name = (char *) data + name_ptr + adj;
1691
1692       bfd_vma ord = bfd_get_16(abfd, 
1693                                     data + 
1694                                     edt.ot_addr
1695                                     + (i*2) + adj);
1696       fprintf(file,
1697               "\t[%4ld] %s\n", (long) ord, name);
1698
1699     }
1700
1701   free (data);
1702
1703   return true;
1704 }
1705
1706 static boolean
1707 pe_print_pdata (abfd, vfile)
1708      bfd  *abfd;
1709      PTR vfile;
1710 {
1711   FILE *file = (FILE *) vfile;
1712   bfd_byte *data = 0;
1713   asection *section = bfd_get_section_by_name (abfd, ".pdata");
1714   bfd_size_type datasize = 0;
1715   bfd_size_type i;
1716   bfd_size_type start, stop;
1717   int onaline = 20;
1718
1719   if (section == 0)
1720     return true;
1721
1722   stop = bfd_section_size (abfd, section);
1723   if ((stop % onaline) != 0)
1724     fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1725              (long)stop, onaline);
1726
1727   fprintf(file,
1728           "\nThe Function Table (interpreted .pdata section contents)\n");
1729   fprintf(file,
1730           " vma:\t\tBegin    End      EH       EH       PrologEnd\n");
1731   fprintf(file,
1732           "     \t\tAddress  Address  Handler  Data     Address\n");
1733
1734   if (bfd_section_size (abfd, section) == 0)
1735     return true;
1736
1737   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1738   datasize = bfd_section_size (abfd, section);
1739   if (data == NULL && datasize != 0)
1740     return false;
1741
1742   bfd_get_section_contents (abfd, 
1743                             section, 
1744                             (PTR) data, 0, 
1745                             bfd_section_size (abfd, section));
1746
1747   start = 0;
1748
1749   for (i = start; i < stop; i += onaline)
1750     {
1751       bfd_vma begin_addr;
1752       bfd_vma end_addr;
1753       bfd_vma eh_handler;
1754       bfd_vma eh_data;
1755       bfd_vma prolog_end_addr;
1756
1757       if (i+20 > stop)
1758           break;
1759       
1760       begin_addr = bfd_get_32(abfd, data+i);
1761       end_addr = bfd_get_32(abfd, data+i+4);
1762       eh_handler = bfd_get_32(abfd, data+i+8);
1763       eh_data = bfd_get_32(abfd, data+i+12);
1764       prolog_end_addr = bfd_get_32(abfd, data+i+16);
1765       
1766       if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1767           && eh_data == 0 && prolog_end_addr == 0)
1768         {
1769           /* We are probably into the padding of the
1770              section now */
1771           break;
1772         }
1773
1774       fprintf (file,
1775                " %08lx\t", 
1776                (unsigned long int) (i + section->vma));
1777
1778       fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1779               begin_addr,
1780               end_addr,
1781               eh_handler,
1782               eh_data,
1783               prolog_end_addr);
1784
1785 #ifdef POWERPC_LE_PE
1786       if (eh_handler == 0 && eh_data != 0)
1787         {
1788           /* Special bits here, although the meaning may */
1789           /* be a little mysterious. The only one I know */
1790           /* for sure is 0x03.                           */
1791           /* Code Significance                           */
1792           /* 0x00 None                                   */
1793           /* 0x01 Register Save Millicode                */
1794           /* 0x02 Register Restore Millicode             */
1795           /* 0x03 Glue Code Sequence                     */
1796           switch (eh_data)
1797             {
1798             case 0x01:
1799               fprintf(file, " Register save millicode");
1800               break;
1801             case 0x02:
1802               fprintf(file, " Register restore millicode");
1803               break;
1804             case 0x03:
1805               fprintf(file, " Glue code sequence");
1806               break;
1807             default:
1808               break;
1809             }
1810         }
1811 #endif     
1812       fprintf(file, "\n");
1813     }
1814
1815   free (data);
1816
1817   return true;
1818 }
1819
1820 static const char *tbl[6] =
1821 {
1822 "ABSOLUTE",
1823 "HIGH",
1824 "LOW",
1825 "HIGHLOW",
1826 "HIGHADJ",
1827 "MIPS_JMPADDR"
1828 };
1829
1830 static boolean
1831 pe_print_reloc (abfd, vfile)
1832      bfd *abfd;
1833      PTR vfile;
1834 {
1835   FILE *file = (FILE *) vfile;
1836   bfd_byte *data = 0;
1837   asection *section = bfd_get_section_by_name (abfd, ".reloc");
1838   bfd_size_type datasize = 0;
1839   bfd_size_type i;
1840   bfd_size_type start, stop;
1841
1842   if (section == 0)
1843     return true;
1844
1845   if (bfd_section_size (abfd, section) == 0)
1846     return true;
1847
1848   fprintf(file,
1849           "\n\nPE File Base Relocations (interpreted .reloc section contents)\n");
1850
1851   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1852   datasize = bfd_section_size (abfd, section);
1853   if (data == NULL && datasize != 0)
1854     return false;
1855
1856   bfd_get_section_contents (abfd, 
1857                             section, 
1858                             (PTR) data, 0, 
1859                             bfd_section_size (abfd, section));
1860
1861   start = 0;
1862
1863   stop = bfd_section_size (abfd, section);
1864
1865   for (i = start; i < stop;)
1866     {
1867       int j;
1868       bfd_vma virtual_address;
1869       long number, size;
1870
1871       /* The .reloc section is a sequence of blocks, with a header consisting
1872          of two 32 bit quantities, followed by a number of 16 bit entries */
1873
1874       virtual_address = bfd_get_32(abfd, data+i);
1875       size = bfd_get_32(abfd, data+i+4);
1876       number = (size - 8) / 2;
1877
1878       if (size == 0) 
1879         {
1880           break;
1881         }
1882
1883       fprintf (file,
1884                "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1885                virtual_address, size, size, number);
1886
1887       for (j = 0; j < number; ++j)
1888         {
1889           unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1890           int t =   (e & 0xF000) >> 12;
1891           int off = e & 0x0FFF;
1892
1893           if (t > 5) 
1894             abort();
1895
1896           fprintf(file,
1897                   "\treloc %4d offset %4x [%4lx] %s\n", 
1898                   j, off, (long) (off + virtual_address), tbl[t]);
1899           
1900         }
1901       i += size;
1902     }
1903
1904   free (data);
1905
1906   return true;
1907 }
1908
1909 static boolean
1910 pe_print_private_bfd_data (abfd, vfile)
1911      bfd *abfd;
1912      PTR vfile;
1913 {
1914   FILE *file = (FILE *) vfile;
1915   int j;
1916   pe_data_type *pe = pe_data (abfd);
1917   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1918
1919   /* The MS dumpbin program reportedly ands with 0xff0f before
1920      printing the characteristics field.  Not sure why.  No reason to
1921      emulate it here.  */
1922   fprintf (file, "\nCharacteristics 0x%x\n", pe->real_flags);
1923 #undef PF
1924 #define PF(x, y)    if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
1925   PF (F_RELFLG, "relocations stripped");
1926   PF (F_EXEC, "executable");
1927   PF (F_LNNO, "line numbers stripped");
1928   PF (F_LSYMS, "symbols stripped");
1929   PF (0x80, "little endian");
1930   PF (F_AR32WR, "32 bit words");
1931   PF (0x200, "debugging information removed");
1932   PF (0x1000, "system file");
1933   PF (F_DLL, "DLL");
1934   PF (0x8000, "big endian");
1935 #undef PF
1936
1937   fprintf (file,"\nImageBase\t\t");
1938   fprintf_vma (file, i->ImageBase);
1939   fprintf (file,"\nSectionAlignment\t");
1940   fprintf_vma (file, i->SectionAlignment);
1941   fprintf (file,"\nFileAlignment\t\t");
1942   fprintf_vma (file, i->FileAlignment);
1943   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1944   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1945   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1946   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1947   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1948   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1949   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1950   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1951   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1952   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1953   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1954   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1955   fprintf (file,"SizeOfStackReserve\t");
1956   fprintf_vma (file, i->SizeOfStackReserve);
1957   fprintf (file,"\nSizeOfStackCommit\t");
1958   fprintf_vma (file, i->SizeOfStackCommit);
1959   fprintf (file,"\nSizeOfHeapReserve\t");
1960   fprintf_vma (file, i->SizeOfHeapReserve);
1961   fprintf (file,"\nSizeOfHeapCommit\t");
1962   fprintf_vma (file, i->SizeOfHeapCommit);
1963   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1964   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1965
1966   fprintf (file,"\nThe Data Directory\n");
1967   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) 
1968     {
1969       fprintf (file, "Entry %1x ", j);
1970       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1971       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1972       fprintf (file, "%s\n", dir_names[j]);
1973     }
1974
1975   pe_print_idata (abfd, vfile);
1976   pe_print_edata (abfd, vfile);
1977   pe_print_pdata (abfd, vfile);
1978   pe_print_reloc (abfd, vfile);
1979
1980   if (pe_saved_coff_bfd_print_private_bfd_data != NULL)
1981     {
1982       fputc ('\n', file);
1983   
1984       return pe_saved_bfd_print_private_bfd_data (abfd, vfile);
1985     }
1986
1987   return true;
1988 }
1989
1990 static boolean
1991 pe_mkobject (abfd)
1992      bfd * abfd;
1993 {
1994   pe_data_type *pe;
1995   abfd->tdata.pe_obj_data = 
1996     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1997
1998   if (abfd->tdata.pe_obj_data == 0)
1999     return false;
2000
2001   pe = pe_data (abfd);
2002
2003   pe->coff.pe = 1;
2004   pe->in_reloc_p = in_reloc_p;
2005   return true;
2006 }
2007
2008 /* Create the COFF backend specific information.  */
2009 static PTR
2010 pe_mkobject_hook (abfd, filehdr, aouthdr)
2011      bfd * abfd;
2012      PTR filehdr;
2013      PTR aouthdr;
2014 {
2015   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2016   pe_data_type *pe;
2017
2018   if (pe_mkobject (abfd) == false)
2019     return NULL;
2020
2021   pe = pe_data (abfd);
2022   pe->coff.sym_filepos = internal_f->f_symptr;
2023   /* These members communicate important constants about the symbol
2024      table to GDB's symbol-reading code.  These `constants'
2025      unfortunately vary among coff implementations...  */
2026   pe->coff.local_n_btmask = N_BTMASK;
2027   pe->coff.local_n_btshft = N_BTSHFT;
2028   pe->coff.local_n_tmask = N_TMASK;
2029   pe->coff.local_n_tshift = N_TSHIFT;
2030   pe->coff.local_symesz = SYMESZ;
2031   pe->coff.local_auxesz = AUXESZ;
2032   pe->coff.local_linesz = LINESZ;
2033
2034   obj_raw_syment_count (abfd) =
2035     obj_conv_table_size (abfd) =
2036       internal_f->f_nsyms;
2037
2038   pe->real_flags = internal_f->f_flags;
2039
2040   if ((internal_f->f_flags & F_DLL) != 0)
2041     pe->dll = 1;
2042
2043 #ifdef COFF_IMAGE_WITH_PE
2044   if (aouthdr) 
2045     pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
2046 #endif
2047
2048 #ifdef ARM 
2049   if (! coff_arm_bfd_set_private_flags (abfd, internal_f->f_flags))
2050     coff_data (abfd) ->flags = 0;
2051 #endif
2052   
2053   return (PTR) pe;
2054 }
2055
2056
2057
2058 /* Copy any private info we understand from the input bfd
2059    to the output bfd.  */
2060
2061 #ifdef  coff_bfd_copy_private_bfd_data
2062 static  boolean (* pe_saved_coff_bfd_copy_private_bfd_data)(bfd *, bfd *) = coff_bfd_copy_private_bfd_data;
2063 #undef  coff_bfd_copy_private_bfd_data
2064 #else
2065 static  boolean (* pe_saved_coff_bfd_copy_private_bfd_data)(bfd *, bfd *) = NULL;
2066 #endif
2067 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
2068
2069 static boolean
2070 pe_bfd_copy_private_bfd_data (ibfd, obfd)
2071      bfd *ibfd, *obfd;
2072 {
2073   /* One day we may try to grok other private data.  */
2074   if (ibfd->xvec->flavour != bfd_target_coff_flavour
2075       || obfd->xvec->flavour != bfd_target_coff_flavour)
2076     return true;
2077
2078   pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
2079   pe_data (obfd)->dll = pe_data (ibfd)->dll;
2080
2081   if (pe_saved_coff_bfd_copy_private_bfd_data)
2082     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
2083   
2084   return true;
2085 }
2086
2087 #ifdef COFF_IMAGE_WITH_PE
2088
2089 /* Copy private section data.  */
2090
2091 #define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
2092
2093 static boolean pe_bfd_copy_private_section_data
2094   PARAMS ((bfd *, asection *, bfd *, asection *));
2095
2096 static boolean
2097 pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
2098      bfd *ibfd;
2099      asection *isec;
2100      bfd *obfd;
2101      asection *osec;
2102 {
2103   if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
2104       || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
2105     return true;
2106
2107   if (coff_section_data (ibfd, isec) != NULL
2108       && pei_section_data (ibfd, isec) != NULL)
2109     {
2110       if (coff_section_data (obfd, osec) == NULL)
2111         {
2112           osec->used_by_bfd =
2113             (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
2114           if (osec->used_by_bfd == NULL)
2115             return false;
2116         }
2117       if (pei_section_data (obfd, osec) == NULL)
2118         {
2119           coff_section_data (obfd, osec)->tdata =
2120             (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
2121           if (coff_section_data (obfd, osec)->tdata == NULL)
2122             return false;
2123         }
2124       pei_section_data (obfd, osec)->virt_size =
2125         pei_section_data (ibfd, isec)->virt_size;
2126     }
2127
2128   return true;
2129 }
2130
2131 #endif