1999-09-11 Donn Terry <donn@interix.com>
[external/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
1147   /* If this section holds uninitialized data, use the virtual size
1148      (stored in s_paddr) instead of the physical size.  */
1149   if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
1150     {
1151       scnhdr_int->s_size = scnhdr_int->s_paddr;
1152       /* This code used to set scnhdr_int->s_paddr to 0.  However,
1153          coff_set_alignment_hook stores s_paddr in virt_size, which
1154          only works if it correctly holds the virtual size of the
1155          section.  */
1156     }
1157 }
1158
1159 static unsigned int
1160 coff_swap_scnhdr_out (abfd, in, out)
1161      bfd       *abfd;
1162      PTR        in;
1163      PTR        out;
1164 {
1165   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
1166   SCNHDR *scnhdr_ext = (SCNHDR *)out;
1167   unsigned int ret = SCNHSZ;
1168   bfd_vma ps;
1169   bfd_vma ss;
1170
1171   memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
1172
1173   PUT_SCNHDR_VADDR (abfd, 
1174                     ((scnhdr_int->s_vaddr 
1175                       - pe_data(abfd)->pe_opthdr.ImageBase)
1176                      & 0xffffffff),
1177                     (bfd_byte *) scnhdr_ext->s_vaddr);
1178
1179   /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1180      value except for the BSS section, its s_size should be 0 */
1181
1182
1183   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
1184     {
1185       ps = scnhdr_int->s_size;
1186       ss = 0;
1187     }
1188   else
1189     {
1190       ps = scnhdr_int->s_paddr;
1191       ss = scnhdr_int->s_size;
1192     }
1193
1194   PUT_SCNHDR_SIZE (abfd, ss,
1195                    (bfd_byte *) scnhdr_ext->s_size);
1196
1197
1198   PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
1199
1200   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
1201                      (bfd_byte *) scnhdr_ext->s_scnptr);
1202   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
1203                      (bfd_byte *) scnhdr_ext->s_relptr);
1204   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
1205                       (bfd_byte *) scnhdr_ext->s_lnnoptr);
1206
1207   /* Extra flags must be set when dealing with NT.  All sections should also
1208      have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
1209      .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1210      sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1211      (this is especially important when dealing with the .idata section since
1212      the addresses for routines from .dlls must be overwritten).  If .reloc
1213      section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1214      (0x02000000).  Also, the resource data should also be read and
1215      writable.  */
1216
1217   /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1218   /* FIXME: even worse, I don't see how to get the original alignment field*/
1219   /*        back...                                                        */
1220
1221   /* FIXME: Basing this on section names is bogus.  Also, this should
1222      be in sec_to_styp_flags.  */
1223
1224   {
1225     int flags = scnhdr_int->s_flags;
1226     if (strcmp (scnhdr_int->s_name, ".data")  == 0 ||
1227         strcmp (scnhdr_int->s_name, ".CRT")   == 0 ||
1228         strcmp (scnhdr_int->s_name, ".bss")   == 0)
1229       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1230     else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1231       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1232     else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1233       flags = (SEC_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
1234                | IMAGE_SCN_MEM_SHARED);
1235     else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1236       flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;     
1237     else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1238              || strcmp (scnhdr_int->s_name, ".edata") == 0)
1239       flags =  IMAGE_SCN_MEM_READ | SEC_DATA;     
1240     else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1241       flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1242                           IMAGE_SCN_MEM_READ ;
1243     /* Remember this field is a max of 8 chars, so the null is _not_ there
1244        for an 8 character name like ".reldata". (yep. Stupid bug) */
1245     else if (strncmp (scnhdr_int->s_name, ".reldata", 8) == 0)
1246       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1247                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1248     else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1249       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1250                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1251     else if (strncmp (scnhdr_int->s_name, ".drectve", 8) == 0)
1252       flags =  IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1253     else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0)
1254       flags |= (IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE
1255                 | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ);
1256     else if (strcmp (scnhdr_int->s_name, ".rsrc")  == 0)
1257       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED;
1258     else
1259       {
1260         flags |= IMAGE_SCN_MEM_READ;
1261         if (! (flags & SEC_READONLY))
1262           flags |= IMAGE_SCN_MEM_WRITE;
1263         if (flags & SEC_SHARED)
1264           flags |= IMAGE_SCN_MEM_SHARED;
1265       }
1266
1267     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1268   }
1269
1270   if (scnhdr_int->s_nlnno <= 0xffff)
1271     bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1272   else
1273     {
1274       (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
1275                              bfd_get_filename (abfd),
1276                              scnhdr_int->s_nlnno);
1277       bfd_set_error (bfd_error_file_truncated);
1278       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1279       ret = 0;
1280     }
1281   if (scnhdr_int->s_nreloc <= 0xffff)
1282     bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1283   else
1284     {
1285       (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
1286                              bfd_get_filename (abfd),
1287                              scnhdr_int->s_nreloc);
1288       bfd_set_error (bfd_error_file_truncated);
1289       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1290       ret = 0;
1291     }
1292   return ret;
1293 }
1294
1295 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = 
1296 {
1297   N_ ("Export Directory [.edata (or where ever we found it)]"),
1298   N_ ("Import Directory [parts of .idata]"),
1299   N_ ("Resource Directory [.rsrc]"),
1300   N_ ("Exception Directory [.pdata]"),
1301   N_ ("Security Directory"),
1302   N_ ("Base Relocation Directory [.reloc]"),
1303   N_ ("Debug Directory"),
1304   N_ ("Description Directory"),
1305   N_ ("Special Directory"),
1306   N_ ("Thread Storage Directory [.tls]"),
1307   N_ ("Load Configuration Directory"),
1308   N_ ("Bound Import Directory"),
1309   N_ ("Import Address Table Directory"),
1310   N_ ("Reserved"),
1311   N_ ("Reserved"),
1312   N_ ("Reserved")
1313 };
1314
1315 /**********************************************************************/
1316 static boolean
1317 pe_print_idata(abfd, vfile)
1318      bfd *abfd;
1319      PTR vfile;
1320 {
1321   FILE *file = (FILE *) vfile;
1322   bfd_byte *data = 0;
1323   asection *section = bfd_get_section_by_name (abfd, ".idata");
1324   unsigned long adj;
1325
1326 #ifdef POWERPC_LE_PE
1327   asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1328 #endif
1329
1330   bfd_size_type datasize;
1331   bfd_size_type dataoff;
1332   bfd_size_type secsize;
1333   bfd_size_type i;
1334   bfd_size_type start, stop;
1335   int onaline = 20;
1336
1337   pe_data_type *pe = pe_data (abfd);
1338   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1339
1340   if (section != NULL)
1341     {
1342       datasize = bfd_section_size (abfd, section);
1343       dataoff = 0;
1344
1345       if (datasize == 0)
1346         return true;
1347     }
1348   else
1349     {
1350       bfd_vma addr, size;
1351
1352       addr = extra->DataDirectory[1].VirtualAddress;
1353       size = extra->DataDirectory[1].Size;
1354
1355       if (addr == 0 || size == 0)
1356         return true;
1357
1358       for (section = abfd->sections; section != NULL; section = section->next)
1359         {
1360           if (section->vma - extra->ImageBase <= addr
1361               && ((section->vma - extra->ImageBase
1362                    + bfd_section_size (abfd, section))
1363                   >= addr + size))
1364             break;
1365         }
1366       if (section == NULL)
1367         return true;
1368
1369       /* For some reason the import table size is not reliable.  The
1370          import data will extend past the indicated size, and before
1371          the indicated address.  */
1372       dataoff = addr - (section->vma - extra->ImageBase);
1373       datasize = size;
1374     }
1375
1376 #ifdef POWERPC_LE_PE
1377   if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1378     {
1379       /* The toc address can be found by taking the starting address,
1380          which on the PPC locates a function descriptor. The descriptor
1381          consists of the function code starting address followed by the
1382          address of the toc. The starting address we get from the bfd,
1383          and the descriptor is supposed to be in the .reldata section. 
1384       */
1385
1386       bfd_vma loadable_toc_address;
1387       bfd_vma toc_address;
1388       bfd_vma start_address;
1389       bfd_byte *data = 0;
1390       int offset;
1391       data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, 
1392                                                                  rel_section));
1393       if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1394         return false;
1395
1396       datasize = bfd_section_size (abfd, rel_section);
1397   
1398       bfd_get_section_contents (abfd, 
1399                                 rel_section, 
1400                                 (PTR) data, 0, 
1401                                 bfd_section_size (abfd, rel_section));
1402
1403       offset = abfd->start_address - rel_section->vma;
1404
1405       start_address = bfd_get_32(abfd, data+offset);
1406       loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1407       toc_address = loadable_toc_address - 32768;
1408
1409       fprintf(file,
1410               _("\nFunction descriptor located at the start address: %04lx\n"),
1411               (unsigned long int) (abfd->start_address));
1412       fprintf (file,
1413                _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"), 
1414                start_address, loadable_toc_address, toc_address);
1415     }
1416   else 
1417     {
1418       fprintf(file,
1419               _("\nNo reldata section! Function descriptor not decoded.\n"));
1420     }
1421 #endif
1422
1423   fprintf(file,
1424           _("\nThe Import Tables (interpreted .idata section contents)\n"));
1425   fprintf(file,
1426           _(" vma:            Hint    Time      Forward  DLL       First\n"));
1427   fprintf(file,
1428           _("                 Table   Stamp     Chain    Name      Thunk\n"));
1429
1430   secsize = bfd_section_size (abfd, section);
1431   data = (bfd_byte *) bfd_malloc (secsize);
1432   if (data == NULL && secsize != 0)
1433     return false;
1434
1435   if (! bfd_get_section_contents (abfd, section, (PTR) data, 0, secsize))
1436     return false;
1437
1438   adj = (extra->ImageBase - section->vma) & 0xffffffff;
1439
1440   start = dataoff;
1441   stop = dataoff + datasize;
1442   for (i = start; i < stop; i += onaline)
1443     {
1444       bfd_vma hint_addr;
1445       bfd_vma time_stamp;
1446       bfd_vma forward_chain;
1447       bfd_vma dll_name;
1448       bfd_vma first_thunk;
1449       int idx = 0;
1450       bfd_size_type j;
1451       char *dll;
1452
1453       fprintf (file,
1454                " %08lx\t", 
1455                (unsigned long int) (i + section->vma + dataoff));
1456       
1457       if (i+20 > stop)
1458         {
1459           /* check stuff */
1460           ;
1461         }
1462       
1463       hint_addr = bfd_get_32(abfd, data+i);
1464       time_stamp = bfd_get_32(abfd, data+i+4);
1465       forward_chain = bfd_get_32(abfd, data+i+8);
1466       dll_name = bfd_get_32(abfd, data+i+12);
1467       first_thunk = bfd_get_32(abfd, data+i+16);
1468       
1469       fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1470               hint_addr,
1471               time_stamp,
1472               forward_chain,
1473               dll_name,
1474               first_thunk);
1475
1476       if (hint_addr == 0 && first_thunk == 0)
1477         break;
1478
1479       /* the image base is present in the section->vma */
1480       dll = (char *) data + dll_name + adj;
1481       fprintf(file, _("\n\tDLL Name: %s\n"), dll);
1482
1483       if (hint_addr != 0)
1484         {
1485           fprintf (file, _("\tvma:  Hint/Ord Member-Name\n"));
1486
1487           idx = hint_addr + adj;
1488
1489           for (j = 0; j < stop; j += 4)
1490             {
1491               unsigned long member = bfd_get_32 (abfd, data + idx + j);
1492
1493               if (member == 0)
1494                 break;
1495               if (member & 0x80000000)
1496                 fprintf (file, "\t%04lx\t %4lu", member,
1497                          member & 0x7fffffff);
1498               else
1499                 {
1500                   int ordinal;
1501                   char *member_name;
1502
1503                   ordinal = bfd_get_16 (abfd, data + member + adj);
1504                   member_name = (char *) data + member + adj + 2;
1505                   fprintf (file, "\t%04lx\t %4d  %s",
1506                            member, ordinal, member_name);
1507                 }
1508
1509               /* If the time stamp is not zero, the import address
1510                  table holds actual addresses.  */
1511               if (time_stamp != 0
1512                   && first_thunk != 0
1513                   && first_thunk != hint_addr)
1514                 fprintf (file, "\t%04lx",
1515                          bfd_get_32 (abfd, data + first_thunk + adj + j));
1516
1517               fprintf (file, "\n");
1518             }
1519         }
1520
1521       if (hint_addr != first_thunk && time_stamp == 0)
1522         {
1523           int differ = 0;
1524           int idx2;
1525
1526           idx2 = first_thunk + adj;
1527
1528           for (j=0;j<stop;j+=4)
1529             {
1530               int ordinal;
1531               char *member_name;
1532               bfd_vma hint_member = 0;
1533               bfd_vma iat_member;
1534
1535               if (hint_addr != 0)
1536                 hint_member = bfd_get_32 (abfd, data + idx + j);
1537               iat_member = bfd_get_32 (abfd, data + idx2 + j);
1538
1539               if (hint_addr == 0 && iat_member == 0)
1540                 break;
1541
1542               if (hint_addr == 0 || hint_member != iat_member)
1543                 {
1544                   if (differ == 0)
1545                     {
1546                       fprintf (file, 
1547                                _("\tThe Import Address Table (difference found)\n"));
1548                       fprintf(file, _("\tvma:  Hint/Ord Member-Name\n"));
1549                       differ = 1;
1550                     }
1551                   if (iat_member == 0)
1552                     {
1553                       fprintf(file,
1554                               _("\t>>> Ran out of IAT members!\n"));
1555                     }
1556                   else 
1557                     {
1558                       ordinal = bfd_get_16(abfd,
1559                                            data + iat_member + adj);
1560                       member_name = (char *) data + iat_member + adj + 2;
1561                       fprintf(file, "\t%04lx\t %4d  %s\n",
1562                               iat_member, ordinal, member_name);
1563                     }
1564                 }
1565
1566               if (hint_addr != 0 && hint_member == 0)
1567                 break;
1568             }
1569           if (differ == 0)
1570             {
1571               fprintf(file,
1572                       _("\tThe Import Address Table is identical\n"));
1573             }
1574         }
1575
1576       fprintf(file, "\n");
1577
1578     }
1579
1580   free (data);
1581
1582   return true;
1583 }
1584
1585 static boolean
1586 pe_print_edata (abfd, vfile)
1587      bfd *abfd;
1588      PTR vfile;
1589 {
1590   FILE *file = (FILE *) vfile;
1591   bfd_byte *data = 0;
1592   asection *section = bfd_get_section_by_name (abfd, ".edata");
1593
1594   bfd_size_type datasize;
1595   bfd_size_type dataoff;
1596   bfd_size_type i;
1597
1598   int adj;
1599   struct EDT_type 
1600     {
1601       long export_flags;             /* reserved - should be zero */
1602       long time_stamp;
1603       short major_ver;
1604       short minor_ver;
1605       bfd_vma name;                  /* rva - relative to image base */
1606       long base;                     /* ordinal base */
1607       unsigned long num_functions;   /* Number in the export address table */
1608       unsigned long num_names;       /* Number in the name pointer table */
1609       bfd_vma eat_addr;    /* rva to the export address table */
1610       bfd_vma npt_addr;        /* rva to the Export Name Pointer Table */
1611       bfd_vma ot_addr; /* rva to the Ordinal Table */
1612     } edt;
1613
1614   pe_data_type *pe = pe_data (abfd);
1615   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1616
1617   if (section != NULL)
1618     {
1619       datasize = bfd_section_size (abfd, section);
1620       dataoff = 0;
1621     }
1622   else
1623     {
1624       bfd_vma addr, size;
1625
1626       addr = extra->DataDirectory[0].VirtualAddress;
1627       size = extra->DataDirectory[0].Size;
1628
1629       if (addr == 0 || size == 0)
1630         return true;
1631
1632       for (section = abfd->sections; section != NULL; section = section->next)
1633         {
1634           if (section->vma - extra->ImageBase <= addr
1635               && ((section->vma - extra->ImageBase
1636                    + bfd_section_size (abfd, section))
1637                   >= addr + size))
1638             break;
1639         }
1640       if (section == NULL)
1641         return true;
1642
1643       datasize = size;
1644       dataoff = addr - (section->vma - extra->ImageBase);
1645     }
1646
1647   data = (bfd_byte *) bfd_malloc (datasize);
1648   if (data == NULL && datasize != 0)
1649     return false;
1650
1651   if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff,
1652                                   datasize))
1653     return false;
1654
1655   /* Go get Export Directory Table */
1656   edt.export_flags   = bfd_get_32(abfd, data+0); 
1657   edt.time_stamp     = bfd_get_32(abfd, data+4);
1658   edt.major_ver      = bfd_get_16(abfd, data+8);
1659   edt.minor_ver      = bfd_get_16(abfd, data+10);
1660   edt.name           = bfd_get_32(abfd, data+12);
1661   edt.base           = bfd_get_32(abfd, data+16);
1662   edt.num_functions  = bfd_get_32(abfd, data+20); 
1663   edt.num_names      = bfd_get_32(abfd, data+24); 
1664   edt.eat_addr       = bfd_get_32(abfd, data+28);
1665   edt.npt_addr       = bfd_get_32(abfd, data+32); 
1666   edt.ot_addr        = bfd_get_32(abfd, data+36);
1667
1668   adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff;
1669
1670
1671   /* Dump the EDT first first */
1672   fprintf(file,
1673           _("\nThe Export Tables (interpreted .edata section contents)\n\n"));
1674
1675   fprintf(file,
1676           _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
1677
1678   fprintf(file,
1679           _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
1680
1681   fprintf(file,
1682           _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
1683
1684   fprintf (file,
1685            _("Name \t\t\t\t"));
1686   fprintf_vma (file, edt.name);
1687   fprintf (file,
1688            " %s\n", data + edt.name + adj);
1689
1690   fprintf(file,
1691           _("Ordinal Base \t\t\t%ld\n"), edt.base);
1692
1693   fprintf(file,
1694           _("Number in:\n"));
1695
1696   fprintf(file,
1697           _("\tExport Address Table \t\t%lx\n"),
1698           edt.num_functions);
1699
1700   fprintf(file,
1701           _("\t[Name Pointer/Ordinal] Table\t%lu\n"), edt.num_names);
1702
1703   fprintf(file,
1704           _("Table Addresses\n"));
1705
1706   fprintf (file,
1707            _("\tExport Address Table \t\t"));
1708   fprintf_vma (file, edt.eat_addr);
1709   fprintf (file, "\n");
1710
1711   fprintf (file,
1712           _("\tName Pointer Table \t\t"));
1713   fprintf_vma (file, edt.npt_addr);
1714   fprintf (file, "\n");
1715
1716   fprintf (file,
1717            _("\tOrdinal Table \t\t\t"));
1718   fprintf_vma (file, edt.ot_addr);
1719   fprintf (file, "\n");
1720
1721   
1722   /* The next table to find si the Export Address Table. It's basically
1723      a list of pointers that either locate a function in this dll, or
1724      forward the call to another dll. Something like:
1725       typedef union 
1726       {
1727         long export_rva;
1728         long forwarder_rva;
1729       } export_address_table_entry;
1730   */
1731
1732   fprintf(file,
1733           _("\nExport Address Table -- Ordinal Base %ld\n"),
1734           edt.base);
1735
1736   for (i = 0; i < edt.num_functions; ++i)
1737     {
1738       bfd_vma eat_member = bfd_get_32 (abfd, 
1739                                        data + edt.eat_addr + (i * 4) + adj);
1740       bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff;
1741       bfd_vma edata_start = bfd_get_section_vma (abfd,section) + dataoff;
1742       bfd_vma edata_end = edata_start + datasize;
1743
1744       if (eat_member == 0)
1745         continue;
1746
1747       if (edata_start < eat_actual && eat_actual < edata_end) 
1748         {
1749           /* this rva is to a name (forwarding function) in our section */
1750           /* Should locate a function descriptor */
1751           fprintf(file,
1752                   "\t[%4ld] +base[%4ld] %04lx %s -- %s\n", 
1753                   (long) i, (long) (i + edt.base), eat_member,
1754                   "Forwarder RVA", data + eat_member + adj);
1755         }
1756       else
1757         {
1758           /* Should locate a function descriptor in the reldata section */
1759           fprintf(file,
1760                   "\t[%4ld] +base[%4ld] %04lx %s\n", 
1761                   (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1762         }
1763     }
1764
1765   /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1766   /* Dump them in parallel for clarity */
1767   fprintf(file,
1768           _("\n[Ordinal/Name Pointer] Table\n"));
1769
1770   for (i = 0; i < edt.num_names; ++i)
1771     {
1772       bfd_vma name_ptr = bfd_get_32(abfd, 
1773                                     data + 
1774                                     edt.npt_addr
1775                                     + (i*4) + adj);
1776       
1777       char *name = (char *) data + name_ptr + adj;
1778
1779       bfd_vma ord = bfd_get_16(abfd, 
1780                                     data + 
1781                                     edt.ot_addr
1782                                     + (i*2) + adj);
1783       fprintf(file,
1784               "\t[%4ld] %s\n", (long) ord, name);
1785
1786     }
1787
1788   free (data);
1789
1790   return true;
1791 }
1792
1793 static boolean
1794 pe_print_pdata (abfd, vfile)
1795      bfd  *abfd;
1796      PTR vfile;
1797 {
1798   FILE *file = (FILE *) vfile;
1799   bfd_byte *data = 0;
1800   asection *section = bfd_get_section_by_name (abfd, ".pdata");
1801   bfd_size_type datasize = 0;
1802   bfd_size_type i;
1803   bfd_size_type start, stop;
1804   int onaline = 20;
1805
1806   if (section == 0)
1807     return true;
1808
1809   stop = bfd_section_size (abfd, section);
1810   if ((stop % onaline) != 0)
1811     fprintf (file, _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
1812              (long)stop, onaline);
1813
1814   fprintf(file,
1815           _("\nThe Function Table (interpreted .pdata section contents)\n"));
1816   fprintf(file,
1817           _(" vma:\t\tBegin    End      EH       EH       PrologEnd\n"));
1818   fprintf(file,
1819           _("     \t\tAddress  Address  Handler  Data     Address\n"));
1820
1821   if (bfd_section_size (abfd, section) == 0)
1822     return true;
1823
1824   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1825   datasize = bfd_section_size (abfd, section);
1826   if (data == NULL && datasize != 0)
1827     return false;
1828
1829   bfd_get_section_contents (abfd, 
1830                             section, 
1831                             (PTR) data, 0, 
1832                             bfd_section_size (abfd, section));
1833
1834   start = 0;
1835
1836   for (i = start; i < stop; i += onaline)
1837     {
1838       bfd_vma begin_addr;
1839       bfd_vma end_addr;
1840       bfd_vma eh_handler;
1841       bfd_vma eh_data;
1842       bfd_vma prolog_end_addr;
1843
1844       if (i+20 > stop)
1845           break;
1846       
1847       begin_addr = bfd_get_32(abfd, data+i);
1848       end_addr = bfd_get_32(abfd, data+i+4);
1849       eh_handler = bfd_get_32(abfd, data+i+8);
1850       eh_data = bfd_get_32(abfd, data+i+12);
1851       prolog_end_addr = bfd_get_32(abfd, data+i+16);
1852       
1853       if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1854           && eh_data == 0 && prolog_end_addr == 0)
1855         {
1856           /* We are probably into the padding of the
1857              section now */
1858           break;
1859         }
1860
1861       fprintf (file,
1862                " %08lx\t", 
1863                (unsigned long int) (i + section->vma));
1864
1865       fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1866               begin_addr,
1867               end_addr,
1868               eh_handler,
1869               eh_data,
1870               prolog_end_addr);
1871
1872 #ifdef POWERPC_LE_PE
1873       if (eh_handler == 0 && eh_data != 0)
1874         {
1875           /* Special bits here, although the meaning may */
1876           /* be a little mysterious. The only one I know */
1877           /* for sure is 0x03.                           */
1878           /* Code Significance                           */
1879           /* 0x00 None                                   */
1880           /* 0x01 Register Save Millicode                */
1881           /* 0x02 Register Restore Millicode             */
1882           /* 0x03 Glue Code Sequence                     */
1883           switch (eh_data)
1884             {
1885             case 0x01:
1886               fprintf(file, _(" Register save millicode"));
1887               break;
1888             case 0x02:
1889               fprintf(file, _(" Register restore millicode"));
1890               break;
1891             case 0x03:
1892               fprintf(file, _(" Glue code sequence"));
1893               break;
1894             default:
1895               break;
1896             }
1897         }
1898 #endif     
1899       fprintf(file, "\n");
1900     }
1901
1902   free (data);
1903
1904   return true;
1905 }
1906
1907 static const char *tbl[6] =
1908 {
1909 "ABSOLUTE",
1910 "HIGH",
1911 "LOW",
1912 "HIGHLOW",
1913 "HIGHADJ",
1914 "MIPS_JMPADDR"
1915 };
1916
1917 static boolean
1918 pe_print_reloc (abfd, vfile)
1919      bfd *abfd;
1920      PTR vfile;
1921 {
1922   FILE *file = (FILE *) vfile;
1923   bfd_byte *data = 0;
1924   asection *section = bfd_get_section_by_name (abfd, ".reloc");
1925   bfd_size_type datasize = 0;
1926   bfd_size_type i;
1927   bfd_size_type start, stop;
1928
1929   if (section == 0)
1930     return true;
1931
1932   if (bfd_section_size (abfd, section) == 0)
1933     return true;
1934
1935   fprintf(file,
1936           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
1937
1938   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1939   datasize = bfd_section_size (abfd, section);
1940   if (data == NULL && datasize != 0)
1941     return false;
1942
1943   bfd_get_section_contents (abfd, 
1944                             section, 
1945                             (PTR) data, 0, 
1946                             bfd_section_size (abfd, section));
1947
1948   start = 0;
1949
1950   stop = bfd_section_size (abfd, section);
1951
1952   for (i = start; i < stop;)
1953     {
1954       int j;
1955       bfd_vma virtual_address;
1956       long number, size;
1957
1958       /* The .reloc section is a sequence of blocks, with a header consisting
1959          of two 32 bit quantities, followed by a number of 16 bit entries */
1960
1961       virtual_address = bfd_get_32(abfd, data+i);
1962       size = bfd_get_32(abfd, data+i+4);
1963       number = (size - 8) / 2;
1964
1965       if (size == 0) 
1966         {
1967           break;
1968         }
1969
1970       fprintf (file,
1971                _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
1972                virtual_address, size, size, number);
1973
1974       for (j = 0; j < number; ++j)
1975         {
1976           unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1977           int t =   (e & 0xF000) >> 12;
1978           int off = e & 0x0FFF;
1979
1980           if (t > 5) 
1981             abort();
1982
1983           fprintf(file,
1984                   _("\treloc %4d offset %4x [%4lx] %s\n"), 
1985                   j, off, (long) (off + virtual_address), tbl[t]);
1986           
1987         }
1988       i += size;
1989     }
1990
1991   free (data);
1992
1993   return true;
1994 }
1995
1996 static boolean
1997 pe_print_private_bfd_data (abfd, vfile)
1998      bfd *abfd;
1999      PTR vfile;
2000 {
2001   FILE *file = (FILE *) vfile;
2002   int j;
2003   pe_data_type *pe = pe_data (abfd);
2004   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
2005
2006   /* The MS dumpbin program reportedly ands with 0xff0f before
2007      printing the characteristics field.  Not sure why.  No reason to
2008      emulate it here.  */
2009   fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
2010 #undef PF
2011 #define PF(x, y)    if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
2012   PF (F_RELFLG, "relocations stripped");
2013   PF (F_EXEC, "executable");
2014   PF (F_LNNO, "line numbers stripped");
2015   PF (F_LSYMS, "symbols stripped");
2016   PF (0x80, "little endian");
2017   PF (F_AR32WR, "32 bit words");
2018   PF (0x200, "debugging information removed");
2019   PF (0x1000, "system file");
2020   PF (F_DLL, "DLL");
2021   PF (0x8000, "big endian");
2022 #undef PF
2023
2024   fprintf (file,"\nImageBase\t\t");
2025   fprintf_vma (file, i->ImageBase);
2026   fprintf (file,"\nSectionAlignment\t");
2027   fprintf_vma (file, i->SectionAlignment);
2028   fprintf (file,"\nFileAlignment\t\t");
2029   fprintf_vma (file, i->FileAlignment);
2030   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
2031   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
2032   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
2033   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
2034   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
2035   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
2036   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
2037   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
2038   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
2039   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
2040   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
2041   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
2042   fprintf (file,"SizeOfStackReserve\t");
2043   fprintf_vma (file, i->SizeOfStackReserve);
2044   fprintf (file,"\nSizeOfStackCommit\t");
2045   fprintf_vma (file, i->SizeOfStackCommit);
2046   fprintf (file,"\nSizeOfHeapReserve\t");
2047   fprintf_vma (file, i->SizeOfHeapReserve);
2048   fprintf (file,"\nSizeOfHeapCommit\t");
2049   fprintf_vma (file, i->SizeOfHeapCommit);
2050   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
2051   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
2052
2053   fprintf (file,"\nThe Data Directory\n");
2054   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) 
2055     {
2056       fprintf (file, "Entry %1x ", j);
2057       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
2058       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
2059       fprintf (file, "%s\n", dir_names[j]);
2060     }
2061
2062   pe_print_idata (abfd, vfile);
2063   pe_print_edata (abfd, vfile);
2064   pe_print_pdata (abfd, vfile);
2065   pe_print_reloc (abfd, vfile);
2066
2067   if (pe_saved_coff_bfd_print_private_bfd_data != NULL)
2068     {
2069       fputc ('\n', file);
2070   
2071       return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
2072     }
2073
2074   return true;
2075 }
2076
2077 static boolean
2078 pe_mkobject (abfd)
2079      bfd * abfd;
2080 {
2081   pe_data_type *pe;
2082   abfd->tdata.pe_obj_data = 
2083     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
2084
2085   if (abfd->tdata.pe_obj_data == 0)
2086     return false;
2087
2088   pe = pe_data (abfd);
2089
2090   pe->coff.pe = 1;
2091   pe->in_reloc_p = in_reloc_p;
2092   return true;
2093 }
2094
2095 /* Create the COFF backend specific information.  */
2096 static PTR
2097 pe_mkobject_hook (abfd, filehdr, aouthdr)
2098      bfd * abfd;
2099      PTR filehdr;
2100      PTR aouthdr ATTRIBUTE_UNUSED;
2101 {
2102   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
2103   pe_data_type *pe;
2104
2105   if (pe_mkobject (abfd) == false)
2106     return NULL;
2107
2108   pe = pe_data (abfd);
2109   pe->coff.sym_filepos = internal_f->f_symptr;
2110   /* These members communicate important constants about the symbol
2111      table to GDB's symbol-reading code.  These `constants'
2112      unfortunately vary among coff implementations...  */
2113   pe->coff.local_n_btmask = N_BTMASK;
2114   pe->coff.local_n_btshft = N_BTSHFT;
2115   pe->coff.local_n_tmask = N_TMASK;
2116   pe->coff.local_n_tshift = N_TSHIFT;
2117   pe->coff.local_symesz = SYMESZ;
2118   pe->coff.local_auxesz = AUXESZ;
2119   pe->coff.local_linesz = LINESZ;
2120
2121   pe->coff.timestamp = internal_f->f_timdat;
2122
2123   obj_raw_syment_count (abfd) =
2124     obj_conv_table_size (abfd) =
2125       internal_f->f_nsyms;
2126
2127   pe->real_flags = internal_f->f_flags;
2128
2129   if ((internal_f->f_flags & F_DLL) != 0)
2130     pe->dll = 1;
2131
2132   if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
2133     abfd->flags |= HAS_DEBUG;
2134
2135 #ifdef COFF_IMAGE_WITH_PE
2136   if (aouthdr) 
2137     pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
2138 #endif
2139
2140 #ifdef ARM 
2141   if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
2142     coff_data (abfd) ->flags = 0;
2143 #endif
2144   
2145   return (PTR) pe;
2146 }
2147
2148
2149
2150 /* Copy any private info we understand from the input bfd
2151    to the output bfd.  */
2152
2153 #ifdef coff_bfd_copy_private_bfd_data
2154 static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
2155      PARAMS ((bfd *, bfd *))
2156      = coff_bfd_copy_private_bfd_data;
2157 #undef coff_bfd_copy_private_bfd_data
2158 #else
2159 static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
2160      PARAMS ((bfd *, bfd *))
2161      = NULL;
2162 #endif
2163 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
2164
2165 static boolean
2166 pe_bfd_copy_private_bfd_data (ibfd, obfd)
2167      bfd *ibfd, *obfd;
2168 {
2169   /* One day we may try to grok other private data.  */
2170   if (ibfd->xvec->flavour != bfd_target_coff_flavour
2171       || obfd->xvec->flavour != bfd_target_coff_flavour)
2172     return true;
2173
2174   pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
2175   pe_data (obfd)->dll = pe_data (ibfd)->dll;
2176
2177   if (pe_saved_coff_bfd_copy_private_bfd_data)
2178     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
2179   
2180   return true;
2181 }
2182
2183 #ifdef COFF_IMAGE_WITH_PE
2184
2185 /* Copy private section data.  */
2186
2187 #define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
2188
2189 static boolean pe_bfd_copy_private_section_data
2190   PARAMS ((bfd *, asection *, bfd *, asection *));
2191
2192 static boolean
2193 pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
2194      bfd *ibfd;
2195      asection *isec;
2196      bfd *obfd;
2197      asection *osec;
2198 {
2199   if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
2200       || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
2201     return true;
2202
2203   if (coff_section_data (ibfd, isec) != NULL
2204       && pei_section_data (ibfd, isec) != NULL)
2205     {
2206       if (coff_section_data (obfd, osec) == NULL)
2207         {
2208           osec->used_by_bfd =
2209             (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
2210           if (osec->used_by_bfd == NULL)
2211             return false;
2212         }
2213       if (pei_section_data (obfd, osec) == NULL)
2214         {
2215           coff_section_data (obfd, osec)->tdata =
2216             (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
2217           if (coff_section_data (obfd, osec)->tdata == NULL)
2218             return false;
2219         }
2220       pei_section_data (obfd, osec)->virt_size =
2221         pei_section_data (ibfd, isec)->virt_size;
2222     }
2223
2224   return true;
2225 }
2226
2227 #endif