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