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