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