OSDN Git Service

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