* peicode.h (pe_print_idata): Call malloc rather than xmalloc.
[external/binutils.git] / bfd / peicode.h
1 /* Support for the generic parts of most COFF variants, for BFD.
2    Copyright 1995 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
27
28 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
29 #define coff_mkobject pe_mkobject
30 #define coff_mkobject_hook pe_mkobject_hook
31
32 #ifndef GET_FCN_LNNOPTR
33 #define GET_FCN_LNNOPTR(abfd, ext) \
34      bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
35 #endif
36
37 #ifndef GET_FCN_ENDNDX
38 #define GET_FCN_ENDNDX(abfd, ext)  \
39         bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
40 #endif
41
42 #ifndef PUT_FCN_LNNOPTR
43 #define PUT_FCN_LNNOPTR(abfd, in, ext)  bfd_h_put_32(abfd,  in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
44 #endif
45 #ifndef PUT_FCN_ENDNDX
46 #define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
47 #endif
48 #ifndef GET_LNSZ_LNNO
49 #define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
50 #endif
51 #ifndef GET_LNSZ_SIZE
52 #define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
53 #endif
54 #ifndef PUT_LNSZ_LNNO
55 #define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno)
56 #endif
57 #ifndef PUT_LNSZ_SIZE
58 #define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
59 #endif
60 #ifndef GET_SCN_SCNLEN
61 #define GET_SCN_SCNLEN(abfd,  ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
62 #endif
63 #ifndef GET_SCN_NRELOC
64 #define GET_SCN_NRELOC(abfd,  ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
65 #endif
66 #ifndef GET_SCN_NLINNO
67 #define GET_SCN_NLINNO(abfd, ext)  bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
68 #endif
69 #ifndef PUT_SCN_SCNLEN
70 #define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
71 #endif
72 #ifndef PUT_SCN_NRELOC
73 #define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
74 #endif
75 #ifndef PUT_SCN_NLINNO
76 #define PUT_SCN_NLINNO(abfd,in, ext)  bfd_h_put_16(abfd,in, (bfd_byte  *) ext->x_scn.x_nlinno)
77 #endif
78 #ifndef GET_LINENO_LNNO
79 #define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
80 #endif
81 #ifndef PUT_LINENO_LNNO
82 #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val,  (bfd_byte *) (ext->l_lnno));
83 #endif
84
85 /* The f_symptr field in the filehdr is sometimes 64 bits.  */
86 #ifndef GET_FILEHDR_SYMPTR
87 #define GET_FILEHDR_SYMPTR bfd_h_get_32
88 #endif
89 #ifndef PUT_FILEHDR_SYMPTR
90 #define PUT_FILEHDR_SYMPTR bfd_h_put_32
91 #endif
92
93 /* Some fields in the aouthdr are sometimes 64 bits.  */
94 #ifndef GET_AOUTHDR_TSIZE
95 #define GET_AOUTHDR_TSIZE bfd_h_get_32
96 #endif
97 #ifndef PUT_AOUTHDR_TSIZE
98 #define PUT_AOUTHDR_TSIZE bfd_h_put_32
99 #endif
100 #ifndef GET_AOUTHDR_DSIZE
101 #define GET_AOUTHDR_DSIZE bfd_h_get_32
102 #endif
103 #ifndef PUT_AOUTHDR_DSIZE
104 #define PUT_AOUTHDR_DSIZE bfd_h_put_32
105 #endif
106 #ifndef GET_AOUTHDR_BSIZE
107 #define GET_AOUTHDR_BSIZE bfd_h_get_32
108 #endif
109 #ifndef PUT_AOUTHDR_BSIZE
110 #define PUT_AOUTHDR_BSIZE bfd_h_put_32
111 #endif
112 #ifndef GET_AOUTHDR_ENTRY
113 #define GET_AOUTHDR_ENTRY bfd_h_get_32
114 #endif
115 #ifndef PUT_AOUTHDR_ENTRY
116 #define PUT_AOUTHDR_ENTRY bfd_h_put_32
117 #endif
118 #ifndef GET_AOUTHDR_TEXT_START
119 #define GET_AOUTHDR_TEXT_START bfd_h_get_32
120 #endif
121 #ifndef PUT_AOUTHDR_TEXT_START
122 #define PUT_AOUTHDR_TEXT_START bfd_h_put_32
123 #endif
124 #ifndef GET_AOUTHDR_DATA_START
125 #define GET_AOUTHDR_DATA_START bfd_h_get_32
126 #endif
127 #ifndef PUT_AOUTHDR_DATA_START
128 #define PUT_AOUTHDR_DATA_START bfd_h_put_32
129 #endif
130
131 /* Some fields in the scnhdr are sometimes 64 bits.  */
132 #ifndef GET_SCNHDR_PADDR
133 #define GET_SCNHDR_PADDR bfd_h_get_32
134 #endif
135 #ifndef PUT_SCNHDR_PADDR
136 #define PUT_SCNHDR_PADDR bfd_h_put_32
137 #endif
138 #ifndef GET_SCNHDR_VADDR
139 #define GET_SCNHDR_VADDR bfd_h_get_32
140 #endif
141 #ifndef PUT_SCNHDR_VADDR
142 #define PUT_SCNHDR_VADDR bfd_h_put_32
143 #endif
144 #ifndef GET_SCNHDR_SIZE
145 #define GET_SCNHDR_SIZE bfd_h_get_32
146 #endif
147 #ifndef PUT_SCNHDR_SIZE
148 #define PUT_SCNHDR_SIZE bfd_h_put_32
149 #endif
150 #ifndef GET_SCNHDR_SCNPTR
151 #define GET_SCNHDR_SCNPTR bfd_h_get_32
152 #endif
153 #ifndef PUT_SCNHDR_SCNPTR
154 #define PUT_SCNHDR_SCNPTR bfd_h_put_32
155 #endif
156 #ifndef GET_SCNHDR_RELPTR
157 #define GET_SCNHDR_RELPTR bfd_h_get_32
158 #endif
159 #ifndef PUT_SCNHDR_RELPTR
160 #define PUT_SCNHDR_RELPTR bfd_h_put_32
161 #endif
162 #ifndef GET_SCNHDR_LNNOPTR
163 #define GET_SCNHDR_LNNOPTR bfd_h_get_32
164 #endif
165 #ifndef PUT_SCNHDR_LNNOPTR
166 #define PUT_SCNHDR_LNNOPTR bfd_h_put_32
167 #endif
168
169
170
171 /**********************************************************************/
172
173 static void
174 coff_swap_reloc_in (abfd, src, dst)
175      bfd *abfd;
176      PTR src;
177      PTR dst;
178 {
179   RELOC *reloc_src = (RELOC *) src;
180   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
181
182   reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
183   reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
184
185   reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
186
187 #ifdef SWAP_IN_RELOC_OFFSET
188   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
189                                              (bfd_byte *) reloc_src->r_offset);
190 #endif
191 }
192
193
194 static unsigned int
195 coff_swap_reloc_out (abfd, src, dst)
196      bfd       *abfd;
197      PTR        src;
198      PTR        dst;
199 {
200   struct internal_reloc *reloc_src = (struct internal_reloc *)src;
201   struct external_reloc *reloc_dst = (struct external_reloc *)dst;
202   bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
203   bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
204
205   bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
206                reloc_dst->r_type);
207
208 #ifdef SWAP_OUT_RELOC_OFFSET
209   SWAP_OUT_RELOC_OFFSET(abfd,
210                         reloc_src->r_offset,
211                         (bfd_byte *) reloc_dst->r_offset);
212 #endif
213 #ifdef SWAP_OUT_RELOC_EXTRA
214   SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
215 #endif
216   return sizeof(struct external_reloc);
217 }
218
219
220 static void
221 coff_swap_filehdr_in (abfd, src, dst)
222      bfd            *abfd;
223      PTR             src;
224      PTR             dst;
225 {
226   FILHDR *filehdr_src = (FILHDR *) src;
227   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
228   filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic);
229   filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns);
230   filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat);
231
232   filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
233   filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
234   filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr);
235
236   /* Other people's tools sometimes generate headers
237      with an nsyms but a zero symptr. */
238   if (filehdr_dst->f_nsyms && filehdr_dst->f_symptr)
239     {
240       filehdr_dst->f_flags |= HAS_SYMS;
241     }
242   else 
243     {
244       filehdr_dst->f_symptr = 0;
245       filehdr_dst->f_nsyms = 0;
246       filehdr_dst->f_flags &= ~HAS_SYMS;
247     }
248
249   filehdr_dst->f_opthdr = bfd_h_get_16(abfd, 
250                                        (bfd_byte *)filehdr_src-> f_opthdr);
251 }
252
253 #ifdef COFF_IMAGE_WITH_PE
254
255 static  unsigned int
256 coff_swap_filehdr_out (abfd, in, out)
257      bfd       *abfd;
258      PTR        in;
259      PTR        out;
260 {
261   int idx;
262   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
263   FILHDR *filehdr_out = (FILHDR *)out;
264
265   if (pe_data (abfd)->has_reloc_section)
266     filehdr_in->f_flags &= ~F_RELFLG;
267
268   if (pe_data (abfd)->dll)
269     filehdr_in->f_flags |= F_DLL;
270
271   filehdr_in->pe.e_magic    = DOSMAGIC;
272   filehdr_in->pe.e_cblp     = 0x90;
273   filehdr_in->pe.e_cp       = 0x3;
274   filehdr_in->pe.e_crlc     = 0x0;
275   filehdr_in->pe.e_cparhdr  = 0x4;
276   filehdr_in->pe.e_minalloc = 0x0;
277   filehdr_in->pe.e_maxalloc = 0xffff;
278   filehdr_in->pe.e_ss       = 0x0;
279   filehdr_in->pe.e_sp       = 0xb8;
280   filehdr_in->pe.e_csum     = 0x0;
281   filehdr_in->pe.e_ip       = 0x0;
282   filehdr_in->pe.e_cs       = 0x0;
283   filehdr_in->pe.e_lfarlc   = 0x40;
284   filehdr_in->pe.e_ovno     = 0x0;
285
286   for (idx=0; idx < 4; idx++)
287     filehdr_in->pe.e_res[idx] = 0x0;
288
289   filehdr_in->pe.e_oemid   = 0x0;
290   filehdr_in->pe.e_oeminfo = 0x0;
291
292   for (idx=0; idx < 10; idx++)
293     filehdr_in->pe.e_res2[idx] = 0x0;
294
295   filehdr_in->pe.e_lfanew = 0x80;
296
297   /* this next collection of data are mostly just characters.  It appears
298      to be constant within the headers put on NT exes */
299   filehdr_in->pe.dos_message[0]  = 0x0eba1f0e;
300   filehdr_in->pe.dos_message[1]  = 0xcd09b400;
301   filehdr_in->pe.dos_message[2]  = 0x4c01b821;
302   filehdr_in->pe.dos_message[3]  = 0x685421cd;
303   filehdr_in->pe.dos_message[4]  = 0x70207369;
304   filehdr_in->pe.dos_message[5]  = 0x72676f72;
305   filehdr_in->pe.dos_message[6]  = 0x63206d61;
306   filehdr_in->pe.dos_message[7]  = 0x6f6e6e61;
307   filehdr_in->pe.dos_message[8]  = 0x65622074;
308   filehdr_in->pe.dos_message[9]  = 0x6e757220;
309   filehdr_in->pe.dos_message[10] = 0x206e6920;
310   filehdr_in->pe.dos_message[11] = 0x20534f44;
311   filehdr_in->pe.dos_message[12] = 0x65646f6d;
312   filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
313   filehdr_in->pe.dos_message[14] = 0x24;
314   filehdr_in->pe.dos_message[15] = 0x0;
315   filehdr_in->pe.nt_signature = NT_SIGNATURE;
316
317
318
319   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
320   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
321
322   bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat);
323   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
324                       (bfd_byte *) filehdr_out->f_symptr);
325   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
326   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
327   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
328
329   /* put in extra dos header stuff.  This data remains essentially
330      constant, it just has to be tacked on to the beginning of all exes 
331      for NT */
332   bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic);
333   bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp);
334   bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp);
335   bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc);
336   bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr, 
337                (bfd_byte *) filehdr_out->e_cparhdr);
338   bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc, 
339                (bfd_byte *) filehdr_out->e_minalloc);
340   bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc, 
341                (bfd_byte *) filehdr_out->e_maxalloc);
342   bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss);
343   bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp);
344   bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum);
345   bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip);
346   bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs);
347   bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
348   bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno);
349   {
350     int idx;
351     for (idx=0; idx < 4; idx++)
352       bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx], 
353                    (bfd_byte *) filehdr_out->e_res[idx]);
354   }
355   bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid);
356   bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo,
357                (bfd_byte *) filehdr_out->e_oeminfo);
358   {
359     int idx;
360     for (idx=0; idx < 10; idx++)
361       bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx],
362                    (bfd_byte *) filehdr_out->e_res2[idx]);
363   }
364   bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
365
366   {
367     int idx;
368     for (idx=0; idx < 16; idx++)
369       bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx],
370                    (bfd_byte *) filehdr_out->dos_message[idx]);
371   }
372
373   /* also put in the NT signature */
374   bfd_h_put_32(abfd, filehdr_in->pe.nt_signature, 
375                (bfd_byte *) filehdr_out->nt_signature);
376
377
378
379
380   return sizeof(FILHDR);
381 }
382 #else
383
384 static  unsigned int
385 coff_swap_filehdr_out (abfd, in, out)
386      bfd       *abfd;
387      PTR        in;
388      PTR        out;
389 {
390   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
391   FILHDR *filehdr_out = (FILHDR *)out;
392
393   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
394   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
395   bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
396   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
397                       (bfd_byte *) filehdr_out->f_symptr);
398   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
399   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
400   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
401
402   return sizeof(FILHDR);
403 }
404
405 #endif
406
407
408 static void
409 coff_swap_sym_in (abfd, ext1, in1)
410      bfd            *abfd;
411      PTR ext1;
412      PTR in1;
413 {
414   SYMENT *ext = (SYMENT *)ext1;
415   struct internal_syment      *in = (struct internal_syment *)in1;
416
417   if( ext->e.e_name[0] == 0) {
418     in->_n._n_n._n_zeroes = 0;
419     in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
420   }
421   else {
422 #if SYMNMLEN != E_SYMNMLEN
423     -> Error, we need to cope with truncating or extending SYMNMLEN!;
424 #else
425     memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
426 #endif
427   }
428
429   in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); 
430   in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
431   if (sizeof(ext->e_type) == 2){
432     in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
433   }
434   else {
435     in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
436   }
437   in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
438   in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
439
440   /* The section symbols for the .idata$ sections have class 68, which MS
441      documentation indicates is a section symbol.  The problem is that the
442      value field in the symbol is simply a copy of the .idata section's flags
443      rather than something useful.  When these symbols are encountered, change
444      the value to 0 and the section number to 1 so that they will be handled
445      somewhat correctly in the bfd code. */
446   if (in->n_sclass == 0x68) {
447     in->n_value = 0x0;
448     in->n_scnum = 1;
449     /* I have tried setting the class to 3 and using the following to set
450        the section number.  This will put the address of the pointer to the
451        string kernel32.dll at addresses 0 and 0x10 off start of idata section
452        which is not correct */
453     /*    if (strcmp (in->_n._n_name, ".idata$4") == 0) */
454     /*      in->n_scnum = 3; */
455     /*    else */
456     /*      in->n_scnum = 2; */
457   }
458
459 #ifdef coff_swap_sym_in_hook
460   coff_swap_sym_in_hook(abfd, ext1, in1);
461 #endif
462 }
463
464 static unsigned int
465 coff_swap_sym_out (abfd, inp, extp)
466      bfd       *abfd;
467      PTR        inp;
468      PTR        extp;
469 {
470   struct internal_syment *in = (struct internal_syment *)inp;
471   SYMENT *ext =(SYMENT *)extp;
472   if(in->_n._n_name[0] == 0) {
473     bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
474     bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *)  ext->e.e.e_offset);
475   }
476   else {
477 #if SYMNMLEN != E_SYMNMLEN
478     -> Error, we need to cope with truncating or extending SYMNMLEN!;
479 #else
480     memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
481 #endif
482   }
483
484   bfd_h_put_32(abfd,  in->n_value , (bfd_byte *) ext->e_value);
485   bfd_h_put_16(abfd,  in->n_scnum , (bfd_byte *) ext->e_scnum);
486   if (sizeof(ext->e_type) == 2)
487     {
488       bfd_h_put_16(abfd,  in->n_type , (bfd_byte *) ext->e_type);
489     }
490   else
491     {
492       bfd_h_put_32(abfd,  in->n_type , (bfd_byte *) ext->e_type);
493     }
494   bfd_h_put_8(abfd,  in->n_sclass , ext->e_sclass);
495   bfd_h_put_8(abfd,  in->n_numaux , ext->e_numaux);
496
497   return sizeof(SYMENT);
498 }
499
500 static void
501 coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
502      bfd            *abfd;
503      PTR              ext1;
504      int             type;
505      int             class;
506      int              indx;
507      int              numaux;
508      PTR              in1;
509 {
510   AUXENT    *ext = (AUXENT *)ext1;
511   union internal_auxent *in = (union internal_auxent *)in1;
512
513   switch (class) {
514   case C_FILE:
515     if (ext->x_file.x_fname[0] == 0) {
516       in->x_file.x_n.x_zeroes = 0;
517       in->x_file.x_n.x_offset = 
518         bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
519     } else {
520 #if FILNMLEN != E_FILNMLEN
521       -> Error, we need to cope with truncating or extending FILNMLEN!;
522 #else
523       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
524 #endif
525     }
526     return;
527
528
529   case C_STAT:
530 #ifdef C_LEAFSTAT
531   case C_LEAFSTAT:
532 #endif
533   case C_HIDDEN:
534     if (type == T_NULL) {
535       in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
536       in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
537       in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
538       return;
539     }
540     break;
541   }
542
543   in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
544 #ifndef NO_TVNDX
545   in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
546 #endif
547
548   if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
549     {
550       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
551       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
552     }
553   else
554     {
555 #if DIMNUM != E_DIMNUM
556  #error we need to cope with truncating or extending DIMNUM
557 #endif
558       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
559         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
560       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
561         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
562       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
563         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
564       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
565         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
566     }
567
568   if (ISFCN(type)) {
569     in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
570   }
571   else {
572     in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
573     in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
574   }
575 }
576
577 static unsigned int
578 coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
579      bfd   *abfd;
580      PTR        inp;
581      int   type;
582      int   class;
583      int   indx;
584      int   numaux;
585      PTR        extp;
586 {
587   union internal_auxent *in = (union internal_auxent *)inp;
588   AUXENT *ext = (AUXENT *)extp;
589
590   memset((PTR)ext, 0, AUXESZ);
591   switch (class) {
592   case C_FILE:
593     if (in->x_file.x_fname[0] == 0) {
594       bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
595       bfd_h_put_32(abfd,
596               in->x_file.x_n.x_offset,
597               (bfd_byte *) ext->x_file.x_n.x_offset);
598     }
599     else {
600 #if FILNMLEN != E_FILNMLEN
601       -> Error, we need to cope with truncating or extending FILNMLEN!;
602 #else
603       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
604 #endif
605     }
606     return sizeof (AUXENT);
607
608
609   case C_STAT:
610 #ifdef C_LEAFSTAT
611   case C_LEAFSTAT:
612 #endif
613   case C_HIDDEN:
614     if (type == T_NULL) {
615       PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
616       PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
617       PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
618       return sizeof (AUXENT);
619     }
620     break;
621   }
622
623   bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
624 #ifndef NO_TVNDX
625   bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
626 #endif
627
628   if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
629     {
630       PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
631       PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
632     }
633   else
634     {
635 #if DIMNUM != E_DIMNUM
636  #error we need to cope with truncating or extending DIMNUM
637 #endif
638       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
639                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
640       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
641                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
642       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
643                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
644       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
645                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
646     }
647
648   if (ISFCN (type))
649     bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
650              (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
651   else
652     {
653       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
654       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
655     }
656
657   return sizeof(AUXENT);
658 }
659
660
661 static void
662 coff_swap_lineno_in (abfd, ext1, in1)
663      bfd            *abfd;
664      PTR ext1;
665      PTR in1;
666 {
667   LINENO *ext = (LINENO *)ext1;
668   struct internal_lineno      *in = (struct internal_lineno *)in1;
669
670   in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
671   in->l_lnno = GET_LINENO_LNNO(abfd, ext);
672 }
673
674 static unsigned int
675 coff_swap_lineno_out (abfd, inp, outp)
676      bfd       *abfd;
677      PTR        inp;
678      PTR        outp;
679 {
680   struct internal_lineno *in = (struct internal_lineno *)inp;
681   struct external_lineno *ext = (struct external_lineno *)outp;
682   bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
683           ext->l_addr.l_symndx);
684
685   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
686   return sizeof(struct external_lineno);
687 }
688
689
690
691 static void
692 coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
693      bfd            *abfd;
694      PTR aouthdr_ext1;
695      PTR aouthdr_int1;
696 {
697   struct internal_extra_pe_aouthdr *a;
698   PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
699   AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
700   struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
701
702   aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
703   aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
704   aouthdr_int->tsize =
705     GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
706   aouthdr_int->dsize =
707     GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
708   aouthdr_int->bsize =
709     GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
710   aouthdr_int->entry =
711     GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
712   aouthdr_int->text_start =
713     GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
714   aouthdr_int->data_start =
715     GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
716
717   a = &aouthdr_int->pe;
718   a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase);
719   a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment);
720   a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment);
721   a->MajorOperatingSystemVersion = 
722     bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion);
723   a->MinorOperatingSystemVersion = 
724     bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion);
725   a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion);
726   a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion);
727   a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion);
728   a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion);
729   a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1);
730   a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage);
731   a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders);
732   a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum);
733   a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem);
734   a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics);
735   a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve);
736   a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit);
737   a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve);
738   a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit);
739   a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags);
740   a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes);
741
742   {
743     int idx;
744     for (idx=0; idx < 16; idx++)
745       {
746         a->DataDirectory[idx].VirtualAddress =
747           bfd_h_get_32 (abfd, src->DataDirectory[idx][0]);
748         a->DataDirectory[idx].Size =
749           bfd_h_get_32 (abfd, src->DataDirectory[idx][1]);
750       }
751   }
752
753   if (aouthdr_int->entry)
754     aouthdr_int->entry += a->ImageBase;
755   if (aouthdr_int->tsize) 
756     aouthdr_int->text_start += a->ImageBase;
757   if (aouthdr_int->dsize) 
758     aouthdr_int->data_start += a->ImageBase;
759 }
760
761
762 static void add_data_entry (abfd, aout, idx, name, base)
763      bfd *abfd;
764      struct internal_extra_pe_aouthdr *aout;
765      int idx;
766      char *name;
767      bfd_vma base;
768 {
769   asection *sec = bfd_get_section_by_name (abfd, name);
770
771   /* add import directory information if it exists */
772   if (sec != NULL)
773     {
774       aout->DataDirectory[idx].VirtualAddress = sec->lma - base;
775       aout->DataDirectory[idx].Size = sec->_cooked_size;
776       sec->flags |= SEC_DATA;
777     }
778 }
779
780 static unsigned int
781 coff_swap_aouthdr_out (abfd, in, out)
782      bfd       *abfd;
783      PTR        in;
784      PTR        out;
785 {
786   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
787   struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
788   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
789
790   bfd_vma sa = extra->SectionAlignment;
791   bfd_vma fa = extra->FileAlignment;
792   bfd_vma ib = extra->ImageBase ;
793
794   if (aouthdr_in->tsize) 
795     aouthdr_in->text_start -= ib;
796   if (aouthdr_in->dsize) 
797     aouthdr_in->data_start -= ib;
798   if (aouthdr_in->entry) 
799     aouthdr_in->entry -= ib;
800
801 #define FA(x)  (((x) + fa -1 ) & (- fa))
802 #define SA(x)  (((x) + sa -1 ) & (- sa))
803
804   /* We like to have the sizes aligned */
805
806   aouthdr_in->bsize = FA (aouthdr_in->bsize);
807
808
809   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
810
811   /* first null out all data directory entries .. */
812   memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
813
814   add_data_entry (abfd, extra, 0, ".edata", ib);
815   add_data_entry (abfd, extra, 1, ".idata", ib);
816   add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
817
818 #ifdef POWERPC_LE_PE
819   /* FIXME: do other PE platforms use this? */
820   add_data_entry (abfd, extra, 3, ".pdata" ,ib);
821 #endif
822
823   add_data_entry (abfd, extra, 5, ".reloc", ib);
824
825 #ifdef POWERPC_LE_PE
826   /* On the PPC NT system, this field is set up as follows. It is
827      not an "officially" reserved field, so it currently has no title.
828      first_thunk_address is idata$5, and the thunk_size is the size
829      of the idata$5 chunk of the idata section.
830   */
831   extra->DataDirectory[12].VirtualAddress = first_thunk_address;
832   extra->DataDirectory[12].Size = thunk_size;
833
834   /* On the PPC NT system, the size of the directory entry is not the
835      size of the entire section. It's actually offset to the end of 
836      the idata$3 component of the idata section. This is the size of
837      the entire import table. (also known as the start of idata$4)
838   */
839   extra->DataDirectory[1].Size = import_table_size;
840 #endif
841
842   {
843     asection *sec;
844     bfd_vma dsize= 0;
845     bfd_vma isize = SA(abfd->sections->filepos);
846     bfd_vma tsize= 0;
847 #ifdef PPC
848     isize = 0;
849 #endif
850     for (sec = abfd->sections; sec; sec = sec->next)
851       {
852         int rounded = FA(sec->_raw_size);
853         if (sec->flags & SEC_DATA) 
854           dsize += rounded;
855         if (sec->flags & SEC_CODE)
856           tsize += rounded;
857         isize += SA(rounded);
858       }
859
860     aouthdr_in->dsize = dsize;
861     aouthdr_in->tsize = tsize;
862     extra->SizeOfImage = isize;
863   }
864
865   extra->SizeOfHeaders = abfd->sections->filepos;
866   bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
867
868 #ifdef POWERPC_LE_PE
869   /* this little piece of magic sets the "linker version" field to 2.60 */
870   bfd_h_put_16(abfd, 2  + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
871 #else
872   /* this little piece of magic sets the "linker version" field to 2.55 */
873   bfd_h_put_16(abfd, 2  + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
874 #endif
875
876   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
877   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
878   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
879   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
880   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
881                           (bfd_byte *) aouthdr_out->standard.text_start);
882
883   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
884                           (bfd_byte *) aouthdr_out->standard.data_start);
885
886
887   bfd_h_put_32 (abfd, extra->ImageBase, 
888                 (bfd_byte *) aouthdr_out->ImageBase);
889   bfd_h_put_32 (abfd, extra->SectionAlignment,
890                 (bfd_byte *) aouthdr_out->SectionAlignment);
891   bfd_h_put_32 (abfd, extra->FileAlignment,
892                 (bfd_byte *) aouthdr_out->FileAlignment);
893   bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
894                 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
895   bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
896                 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
897   bfd_h_put_16 (abfd, extra->MajorImageVersion,
898                 (bfd_byte *) aouthdr_out->MajorImageVersion);
899   bfd_h_put_16 (abfd, extra->MinorImageVersion,
900                 (bfd_byte *) aouthdr_out->MinorImageVersion);
901   bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
902                 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
903   bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
904                 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
905   bfd_h_put_32 (abfd, extra->Reserved1,
906                 (bfd_byte *) aouthdr_out->Reserved1);
907   bfd_h_put_32 (abfd, extra->SizeOfImage,
908                 (bfd_byte *) aouthdr_out->SizeOfImage);
909   bfd_h_put_32 (abfd, extra->SizeOfHeaders,
910                 (bfd_byte *) aouthdr_out->SizeOfHeaders);
911   bfd_h_put_32 (abfd, extra->CheckSum,
912                 (bfd_byte *) aouthdr_out->CheckSum);
913   bfd_h_put_16 (abfd, extra->Subsystem,
914                 (bfd_byte *) aouthdr_out->Subsystem);
915   bfd_h_put_16 (abfd, extra->DllCharacteristics,
916                 (bfd_byte *) aouthdr_out->DllCharacteristics);
917   bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
918                 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
919   bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
920                 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
921   bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
922                 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
923   bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
924                 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
925   bfd_h_put_32 (abfd, extra->LoaderFlags,
926                 (bfd_byte *) aouthdr_out->LoaderFlags);
927   bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
928                 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
929   {
930     int idx;
931     for (idx=0; idx < 16; idx++)
932       {
933         bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
934                       (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
935         bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
936                       (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
937       }
938   }
939
940   return sizeof(AOUTHDR);
941 }
942
943 static void
944     coff_swap_scnhdr_in (abfd, ext, in)
945       bfd            *abfd;
946   PTR        ext;
947   PTR        in;
948 {
949   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
950   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
951
952   memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
953   scnhdr_int->s_vaddr =
954     GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
955   scnhdr_int->s_paddr =
956     GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
957   scnhdr_int->s_size =
958     GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
959   scnhdr_int->s_scnptr =
960     GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
961   scnhdr_int->s_relptr =
962     GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
963   scnhdr_int->s_lnnoptr =
964     GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
965   scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
966
967   scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
968   scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
969
970   if (scnhdr_int->s_vaddr != 0) 
971     {
972       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
973     }
974   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
975     {
976       scnhdr_int->s_size = scnhdr_int->s_paddr;
977       scnhdr_int->s_paddr = 0;
978     }
979 }
980
981 static unsigned int
982 coff_swap_scnhdr_out (abfd, in, out)
983      bfd       *abfd;
984      PTR        in;
985      PTR        out;
986 {
987   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
988   SCNHDR *scnhdr_ext = (SCNHDR *)out;
989   unsigned int ret = sizeof (SCNHDR);
990   bfd_vma ps;
991   bfd_vma ss;
992
993   memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
994
995   PUT_SCNHDR_VADDR (abfd, 
996                     (scnhdr_int->s_vaddr 
997                      - pe_data(abfd)->pe_opthdr.ImageBase),
998                     (bfd_byte *) scnhdr_ext->s_vaddr);
999
1000   /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1001      value except for the BSS section, its s_size should be 0 */
1002
1003
1004   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
1005     {
1006       ps = scnhdr_int->s_size;
1007       ss = 0;
1008     }
1009   else
1010     {
1011       ps = scnhdr_int->s_paddr;
1012       ss = scnhdr_int->s_size;
1013     }
1014
1015   PUT_SCNHDR_SIZE (abfd, ss,
1016                    (bfd_byte *) scnhdr_ext->s_size);
1017
1018
1019   PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
1020
1021   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
1022                      (bfd_byte *) scnhdr_ext->s_scnptr);
1023   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
1024                      (bfd_byte *) scnhdr_ext->s_relptr);
1025   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
1026                       (bfd_byte *) scnhdr_ext->s_lnnoptr);
1027
1028   /* Extra flags must be set when dealing with NT.  All sections should also
1029      have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
1030      .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1031      sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1032      (this is especially important when dealing with the .idata section since
1033      the addresses for routines from .dlls must be overwritten).  If .reloc
1034      section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1035      (0x02000000).  Also, the resource data should also be read and
1036      writable.  */
1037
1038   /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1039   /* FIXME: even worse, I don't see how to get the original alignment field*/
1040   /*        back...                                                        */
1041
1042   {
1043     int flags = scnhdr_int->s_flags;
1044     if (strcmp (scnhdr_int->s_name, ".data")  == 0 ||
1045         strcmp (scnhdr_int->s_name, ".CRT")   == 0 ||
1046         strcmp (scnhdr_int->s_name, ".rsrc")  == 0 ||
1047         strcmp (scnhdr_int->s_name, ".bss")   == 0)
1048       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1049     else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1050       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1051     else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1052       flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
1053     else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1054       flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;     
1055     else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1056              || strcmp (scnhdr_int->s_name, ".edata") == 0)
1057       flags =  IMAGE_SCN_MEM_READ | SEC_DATA;     
1058     /* ppc-nt additions */
1059     else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1060       flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1061                           IMAGE_SCN_MEM_READ ;
1062     /* Remember this field is a max of 8 chars, so the null is _not_ there
1063        for an 8 character name like ".reldata". (yep. Stupid bug) */
1064     else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
1065       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1066                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1067     else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1068       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1069                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1070     else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1071       flags =  IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1072     /* end of ppc-nt additions */
1073
1074     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1075   }
1076
1077   if (scnhdr_int->s_nlnno <= 0xffff)
1078     bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1079   else
1080     {
1081       (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1082                              bfd_get_filename (abfd),
1083                              scnhdr_int->s_nlnno);
1084       bfd_set_error (bfd_error_file_truncated);
1085       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1086       ret = 0;
1087     }
1088   if (scnhdr_int->s_nreloc <= 0xffff)
1089     bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1090   else
1091     {
1092       (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1093                              bfd_get_filename (abfd),
1094                              scnhdr_int->s_nreloc);
1095       bfd_set_error (bfd_error_file_truncated);
1096       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1097       ret = 0;
1098     }
1099   return ret;
1100 }
1101
1102 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = 
1103 {
1104   "Export Directory [.edata]",
1105   "Import Directory [parts of .idata]",
1106   "Resource Directory [.rsrc]",
1107   "Exception Directory [.pdata]",
1108   "Security Directory",
1109   "Base Relocation Directory [.reloc]",
1110   "Debug Directory",
1111   "Description Directory",
1112   "Special Directory",
1113   "Thread Storage Directory [.tls]",
1114   "Load Configuration Directory",
1115   "Bound Import Directory",
1116   "Import Address Table Directory",
1117   "Reserved",
1118   "Reserved",
1119   "Reserved"
1120 };
1121
1122 /**********************************************************************/
1123 static boolean
1124 pe_print_idata(abfd, vfile)
1125      bfd*abfd;
1126      void *vfile;
1127 {
1128   FILE *file = vfile;
1129   bfd_byte *data = 0;
1130   asection *section = bfd_get_section_by_name (abfd, ".idata");
1131
1132 #ifdef POWERPC_LE_PE
1133   asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1134 #endif
1135
1136   bfd_size_type datasize = 0;
1137   bfd_size_type i;
1138   bfd_size_type start, stop;
1139   int onaline = 20;
1140   bfd_vma addr_value;
1141   bfd_vma loadable_toc_address;
1142   bfd_vma toc_address;
1143   bfd_vma start_address;
1144
1145   pe_data_type *pe = pe_data (abfd);
1146   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1147
1148   if (section == 0)
1149     return true;
1150
1151 #ifdef POWERPC_LE_PE
1152   if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1153     {
1154       /* The toc address can be found by taking the starting address,
1155          which on the PPC locates a function descriptor. The descriptor
1156          consists of the function code starting address followed by the
1157          address of the toc. The starting address we get from the bfd,
1158          and the descriptor is supposed to be in the .reldata section. 
1159       */
1160
1161       bfd_byte *data = 0;
1162       int offset;
1163       data = (bfd_byte *) malloc ((size_t) bfd_section_size (abfd, 
1164                                                              rel_section));
1165       if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1166         {
1167           bfd_set_error (bfd_error_no_memory);
1168           return false;
1169         }
1170       datasize = bfd_section_size (abfd, rel_section);
1171   
1172       bfd_get_section_contents (abfd, 
1173                                 rel_section, 
1174                                 (PTR) data, 0, 
1175                                 bfd_section_size (abfd, rel_section));
1176
1177       offset = abfd->start_address - rel_section->vma;
1178
1179       start_address = bfd_get_32(abfd, data+offset);
1180       loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1181       toc_address = loadable_toc_address - 32768;
1182       fprintf(file,
1183               "\nFunction descriptor located at the start address:\n");
1184       fprintf (file,
1185                " %04lx code-base %08lx toc (loadable) %08lx toc (actual) %08lx\n", 
1186                (unsigned long int) (abfd->start_address),
1187                start_address, loadable_toc_address, toc_address);
1188     }
1189   else
1190     {
1191       loadable_toc_address = 0; 
1192       toc_address = 0; 
1193       start_address = 0;
1194     }
1195 #endif
1196
1197   fprintf(file,
1198           "\nThe Import Tables (interpreted .idata section contents)\n");
1199   fprintf(file,
1200           " vma:    Hint    Time      Forward  DLL       First\n");
1201   fprintf(file,
1202           "         Table   Stamp     Chain    Name      Thunk\n");
1203
1204   if (bfd_section_size (abfd, section) == 0)
1205     return true;
1206
1207   data = (bfd_byte *) malloc ((size_t) bfd_section_size (abfd, section));
1208   datasize = bfd_section_size (abfd, section);
1209   if (data == NULL && datasize != 0)
1210     {
1211       bfd_set_error (bfd_error_no_memory);
1212       return false;
1213     }
1214
1215   bfd_get_section_contents (abfd, 
1216                             section, 
1217                             (PTR) data, 0, 
1218                             bfd_section_size (abfd, section));
1219
1220   start = 0;
1221
1222   stop = bfd_section_size (abfd, section);
1223
1224   for (i = start; i < stop; i += onaline)
1225     {
1226       bfd_vma hint_addr;
1227       bfd_vma time_stamp;
1228       bfd_vma forward_chain;
1229       bfd_vma dll_name;
1230       bfd_vma first_thunk;
1231       int idx;
1232       int j;
1233       char *dll;
1234       int adj = extra->ImageBase - section->vma;
1235
1236       fprintf (file,
1237                " %04lx\t", 
1238                (unsigned long int) (i + section->vma));
1239       
1240       if (i+20 > stop)
1241         {
1242           /* check stuff */
1243           ;
1244         }
1245       
1246       hint_addr = bfd_get_32(abfd, data+i);
1247       time_stamp = bfd_get_32(abfd, data+i+4);
1248       forward_chain = bfd_get_32(abfd, data+i+8);
1249       dll_name = bfd_get_32(abfd, data+i+12);
1250       first_thunk = bfd_get_32(abfd, data+i+16);
1251       
1252       fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1253               hint_addr,
1254               time_stamp,
1255               forward_chain,
1256               dll_name,
1257               first_thunk);
1258
1259       if (hint_addr ==0)
1260         {
1261           break;
1262         }
1263
1264       /* the image base is present in the section->vma */
1265       dll = data + dll_name + adj;
1266       fprintf(file, "\n\tDLL Name: %s\n", dll);
1267       fprintf(file, "\tvma:  Ordinal  Member-Name\n");
1268
1269       idx = hint_addr + adj;
1270
1271       for (j=0;j<stop;j+=4)
1272         {
1273           int ordinal;
1274           char *member_name;
1275           bfd_vma member = bfd_get_32(abfd, data + idx + j);
1276           if (member == 0)
1277             break;
1278           ordinal = bfd_get_16(abfd,
1279                                data + member + adj);
1280           member_name = data + member + adj + 2;
1281           fprintf(file, "\t%04lx\t %4d  %s\n",
1282                   member, ordinal, member_name);
1283         }
1284
1285       if (hint_addr != first_thunk) 
1286         {
1287           int differ = 0;
1288           int idx2;
1289
1290           idx2 = first_thunk + adj;
1291
1292           for (j=0;j<stop;j+=4)
1293             {
1294               int ordinal;
1295               char *member_name;
1296               bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1297               bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1298               if (hint_member != iat_member)
1299                 {
1300                   if (differ == 0)
1301                     {
1302                       fprintf(file, 
1303                               "\tThe Import Address Table (difference found)\n");
1304                       fprintf(file, "\tvma:  Ordinal  Member-Name\n");
1305                       differ = 1;
1306                     }
1307                   if (iat_member == 0)
1308                     {
1309                       fprintf(file,
1310                               "\t>>> Ran out of IAT members!\n");
1311                     }
1312                   else 
1313                     {
1314                       ordinal = bfd_get_16(abfd,
1315                                            data + iat_member + adj);
1316                       member_name = data + iat_member + adj + 2;
1317                       fprintf(file, "\t%04lx\t %4d  %s\n",
1318                               iat_member, ordinal, member_name);
1319                     }
1320                   break;
1321                 }
1322               if (hint_member == 0)
1323                 break;
1324             }
1325           if (differ == 0)
1326             {
1327               fprintf(file,
1328                       "\tThe Import Address Table is identical\n");
1329             }
1330         }
1331
1332       fprintf(file, "\n");
1333
1334     }
1335
1336
1337   free (data);
1338 }
1339 static boolean
1340 pe_print_pdata(abfd, vfile)
1341      bfd*abfd;
1342      void *vfile;
1343 {
1344   FILE *file = vfile;
1345   bfd_byte *data = 0;
1346   asection *section = bfd_get_section_by_name (abfd, ".pdata");
1347   bfd_size_type datasize = 0;
1348   bfd_size_type i;
1349   bfd_size_type start, stop;
1350   int onaline = 20;
1351   bfd_vma addr_value;
1352
1353   if (section == 0)
1354     return true;
1355
1356   fprintf(file,
1357           "\nThe Function Table (interpreted .pdata section contents)\n");
1358   fprintf(file,
1359           " vma:   Begin    End      EH       EH       PrologEnd\n");
1360   fprintf(file,
1361           "        Address  Address  Handler  Data     Address\n");
1362
1363   if (bfd_section_size (abfd, section) == 0)
1364     return true;
1365
1366   data = (bfd_byte *) malloc ((size_t) bfd_section_size (abfd, section));
1367   datasize = bfd_section_size (abfd, section);
1368   if (data == NULL && datasize != 0)
1369     {
1370       bfd_set_error (bfd_error_no_memory);
1371       return false;
1372     }
1373
1374   bfd_get_section_contents (abfd, 
1375                             section, 
1376                             (PTR) data, 0, 
1377                             bfd_section_size (abfd, section));
1378
1379   start = 0;
1380
1381   stop = bfd_section_size (abfd, section);
1382
1383   for (i = start; i < stop; i += onaline)
1384     {
1385       bfd_vma begin_addr;
1386       bfd_vma end_addr;
1387       bfd_vma eh_handler;
1388       bfd_vma eh_data;
1389       bfd_vma prolog_end_addr;
1390
1391       if (i+20 > stop)
1392           break;
1393       
1394       begin_addr = bfd_get_32(abfd, data+i);
1395       end_addr = bfd_get_32(abfd, data+i+4);
1396       eh_handler = bfd_get_32(abfd, data+i+8);
1397       eh_data = bfd_get_32(abfd, data+i+12);
1398       prolog_end_addr = bfd_get_32(abfd, data+i+16);
1399       
1400       if (begin_addr == 0)
1401         {
1402           /* We are probably into the padding of the
1403              section now */
1404           break;
1405         }
1406
1407       fprintf (file,
1408                " %04lx\t", 
1409                (unsigned long int) (i + section->vma));
1410
1411       fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1412               begin_addr,
1413               end_addr,
1414               eh_handler,
1415               eh_data,
1416               prolog_end_addr);
1417
1418 #ifdef POWERPC_LE_PE
1419       if (eh_handler == 0 && eh_data != 0)
1420         {
1421           /* Special bits here, although the meaning may */
1422           /* be a little mysterious. The only one I know */
1423           /* for sure is 0x03.                           */
1424           /* Code Significance                           */
1425           /* 0x00 None                                   */
1426           /* 0x01 Register Save Millicode                */
1427           /* 0x02 Register Restore Millicode             */
1428           /* 0x03 Glue Code Sequence                     */
1429           switch (eh_data)
1430             {
1431             case 0x01:
1432               fprintf(file, " Register save millicode");
1433               break;
1434             case 0x02:
1435               fprintf(file, " Register restore millicode");
1436               break;
1437             case 0x03:
1438               fprintf(file, " Glue code sequence");
1439               break;
1440             default:
1441               break;
1442             }
1443         }
1444 #endif     
1445       fprintf(file, "\n");
1446     }
1447
1448   free (data);
1449 }
1450
1451 static boolean
1452 pe_print_private_bfd_data (abfd, vfile)
1453      bfd *abfd;
1454      PTR vfile;
1455 {
1456   FILE *file = (FILE *) vfile;
1457   int j;
1458   pe_data_type *pe = pe_data (abfd);
1459   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1460
1461   fprintf (file,"\nImageBase\t\t");
1462   fprintf_vma (file, i->ImageBase);
1463   fprintf (file,"\nSectionAlignment\t");
1464   fprintf_vma (file, i->SectionAlignment);
1465   fprintf (file,"\nFileAlignment\t\t");
1466   fprintf_vma (file, i->FileAlignment);
1467   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1468   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1469   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1470   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1471   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1472   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1473   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1474   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1475   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1476   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1477   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1478   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1479   fprintf (file,"SizeOfStackReserve\t");
1480   fprintf_vma (file, i->SizeOfStackReserve);
1481   fprintf (file,"\nSizeOfStackCommit\t");
1482   fprintf_vma (file, i->SizeOfStackCommit);
1483   fprintf (file,"\nSizeOfHeapReserve\t");
1484   fprintf_vma (file, i->SizeOfHeapReserve);
1485   fprintf (file,"\nSizeOfHeapCommit\t");
1486   fprintf_vma (file, i->SizeOfHeapCommit);
1487   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1488   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1489
1490   fprintf (file,"\nThe Data Directory\n");
1491   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) 
1492     {
1493       fprintf (file, "Entry %1x ", j);
1494       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1495       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1496       fprintf (file, "%s\n", dir_names[j]);
1497     }
1498
1499   pe_print_idata(abfd, vfile);
1500   pe_print_pdata(abfd, vfile);
1501
1502   return true;
1503 }
1504
1505 static boolean
1506 pe_mkobject (abfd)
1507      bfd * abfd;
1508 {
1509   pe_data_type *pe;
1510   abfd->tdata.pe_obj_data = 
1511     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1512
1513   if (abfd->tdata.pe_obj_data == 0)
1514     return false;
1515
1516   pe = pe_data (abfd);
1517
1518   pe->coff.pe = 1;
1519   pe->in_reloc_p = in_reloc_p;
1520   return true;
1521 }
1522
1523 /* Create the COFF backend specific information.  */
1524 static PTR
1525 pe_mkobject_hook (abfd, filehdr, aouthdr)
1526      bfd * abfd;
1527      PTR filehdr;
1528      PTR aouthdr;
1529 {
1530   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1531   pe_data_type *pe;
1532
1533   if (pe_mkobject (abfd) == false)
1534     return NULL;
1535
1536   pe = pe_data (abfd);
1537   pe->coff.sym_filepos = internal_f->f_symptr;
1538   /* These members communicate important constants about the symbol
1539      table to GDB's symbol-reading code.  These `constants'
1540      unfortunately vary among coff implementations...  */
1541   pe->coff.local_n_btmask = N_BTMASK;
1542   pe->coff.local_n_btshft = N_BTSHFT;
1543   pe->coff.local_n_tmask = N_TMASK;
1544   pe->coff.local_n_tshift = N_TSHIFT;
1545   pe->coff.local_symesz = SYMESZ;
1546   pe->coff.local_auxesz = AUXESZ;
1547   pe->coff.local_linesz = LINESZ;
1548
1549   obj_raw_syment_count (abfd) =
1550     obj_conv_table_size (abfd) =
1551       internal_f->f_nsyms;
1552
1553   pe->real_flags = internal_f->f_flags;
1554
1555 #ifdef COFF_IMAGE_WITH_PE
1556   if (aouthdr) 
1557     {
1558       pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1559     }
1560 #endif
1561
1562   return (PTR) pe;
1563 }
1564
1565
1566
1567 /* Copy any private info we understand from the input bfd
1568    to the output bfd.  */
1569
1570 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1571
1572 static boolean
1573 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1574      bfd *ibfd, *obfd;
1575 {
1576   /* One day we may try to grok other private data.  */
1577   if (ibfd->xvec->flavour != bfd_target_coff_flavour
1578       || obfd->xvec->flavour != bfd_target_coff_flavour)
1579     return true;
1580
1581   pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1582
1583   return true;
1584 }