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