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