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