xref: /openbsd-src/gnu/usr.bin/binutils/bfd/peicode.h (revision 2159047f7a97bd07d66507696a8b038f6aef0509)
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   "Reserved",
1116   "Reserved [first thunk address on PPC]",
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 *) xmalloc ((size_t) bfd_section_size (abfd,
1164 							      rel_section));
1165       datasize = bfd_section_size (abfd, rel_section);
1166 
1167       bfd_get_section_contents (abfd,
1168 				rel_section,
1169 				(PTR) data, 0,
1170 				bfd_section_size (abfd, rel_section));
1171 
1172       offset = abfd->start_address - rel_section->vma;
1173 
1174       start_address = bfd_get_32(abfd, data+offset);
1175       loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1176       toc_address = loadable_toc_address - 32768;
1177       fprintf(file,
1178 	      "\nFunction descriptor located at the start address:\n");
1179       fprintf (file,
1180 	       " %04lx code-base %08lx toc (loadable) %08lx toc (actual) %08lx\n",
1181 	       (unsigned long int) (abfd->start_address),
1182 	       start_address, loadable_toc_address, toc_address);
1183     }
1184   else
1185     {
1186       loadable_toc_address = 0;
1187       toc_address = 0;
1188       start_address = 0;
1189     }
1190 #endif
1191 
1192   fprintf(file,
1193 	  "\nThe Import Tables (interpreted .idata section contents)\n");
1194   fprintf(file,
1195 	  " vma:    Hint    Time      Forward  DLL       First\n");
1196   fprintf(file,
1197 	  "         Table   Stamp     Chain    Name      Thunk\n");
1198 
1199   if (bfd_section_size (abfd, section) == 0)
1200     return true;
1201 
1202   data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
1203   datasize = bfd_section_size (abfd, section);
1204 
1205   bfd_get_section_contents (abfd,
1206 			    section,
1207 			    (PTR) data, 0,
1208 			    bfd_section_size (abfd, section));
1209 
1210   start = 0;
1211 
1212   stop = bfd_section_size (abfd, section);
1213 
1214   for (i = start; i < stop; i += onaline)
1215     {
1216       bfd_vma hint_addr;
1217       bfd_vma time_stamp;
1218       bfd_vma forward_chain;
1219       bfd_vma dll_name;
1220       bfd_vma first_thunk;
1221       int idx;
1222       int j;
1223       char *dll;
1224       int adj = extra->ImageBase - section->vma;
1225 
1226       fprintf (file,
1227 	       " %04lx\t",
1228 	       (unsigned long int) (i + section->vma));
1229 
1230       if (i+20 > stop)
1231 	{
1232 	  /* check stuff */
1233 	  ;
1234 	}
1235 
1236       hint_addr = bfd_get_32(abfd, data+i);
1237       time_stamp = bfd_get_32(abfd, data+i+4);
1238       forward_chain = bfd_get_32(abfd, data+i+8);
1239       dll_name = bfd_get_32(abfd, data+i+12);
1240       first_thunk = bfd_get_32(abfd, data+i+16);
1241 
1242       fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1243 	      hint_addr,
1244 	      time_stamp,
1245 	      forward_chain,
1246 	      dll_name,
1247 	      first_thunk);
1248 
1249       if (hint_addr ==0)
1250 	{
1251 	  break;
1252 	}
1253 
1254       /* the image base is present in the section->vma */
1255       dll = data + dll_name + adj;
1256       fprintf(file, "\n\tDLL Name: %s\n", dll);
1257       fprintf(file, "\tvma:  Ordinal  Member-Name\n");
1258 
1259       idx = hint_addr + adj;
1260 
1261       for (j=0;j<stop;j+=4)
1262 	{
1263 	  int ordinal;
1264 	  char *member_name;
1265 	  bfd_vma member = bfd_get_32(abfd, data + idx + j);
1266 	  if (member == 0)
1267 	    break;
1268 	  ordinal = bfd_get_16(abfd,
1269 			       data + member + adj);
1270 	  member_name = data + member + adj + 2;
1271 	  fprintf(file, "\t%04lx\t %4d  %s\n",
1272 		  member, ordinal, member_name);
1273 	}
1274 
1275       if (hint_addr != first_thunk)
1276 	{
1277 	  int differ = 0;
1278 	  int idx2;
1279 
1280 	  idx2 = first_thunk + adj;
1281 
1282 	  for (j=0;j<stop;j+=4)
1283 	    {
1284 	      int ordinal;
1285 	      char *member_name;
1286 	      bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1287 	      bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1288 	      if (hint_member != iat_member)
1289 		{
1290 		  if (differ == 0)
1291 		    {
1292 		      fprintf(file,
1293 			      "\tThe Import Address Table (difference found)\n");
1294 		      fprintf(file, "\tvma:  Ordinal  Member-Name\n");
1295 		      differ = 1;
1296 		    }
1297 		  if (iat_member == 0)
1298 		    {
1299 		      fprintf(file,
1300 			      "\t>>> Ran out of IAT members!\n");
1301 		    }
1302 		  else
1303 		    {
1304 		      ordinal = bfd_get_16(abfd,
1305 					   data + iat_member + adj);
1306 		      member_name = data + iat_member + adj + 2;
1307 		      fprintf(file, "\t%04lx\t %4d  %s\n",
1308 			      iat_member, ordinal, member_name);
1309 		    }
1310 		  break;
1311 		}
1312 	      if (hint_member == 0)
1313 		break;
1314 	    }
1315 	  if (differ == 0)
1316 	    {
1317 	      fprintf(file,
1318 		      "\tThe Import Address Table is identical\n");
1319 	    }
1320 	}
1321 
1322       fprintf(file, "\n");
1323 
1324     }
1325 
1326 
1327   free (data);
1328 }
1329 static boolean
1330 pe_print_pdata(abfd, vfile)
1331      bfd*abfd;
1332      void *vfile;
1333 {
1334   FILE *file = vfile;
1335   bfd_byte *data = 0;
1336   asection *section = bfd_get_section_by_name (abfd, ".pdata");
1337   bfd_size_type datasize = 0;
1338   bfd_size_type i;
1339   bfd_size_type start, stop;
1340   int onaline = 20;
1341   bfd_vma addr_value;
1342 
1343   if (section == 0)
1344     return true;
1345 
1346   fprintf(file,
1347 	  "\nThe Function Table (interpreted .pdata section contents)\n");
1348   fprintf(file,
1349 	  " vma:   Begin    End      EH       EH       PrologEnd\n");
1350   fprintf(file,
1351 	  "        Address  Address  Handler  Data     Address\n");
1352 
1353   if (bfd_section_size (abfd, section) == 0)
1354     return true;
1355 
1356   data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
1357   datasize = bfd_section_size (abfd, section);
1358 
1359   bfd_get_section_contents (abfd,
1360 			    section,
1361 			    (PTR) data, 0,
1362 			    bfd_section_size (abfd, section));
1363 
1364   start = 0;
1365 
1366   stop = bfd_section_size (abfd, section);
1367 
1368   for (i = start; i < stop; i += onaline)
1369     {
1370       bfd_vma begin_addr;
1371       bfd_vma end_addr;
1372       bfd_vma eh_handler;
1373       bfd_vma eh_data;
1374       bfd_vma prolog_end_addr;
1375 
1376       if (i+20 > stop)
1377 	  break;
1378 
1379       begin_addr = bfd_get_32(abfd, data+i);
1380       end_addr = bfd_get_32(abfd, data+i+4);
1381       eh_handler = bfd_get_32(abfd, data+i+8);
1382       eh_data = bfd_get_32(abfd, data+i+12);
1383       prolog_end_addr = bfd_get_32(abfd, data+i+16);
1384 
1385       if (begin_addr == 0)
1386 	{
1387 	  /* We are probably into the padding of the
1388 	     section now */
1389 	  break;
1390 	}
1391 
1392       fprintf (file,
1393 	       " %04lx\t",
1394 	       (unsigned long int) (i + section->vma));
1395 
1396       fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1397 	      begin_addr,
1398 	      end_addr,
1399 	      eh_handler,
1400 	      eh_data,
1401 	      prolog_end_addr);
1402 
1403 #ifdef POWERPC_LE_PE
1404       if (eh_handler == 0 && eh_data != 0)
1405 	{
1406 	  /* Special bits here, although the meaning may */
1407 	  /* be a little mysterious. The only one I know */
1408 	  /* for sure is 0x03.                           */
1409 	  /* Code Significance                           */
1410 	  /* 0x00 None                                   */
1411 	  /* 0x01 Register Save Millicode                */
1412 	  /* 0x02 Register Restore Millicode             */
1413 	  /* 0x03 Glue Code Sequence                     */
1414 	  switch (eh_data)
1415 	    {
1416 	    case 0x01:
1417 	      fprintf(file, " Register save millicode");
1418 	      break;
1419 	    case 0x02:
1420 	      fprintf(file, " Register restore millicode");
1421 	      break;
1422 	    case 0x03:
1423 	      fprintf(file, " Glue code sequence");
1424 	      break;
1425 	    default:
1426 	      break;
1427 	    }
1428 	}
1429 #endif
1430       fprintf(file, "\n");
1431     }
1432 
1433   free (data);
1434 }
1435 
1436 static boolean
1437 pe_print_private_bfd_data (abfd, vfile)
1438      bfd *abfd;
1439      PTR vfile;
1440 {
1441   FILE *file = (FILE *) vfile;
1442   int j;
1443   pe_data_type *pe = pe_data (abfd);
1444   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1445 
1446   fprintf (file,"\nImageBase\t\t");
1447   fprintf_vma (file, i->ImageBase);
1448   fprintf (file,"\nSectionAlignment\t");
1449   fprintf_vma (file, i->SectionAlignment);
1450   fprintf (file,"\nFileAlignment\t\t");
1451   fprintf_vma (file, i->FileAlignment);
1452   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1453   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1454   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1455   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1456   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1457   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1458   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1459   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1460   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1461   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1462   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1463   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1464   fprintf (file,"SizeOfStackReserve\t");
1465   fprintf_vma (file, i->SizeOfStackReserve);
1466   fprintf (file,"\nSizeOfStackCommit\t");
1467   fprintf_vma (file, i->SizeOfStackCommit);
1468   fprintf (file,"\nSizeOfHeapReserve\t");
1469   fprintf_vma (file, i->SizeOfHeapReserve);
1470   fprintf (file,"\nSizeOfHeapCommit\t");
1471   fprintf_vma (file, i->SizeOfHeapCommit);
1472   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1473   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1474 
1475   fprintf (file,"\nThe Data Directory\n");
1476   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1477     {
1478       fprintf (file, "Entry %1x ", j);
1479       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1480       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1481       fprintf (file, "%s\n", dir_names[j]);
1482     }
1483 
1484   pe_print_idata(abfd, vfile);
1485   pe_print_pdata(abfd, vfile);
1486 
1487   return true;
1488 }
1489 
1490 static boolean
1491 pe_mkobject (abfd)
1492      bfd * abfd;
1493 {
1494   pe_data_type *pe;
1495   abfd->tdata.pe_obj_data =
1496     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1497 
1498   if (abfd->tdata.pe_obj_data == 0)
1499     {
1500       bfd_set_error (bfd_error_no_memory);
1501       return false;
1502     }
1503 
1504   pe = pe_data (abfd);
1505 
1506   pe->coff.pe = 1;
1507   pe->in_reloc_p = in_reloc_p;
1508   return true;
1509 }
1510 
1511 /* Create the COFF backend specific information.  */
1512 static PTR
1513 pe_mkobject_hook (abfd, filehdr, aouthdr)
1514      bfd * abfd;
1515      PTR filehdr;
1516      PTR aouthdr;
1517 {
1518   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1519   pe_data_type *pe;
1520 
1521   if (pe_mkobject (abfd) == false)
1522     return NULL;
1523 
1524   pe = pe_data (abfd);
1525   pe->coff.sym_filepos = internal_f->f_symptr;
1526   /* These members communicate important constants about the symbol
1527      table to GDB's symbol-reading code.  These `constants'
1528      unfortunately vary among coff implementations...  */
1529   pe->coff.local_n_btmask = N_BTMASK;
1530   pe->coff.local_n_btshft = N_BTSHFT;
1531   pe->coff.local_n_tmask = N_TMASK;
1532   pe->coff.local_n_tshift = N_TSHIFT;
1533   pe->coff.local_symesz = SYMESZ;
1534   pe->coff.local_auxesz = AUXESZ;
1535   pe->coff.local_linesz = LINESZ;
1536 
1537   obj_raw_syment_count (abfd) =
1538     obj_conv_table_size (abfd) =
1539       internal_f->f_nsyms;
1540 
1541   pe->real_flags = internal_f->f_flags;
1542 
1543 #ifdef COFF_IMAGE_WITH_PE
1544   if (aouthdr)
1545     {
1546       pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1547     }
1548 #endif
1549 
1550   return (PTR) pe;
1551 }
1552 
1553 
1554 
1555 /* Copy any private info we understand from the input bfd
1556    to the output bfd.  */
1557 
1558 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1559 
1560 static boolean
1561 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1562      bfd *ibfd, *obfd;
1563 {
1564   /* One day we may try to grok other private data.  */
1565   if (ibfd->xvec->flavour != bfd_target_coff_flavour
1566       || obfd->xvec->flavour != bfd_target_coff_flavour)
1567     return true;
1568 
1569   pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1570 
1571   return true;
1572 }
1573