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