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