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