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