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