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