* cofflink.c (_bfd_coff_final_link): Handle long section names.
[platform/upstream/binutils.git] / bfd / peicode.h
1 /* Support for the generic parts of most COFF variants, for BFD.
2    Copyright 1995, 1996 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /*
22 Most of this hacked by  Steve Chamberlain,
23                         sac@cygnus.com
24 */
25
26
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 = sec->_cooked_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     /* ppc-nt additions */
1069     else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1070       flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1071                           IMAGE_SCN_MEM_READ ;
1072     /* Remember this field is a max of 8 chars, so the null is _not_ there
1073        for an 8 character name like ".reldata". (yep. Stupid bug) */
1074     else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
1075       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1076                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1077     else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1078       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1079                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1080     else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1081       flags =  IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1082     /* end of ppc-nt additions */
1083 #ifdef POWERPC_LE_PE
1084     else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0)
1085       {
1086         flags =  IMAGE_SCN_LNK_INFO;
1087       }
1088     else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1089       {
1090         flags =  IMAGE_SCN_LNK_INFO;
1091       }
1092 #endif
1093
1094     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1095   }
1096
1097   if (scnhdr_int->s_nlnno <= 0xffff)
1098     bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1099   else
1100     {
1101       (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1102                              bfd_get_filename (abfd),
1103                              scnhdr_int->s_nlnno);
1104       bfd_set_error (bfd_error_file_truncated);
1105       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1106       ret = 0;
1107     }
1108   if (scnhdr_int->s_nreloc <= 0xffff)
1109     bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1110   else
1111     {
1112       (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1113                              bfd_get_filename (abfd),
1114                              scnhdr_int->s_nreloc);
1115       bfd_set_error (bfd_error_file_truncated);
1116       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1117       ret = 0;
1118     }
1119   return ret;
1120 }
1121
1122 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = 
1123 {
1124   "Export Directory [.edata]",
1125   "Import Directory [parts of .idata]",
1126   "Resource Directory [.rsrc]",
1127   "Exception Directory [.pdata]",
1128   "Security Directory",
1129   "Base Relocation Directory [.reloc]",
1130   "Debug Directory",
1131   "Description Directory",
1132   "Special Directory",
1133   "Thread Storage Directory [.tls]",
1134   "Load Configuration Directory",
1135   "Bound Import Directory",
1136   "Import Address Table Directory",
1137   "Reserved",
1138   "Reserved",
1139   "Reserved"
1140 };
1141
1142 /**********************************************************************/
1143 static boolean
1144 pe_print_idata(abfd, vfile)
1145      bfd*abfd;
1146      void *vfile;
1147 {
1148   FILE *file = vfile;
1149   bfd_byte *data = 0;
1150   asection *section = bfd_get_section_by_name (abfd, ".idata");
1151
1152 #ifdef POWERPC_LE_PE
1153   asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1154 #endif
1155
1156   bfd_size_type datasize = 0;
1157   bfd_size_type i;
1158   bfd_size_type start, stop;
1159   int onaline = 20;
1160
1161   pe_data_type *pe = pe_data (abfd);
1162   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1163
1164   if (section == 0)
1165     return true;
1166
1167 #ifdef POWERPC_LE_PE
1168   if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1169     {
1170       /* The toc address can be found by taking the starting address,
1171          which on the PPC locates a function descriptor. The descriptor
1172          consists of the function code starting address followed by the
1173          address of the toc. The starting address we get from the bfd,
1174          and the descriptor is supposed to be in the .reldata section. 
1175       */
1176
1177       bfd_vma loadable_toc_address;
1178       bfd_vma toc_address;
1179       bfd_vma start_address;
1180       bfd_byte *data = 0;
1181       int offset;
1182       data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, 
1183                                                                  rel_section));
1184       if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1185         return false;
1186
1187       datasize = bfd_section_size (abfd, rel_section);
1188   
1189       bfd_get_section_contents (abfd, 
1190                                 rel_section, 
1191                                 (PTR) data, 0, 
1192                                 bfd_section_size (abfd, rel_section));
1193
1194       offset = abfd->start_address - rel_section->vma;
1195
1196       start_address = bfd_get_32(abfd, data+offset);
1197       loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1198       toc_address = loadable_toc_address - 32768;
1199
1200       fprintf(file,
1201               "\nFunction descriptor located at the start address: %04lx\n",
1202               (unsigned long int) (abfd->start_address));
1203       fprintf (file,
1204                "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n", 
1205                start_address, loadable_toc_address, toc_address);
1206     }
1207 #endif
1208
1209   fprintf(file,
1210           "\nThe Import Tables (interpreted .idata section contents)\n");
1211   fprintf(file,
1212           " vma:    Hint    Time      Forward  DLL       First\n");
1213   fprintf(file,
1214           "         Table   Stamp     Chain    Name      Thunk\n");
1215
1216   if (bfd_section_size (abfd, section) == 0)
1217     return true;
1218
1219   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1220   datasize = bfd_section_size (abfd, section);
1221   if (data == NULL && datasize != 0)
1222     return false;
1223
1224   bfd_get_section_contents (abfd, 
1225                             section, 
1226                             (PTR) data, 0, 
1227                             bfd_section_size (abfd, section));
1228
1229   start = 0;
1230
1231   stop = bfd_section_size (abfd, section);
1232
1233   for (i = start; i < stop; i += onaline)
1234     {
1235       bfd_vma hint_addr;
1236       bfd_vma time_stamp;
1237       bfd_vma forward_chain;
1238       bfd_vma dll_name;
1239       bfd_vma first_thunk;
1240       int idx;
1241       int j;
1242       char *dll;
1243       int adj = extra->ImageBase - section->vma;
1244
1245       fprintf (file,
1246                " %04lx\t", 
1247                (unsigned long int) (i + section->vma));
1248       
1249       if (i+20 > stop)
1250         {
1251           /* check stuff */
1252           ;
1253         }
1254       
1255       hint_addr = bfd_get_32(abfd, data+i);
1256       time_stamp = bfd_get_32(abfd, data+i+4);
1257       forward_chain = bfd_get_32(abfd, data+i+8);
1258       dll_name = bfd_get_32(abfd, data+i+12);
1259       first_thunk = bfd_get_32(abfd, data+i+16);
1260       
1261       fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1262               hint_addr,
1263               time_stamp,
1264               forward_chain,
1265               dll_name,
1266               first_thunk);
1267
1268       if (hint_addr ==0)
1269         {
1270           break;
1271         }
1272
1273       /* the image base is present in the section->vma */
1274       dll = (char *) data + dll_name + adj;
1275       fprintf(file, "\n\tDLL Name: %s\n", dll);
1276       fprintf(file, "\tvma:  Ordinal  Member-Name\n");
1277
1278       idx = hint_addr + adj;
1279
1280       for (j=0;j<stop;j+=4)
1281         {
1282           int ordinal;
1283           char *member_name;
1284           bfd_vma member = bfd_get_32(abfd, data + idx + j);
1285           if (member == 0)
1286             break;
1287           ordinal = bfd_get_16(abfd,
1288                                data + member + adj);
1289           member_name = (char *) data + member + adj + 2;
1290           fprintf(file, "\t%04lx\t %4d  %s\n",
1291                   member, ordinal, member_name);
1292         }
1293
1294       if (hint_addr != first_thunk) 
1295         {
1296           int differ = 0;
1297           int idx2;
1298
1299           idx2 = first_thunk + adj;
1300
1301           for (j=0;j<stop;j+=4)
1302             {
1303               int ordinal;
1304               char *member_name;
1305               bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1306               bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1307               if (hint_member != iat_member)
1308                 {
1309                   if (differ == 0)
1310                     {
1311                       fprintf(file, 
1312                               "\tThe Import Address Table (difference found)\n");
1313                       fprintf(file, "\tvma:  Ordinal  Member-Name\n");
1314                       differ = 1;
1315                     }
1316                   if (iat_member == 0)
1317                     {
1318                       fprintf(file,
1319                               "\t>>> Ran out of IAT members!\n");
1320                     }
1321                   else 
1322                     {
1323                       ordinal = bfd_get_16(abfd,
1324                                            data + iat_member + adj);
1325                       member_name = (char *) data + iat_member + adj + 2;
1326                       fprintf(file, "\t%04lx\t %4d  %s\n",
1327                               iat_member, ordinal, member_name);
1328                     }
1329                   break;
1330                 }
1331               if (hint_member == 0)
1332                 break;
1333             }
1334           if (differ == 0)
1335             {
1336               fprintf(file,
1337                       "\tThe Import Address Table is identical\n");
1338             }
1339         }
1340
1341       fprintf(file, "\n");
1342
1343     }
1344
1345   free (data);
1346
1347   return true;
1348 }
1349
1350 static boolean
1351 pe_print_edata(abfd, vfile)
1352      bfd*abfd;
1353      void *vfile;
1354 {
1355   FILE *file = vfile;
1356   bfd_byte *data = 0;
1357   asection *section = bfd_get_section_by_name (abfd, ".edata");
1358
1359   bfd_size_type datasize = 0;
1360   bfd_size_type i;
1361
1362   int adj;
1363   struct EDT_type 
1364     {
1365       long export_flags;             /* reserved - should be zero */
1366       long time_stamp;
1367       short major_ver;
1368       short minor_ver;
1369       bfd_vma name;                  /* rva - relative to image base */
1370       long base;                     /* ordinal base */
1371       long num_functions;        /* Number in the export address table */
1372       long num_names;            /* Number in the name pointer table */
1373       bfd_vma eat_addr;    /* rva to the export address table */
1374       bfd_vma npt_addr;        /* rva to the Export Name Pointer Table */
1375       bfd_vma ot_addr; /* rva to the Ordinal Table */
1376     } edt;
1377
1378   pe_data_type *pe = pe_data (abfd);
1379   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1380
1381   if (section == 0)
1382     return true;
1383
1384   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, 
1385                                                              section));
1386   datasize = bfd_section_size (abfd, section);
1387
1388   if (data == NULL && datasize != 0)
1389     return false;
1390
1391   bfd_get_section_contents (abfd, 
1392                             section, 
1393                             (PTR) data, 0, 
1394                             bfd_section_size (abfd, section));
1395
1396   /* Go get Export Directory Table */
1397   edt.export_flags   = bfd_get_32(abfd, data+0); 
1398   edt.time_stamp     = bfd_get_32(abfd, data+4);
1399   edt.major_ver      = bfd_get_16(abfd, data+8);
1400   edt.minor_ver      = bfd_get_16(abfd, data+10);
1401   edt.name           = bfd_get_32(abfd, data+12);
1402   edt.base           = bfd_get_32(abfd, data+16);
1403   edt.num_functions  = bfd_get_32(abfd, data+20); 
1404   edt.num_names      = bfd_get_32(abfd, data+24); 
1405   edt.eat_addr       = bfd_get_32(abfd, data+28);
1406   edt.npt_addr       = bfd_get_32(abfd, data+32); 
1407   edt.ot_addr        = bfd_get_32(abfd, data+36);
1408
1409   adj = extra->ImageBase - section->vma;
1410
1411
1412   /* Dump the EDT first first */
1413   fprintf(file,
1414           "\nThe Export Tables (interpreted .edata section contents)\n\n");
1415
1416   fprintf(file,
1417           "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1418
1419   fprintf(file,
1420           "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1421
1422   fprintf(file,
1423           "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1424
1425   fprintf (file,
1426            "Name \t\t\t\t");
1427   fprintf_vma (file, edt.name);
1428   fprintf (file,
1429            "%s\n", data + edt.name + adj);
1430
1431   fprintf(file,
1432           "Ordinal Base \t\t\t%ld\n", edt.base);
1433
1434   fprintf(file,
1435           "Number in:\n");
1436
1437   fprintf(file,
1438           "\tExport Address Table \t\t%lx\n",
1439           (unsigned long) edt.num_functions);
1440
1441   fprintf(file,
1442           "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1443
1444   fprintf(file,
1445           "Table Addresses\n");
1446
1447   fprintf (file,
1448            "\tExport Address Table \t\t");
1449   fprintf_vma (file, edt.eat_addr);
1450   fprintf (file, "\n");
1451
1452   fprintf (file,
1453           "\tName Pointer Table \t\t");
1454   fprintf_vma (file, edt.npt_addr);
1455   fprintf (file, "\n");
1456
1457   fprintf (file,
1458            "\tOrdinal Table \t\t\t");
1459   fprintf_vma (file, edt.ot_addr);
1460   fprintf (file, "\n");
1461
1462   
1463   /* The next table to find si the Export Address Table. It's basically
1464      a list of pointers that either locate a function in this dll, or
1465      forward the call to another dll. Something like:
1466       typedef union 
1467       {
1468         long export_rva;
1469         long forwarder_rva;
1470       } export_address_table_entry;
1471   */
1472
1473   fprintf(file,
1474           "\nExport Address Table -- Ordinal Base %ld\n",
1475           edt.base);
1476
1477   for (i = 0; i < edt.num_functions; ++i)
1478     {
1479       bfd_vma eat_member = bfd_get_32(abfd, 
1480                                       data + edt.eat_addr + (i*4) + adj);
1481       bfd_vma eat_actual = extra->ImageBase + eat_member;
1482       bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1483       bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1484
1485
1486       if (eat_member == 0)
1487         continue;
1488
1489       if (edata_start < eat_actual && eat_actual < edata_end) 
1490         {
1491           /* this rva is to a name (forwarding function) in our section */
1492           /* Should locate a function descriptor */
1493           fprintf(file,
1494                   "\t[%4ld] +base[%4ld] %04lx %s -- %s\n", 
1495                   (long) i, (long) (i + edt.base), eat_member,
1496                   "Forwarder RVA", data + eat_member + adj);
1497         }
1498       else
1499         {
1500           /* Should locate a function descriptor in the reldata section */
1501           fprintf(file,
1502                   "\t[%4ld] +base[%4ld] %04lx %s\n", 
1503                   (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1504         }
1505     }
1506
1507   /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1508   /* Dump them in parallel for clarity */
1509   fprintf(file,
1510           "\n[Ordinal/Name Pointer] Table\n");
1511
1512   for (i = 0; i < edt.num_names; ++i)
1513     {
1514       bfd_vma name_ptr = bfd_get_32(abfd, 
1515                                     data + 
1516                                     edt.npt_addr
1517                                     + (i*4) + adj);
1518       
1519       char *name = (char *) data + name_ptr + adj;
1520
1521       bfd_vma ord = bfd_get_16(abfd, 
1522                                     data + 
1523                                     edt.ot_addr
1524                                     + (i*2) + adj);
1525       fprintf(file,
1526               "\t[%4ld] %s\n", (long) ord, name);
1527
1528     }
1529
1530   free (data);
1531
1532   return true;
1533 }
1534
1535 static boolean
1536 pe_print_pdata(abfd, vfile)
1537      bfd*abfd;
1538      void *vfile;
1539 {
1540   FILE *file = vfile;
1541   bfd_byte *data = 0;
1542   asection *section = bfd_get_section_by_name (abfd, ".pdata");
1543   bfd_size_type datasize = 0;
1544   bfd_size_type i;
1545   bfd_size_type start, stop;
1546   int onaline = 20;
1547
1548   if (section == 0)
1549     return true;
1550
1551   stop = bfd_section_size (abfd, section);
1552   if ((stop % onaline) != 0)
1553     fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1554              (long)stop, onaline);
1555
1556   fprintf(file,
1557           "\nThe Function Table (interpreted .pdata section contents)\n");
1558   fprintf(file,
1559           " vma:\t\tBegin    End      EH       EH       PrologEnd\n");
1560   fprintf(file,
1561           "     \t\tAddress  Address  Handler  Data     Address\n");
1562
1563   if (bfd_section_size (abfd, section) == 0)
1564     return true;
1565
1566   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1567   datasize = bfd_section_size (abfd, section);
1568   if (data == NULL && datasize != 0)
1569     return false;
1570
1571   bfd_get_section_contents (abfd, 
1572                             section, 
1573                             (PTR) data, 0, 
1574                             bfd_section_size (abfd, section));
1575
1576   start = 0;
1577
1578   for (i = start; i < stop; i += onaline)
1579     {
1580       bfd_vma begin_addr;
1581       bfd_vma end_addr;
1582       bfd_vma eh_handler;
1583       bfd_vma eh_data;
1584       bfd_vma prolog_end_addr;
1585
1586       if (i+20 > stop)
1587           break;
1588       
1589       begin_addr = bfd_get_32(abfd, data+i);
1590       end_addr = bfd_get_32(abfd, data+i+4);
1591       eh_handler = bfd_get_32(abfd, data+i+8);
1592       eh_data = bfd_get_32(abfd, data+i+12);
1593       prolog_end_addr = bfd_get_32(abfd, data+i+16);
1594       
1595       if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1596           && eh_data == 0 && prolog_end_addr == 0)
1597         {
1598           /* We are probably into the padding of the
1599              section now */
1600           break;
1601         }
1602
1603       fprintf (file,
1604                " %08lx\t", 
1605                (unsigned long int) (i + section->vma));
1606
1607       fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1608               begin_addr,
1609               end_addr,
1610               eh_handler,
1611               eh_data,
1612               prolog_end_addr);
1613
1614 #ifdef POWERPC_LE_PE
1615       if (eh_handler == 0 && eh_data != 0)
1616         {
1617           /* Special bits here, although the meaning may */
1618           /* be a little mysterious. The only one I know */
1619           /* for sure is 0x03.                           */
1620           /* Code Significance                           */
1621           /* 0x00 None                                   */
1622           /* 0x01 Register Save Millicode                */
1623           /* 0x02 Register Restore Millicode             */
1624           /* 0x03 Glue Code Sequence                     */
1625           switch (eh_data)
1626             {
1627             case 0x01:
1628               fprintf(file, " Register save millicode");
1629               break;
1630             case 0x02:
1631               fprintf(file, " Register restore millicode");
1632               break;
1633             case 0x03:
1634               fprintf(file, " Glue code sequence");
1635               break;
1636             default:
1637               break;
1638             }
1639         }
1640 #endif     
1641       fprintf(file, "\n");
1642     }
1643
1644   free (data);
1645
1646   return true;
1647 }
1648
1649 static const char *tbl[6] =
1650 {
1651 "ABSOLUTE",
1652 "HIGH",
1653 "LOW",
1654 "HIGHLOW",
1655 "HIGHADJ",
1656 "unknown"
1657 };
1658
1659 static boolean
1660 pe_print_reloc(abfd, vfile)
1661      bfd*abfd;
1662      void *vfile;
1663 {
1664   FILE *file = vfile;
1665   bfd_byte *data = 0;
1666   asection *section = bfd_get_section_by_name (abfd, ".reloc");
1667   bfd_size_type datasize = 0;
1668   bfd_size_type i;
1669   bfd_size_type start, stop;
1670
1671   if (section == 0)
1672     return true;
1673
1674   if (bfd_section_size (abfd, section) == 0)
1675     return true;
1676
1677   fprintf(file,
1678           "\n\nPE File Base Relocations (interpreted .reloc section contents)\n");
1679
1680   data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1681   datasize = bfd_section_size (abfd, section);
1682   if (data == NULL && datasize != 0)
1683     return false;
1684
1685   bfd_get_section_contents (abfd, 
1686                             section, 
1687                             (PTR) data, 0, 
1688                             bfd_section_size (abfd, section));
1689
1690   start = 0;
1691
1692   stop = bfd_section_size (abfd, section);
1693
1694   for (i = start; i < stop;)
1695     {
1696       int j;
1697       bfd_vma virtual_address;
1698       long number, size;
1699
1700       /* The .reloc section is a sequence of blocks, with a header consisting
1701          of two 32 bit quantities, followed by a number of 16 bit entries */
1702
1703       virtual_address = bfd_get_32(abfd, data+i);
1704       size = bfd_get_32(abfd, data+i+4);
1705       number = (size - 8) / 2;
1706
1707       if (size == 0) 
1708         {
1709           break;
1710         }
1711
1712       fprintf (file,
1713                "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1714                virtual_address, size, size, number);
1715
1716       for (j = 0; j < number; ++j)
1717         {
1718           unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1719           int t =   (e & 0xF000) >> 12;
1720           int off = e & 0x0FFF;
1721
1722           if (t > 5) 
1723             abort();
1724
1725           fprintf(file,
1726                   "\treloc %4d offset %4x [%4lx] %s\n", 
1727                   j, off, (long) (off + virtual_address), tbl[t]);
1728           
1729         }
1730       i += size;
1731     }
1732
1733   free (data);
1734
1735   return true;
1736 }
1737
1738 static boolean
1739 pe_print_private_bfd_data (abfd, vfile)
1740      bfd *abfd;
1741      PTR vfile;
1742 {
1743   FILE *file = (FILE *) vfile;
1744   int j;
1745   pe_data_type *pe = pe_data (abfd);
1746   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1747
1748   fprintf (file,"\nImageBase\t\t");
1749   fprintf_vma (file, i->ImageBase);
1750   fprintf (file,"\nSectionAlignment\t");
1751   fprintf_vma (file, i->SectionAlignment);
1752   fprintf (file,"\nFileAlignment\t\t");
1753   fprintf_vma (file, i->FileAlignment);
1754   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1755   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1756   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1757   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1758   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1759   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1760   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1761   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1762   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1763   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1764   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1765   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1766   fprintf (file,"SizeOfStackReserve\t");
1767   fprintf_vma (file, i->SizeOfStackReserve);
1768   fprintf (file,"\nSizeOfStackCommit\t");
1769   fprintf_vma (file, i->SizeOfStackCommit);
1770   fprintf (file,"\nSizeOfHeapReserve\t");
1771   fprintf_vma (file, i->SizeOfHeapReserve);
1772   fprintf (file,"\nSizeOfHeapCommit\t");
1773   fprintf_vma (file, i->SizeOfHeapCommit);
1774   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1775   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1776
1777   fprintf (file,"\nThe Data Directory\n");
1778   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) 
1779     {
1780       fprintf (file, "Entry %1x ", j);
1781       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1782       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1783       fprintf (file, "%s\n", dir_names[j]);
1784     }
1785
1786   pe_print_idata(abfd, vfile);
1787   pe_print_edata(abfd, vfile);
1788   pe_print_pdata(abfd, vfile);
1789   pe_print_reloc(abfd, vfile);
1790
1791   return true;
1792 }
1793
1794 static boolean
1795 pe_mkobject (abfd)
1796      bfd * abfd;
1797 {
1798   pe_data_type *pe;
1799   abfd->tdata.pe_obj_data = 
1800     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1801
1802   if (abfd->tdata.pe_obj_data == 0)
1803     return false;
1804
1805   pe = pe_data (abfd);
1806
1807   pe->coff.pe = 1;
1808   pe->in_reloc_p = in_reloc_p;
1809   return true;
1810 }
1811
1812 /* Create the COFF backend specific information.  */
1813 static PTR
1814 pe_mkobject_hook (abfd, filehdr, aouthdr)
1815      bfd * abfd;
1816      PTR filehdr;
1817      PTR aouthdr;
1818 {
1819   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1820   pe_data_type *pe;
1821
1822   if (pe_mkobject (abfd) == false)
1823     return NULL;
1824
1825   pe = pe_data (abfd);
1826   pe->coff.sym_filepos = internal_f->f_symptr;
1827   /* These members communicate important constants about the symbol
1828      table to GDB's symbol-reading code.  These `constants'
1829      unfortunately vary among coff implementations...  */
1830   pe->coff.local_n_btmask = N_BTMASK;
1831   pe->coff.local_n_btshft = N_BTSHFT;
1832   pe->coff.local_n_tmask = N_TMASK;
1833   pe->coff.local_n_tshift = N_TSHIFT;
1834   pe->coff.local_symesz = SYMESZ;
1835   pe->coff.local_auxesz = AUXESZ;
1836   pe->coff.local_linesz = LINESZ;
1837
1838   obj_raw_syment_count (abfd) =
1839     obj_conv_table_size (abfd) =
1840       internal_f->f_nsyms;
1841
1842   pe->real_flags = internal_f->f_flags;
1843
1844 #ifdef COFF_IMAGE_WITH_PE
1845   if (aouthdr) 
1846     {
1847       pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1848     }
1849 #endif
1850
1851   return (PTR) pe;
1852 }
1853
1854
1855
1856 /* Copy any private info we understand from the input bfd
1857    to the output bfd.  */
1858
1859 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1860
1861 static boolean
1862 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1863      bfd *ibfd, *obfd;
1864 {
1865   /* One day we may try to grok other private data.  */
1866   if (ibfd->xvec->flavour != bfd_target_coff_flavour
1867       || obfd->xvec->flavour != bfd_target_coff_flavour)
1868     return true;
1869
1870   pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1871
1872   return true;
1873 }
1874
1875 #ifdef COFF_IMAGE_WITH_PE
1876
1877 /* Copy private section data.  */
1878
1879 #define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
1880
1881 static boolean pe_bfd_copy_private_section_data
1882   PARAMS ((bfd *, asection *, bfd *, asection *));
1883
1884 static boolean
1885 pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
1886      bfd *ibfd;
1887      asection *isec;
1888      bfd *obfd;
1889      asection *osec;
1890 {
1891   if (coff_section_data (ibfd, isec) != NULL
1892       && pei_section_data (ibfd, isec) != NULL)
1893     {
1894       if (coff_section_data (obfd, osec) == NULL)
1895         {
1896           osec->used_by_bfd =
1897             (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
1898           if (osec->used_by_bfd == NULL)
1899             return false;
1900         }
1901       if (pei_section_data (obfd, osec) == NULL)
1902         {
1903           coff_section_data (obfd, osec)->tdata =
1904             (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
1905           if (coff_section_data (obfd, osec)->tdata == NULL)
1906             return false;
1907         }
1908       pei_section_data (obfd, osec)->virt_size =
1909         pei_section_data (ibfd, isec)->virt_size;
1910     }
1911
1912   return true;
1913 }
1914
1915 #endif