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