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