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