9335507bdd578515788b1362177580678c508a2f
[binutils-gdb.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 #ifdef POWERPC_LE_PE
1167 else if (strncmp (scnhdr_int->s_name, ".stabstr", 8) == 0)
1168 {
1169 flags = IMAGE_SCN_LNK_INFO;
1170 }
1171 else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1172 {
1173 flags = IMAGE_SCN_LNK_INFO;
1174 }
1175 #endif
1176 else
1177 flags = IMAGE_SCN_MEM_READ;
1178
1179 bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1180 }
1181
1182 if (scnhdr_int->s_nlnno <= 0xffff)
1183 bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1184 else
1185 {
1186 (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1187 bfd_get_filename (abfd),
1188 scnhdr_int->s_nlnno);
1189 bfd_set_error (bfd_error_file_truncated);
1190 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1191 ret = 0;
1192 }
1193 if (scnhdr_int->s_nreloc <= 0xffff)
1194 bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1195 else
1196 {
1197 (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1198 bfd_get_filename (abfd),
1199 scnhdr_int->s_nreloc);
1200 bfd_set_error (bfd_error_file_truncated);
1201 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1202 ret = 0;
1203 }
1204 return ret;
1205 }
1206
1207 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1208 {
1209 "Export Directory [.edata (or where ever we found it)]",
1210 "Import Directory [parts of .idata]",
1211 "Resource Directory [.rsrc]",
1212 "Exception Directory [.pdata]",
1213 "Security Directory",
1214 "Base Relocation Directory [.reloc]",
1215 "Debug Directory",
1216 "Description Directory",
1217 "Special Directory",
1218 "Thread Storage Directory [.tls]",
1219 "Load Configuration Directory",
1220 "Bound Import Directory",
1221 "Import Address Table Directory",
1222 "Reserved",
1223 "Reserved",
1224 "Reserved"
1225 };
1226
1227 /**********************************************************************/
1228 static boolean
1229 pe_print_idata(abfd, vfile)
1230 bfd *abfd;
1231 PTR vfile;
1232 {
1233 FILE *file = (FILE *) vfile;
1234 bfd_byte *data = 0;
1235 asection *section = bfd_get_section_by_name (abfd, ".idata");
1236
1237 #ifdef POWERPC_LE_PE
1238 asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1239 #endif
1240 else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0)
1241 flags |= IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE;
1242
1243 bfd_size_type datasize = 0;
1244 bfd_size_type i;
1245 bfd_size_type start, stop;
1246 int onaline = 20;
1247
1248 pe_data_type *pe = pe_data (abfd);
1249 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1250
1251 if (section == 0)
1252 return true;
1253
1254 #ifdef POWERPC_LE_PE
1255 if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1256 {
1257 /* The toc address can be found by taking the starting address,
1258 which on the PPC locates a function descriptor. The descriptor
1259 consists of the function code starting address followed by the
1260 address of the toc. The starting address we get from the bfd,
1261 and the descriptor is supposed to be in the .reldata section.
1262 */
1263
1264 bfd_vma loadable_toc_address;
1265 bfd_vma toc_address;
1266 bfd_vma start_address;
1267 bfd_byte *data = 0;
1268 int offset;
1269 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1270 rel_section));
1271 if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1272 return false;
1273
1274 datasize = bfd_section_size (abfd, rel_section);
1275
1276 bfd_get_section_contents (abfd,
1277 rel_section,
1278 (PTR) data, 0,
1279 bfd_section_size (abfd, rel_section));
1280
1281 offset = abfd->start_address - rel_section->vma;
1282
1283 start_address = bfd_get_32(abfd, data+offset);
1284 loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1285 toc_address = loadable_toc_address - 32768;
1286
1287 fprintf(file,
1288 "\nFunction descriptor located at the start address: %04lx\n",
1289 (unsigned long int) (abfd->start_address));
1290 fprintf (file,
1291 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
1292 start_address, loadable_toc_address, toc_address);
1293 }
1294 else
1295 {
1296 fprintf(file,
1297 "\nNo reldata section! Function descriptor not decoded.\n");
1298 }
1299 #endif
1300
1301 fprintf(file,
1302 "\nThe Import Tables (interpreted .idata section contents)\n");
1303 fprintf(file,
1304 " vma: Hint Time Forward DLL First\n");
1305 fprintf(file,
1306 " Table Stamp Chain Name Thunk\n");
1307
1308 if (bfd_section_size (abfd, section) == 0)
1309 return true;
1310
1311 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1312 datasize = bfd_section_size (abfd, section);
1313 if (data == NULL && datasize != 0)
1314 return false;
1315
1316 bfd_get_section_contents (abfd,
1317 section,
1318 (PTR) data, 0,
1319 bfd_section_size (abfd, section));
1320
1321 start = 0;
1322
1323 stop = bfd_section_size (abfd, section);
1324
1325 for (i = start; i < stop; i += onaline)
1326 {
1327 bfd_vma hint_addr;
1328 bfd_vma time_stamp;
1329 bfd_vma forward_chain;
1330 bfd_vma dll_name;
1331 bfd_vma first_thunk;
1332 int idx;
1333 int j;
1334 char *dll;
1335 int adj = (extra->ImageBase - section->vma) & 0xffffffff;
1336
1337 fprintf (file,
1338 " %04lx\t",
1339 (unsigned long int) (i + section->vma));
1340
1341 if (i+20 > stop)
1342 {
1343 /* check stuff */
1344 ;
1345 }
1346
1347 hint_addr = bfd_get_32(abfd, data+i);
1348 time_stamp = bfd_get_32(abfd, data+i+4);
1349 forward_chain = bfd_get_32(abfd, data+i+8);
1350 dll_name = bfd_get_32(abfd, data+i+12);
1351 first_thunk = bfd_get_32(abfd, data+i+16);
1352
1353 fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1354 hint_addr,
1355 time_stamp,
1356 forward_chain,
1357 dll_name,
1358 first_thunk);
1359
1360 if (hint_addr ==0)
1361 {
1362 break;
1363 }
1364
1365 /* the image base is present in the section->vma */
1366 dll = (char *) data + dll_name + adj;
1367 fprintf(file, "\n\tDLL Name: %s\n", dll);
1368 fprintf(file, "\tvma: Ordinal Member-Name\n");
1369
1370 idx = hint_addr + adj;
1371
1372 for (j=0;j<stop;j+=4)
1373 {
1374 int ordinal;
1375 char *member_name;
1376 bfd_vma member = bfd_get_32(abfd, data + idx + j);
1377 if (member == 0)
1378 break;
1379 ordinal = bfd_get_16(abfd,
1380 data + member + adj);
1381 member_name = (char *) data + member + adj + 2;
1382 fprintf(file, "\t%04lx\t %4d %s\n",
1383 member, ordinal, member_name);
1384 }
1385
1386 if (hint_addr != first_thunk)
1387 {
1388 int differ = 0;
1389 int idx2;
1390
1391 idx2 = first_thunk + adj;
1392
1393 for (j=0;j<stop;j+=4)
1394 {
1395 int ordinal;
1396 char *member_name;
1397 bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1398 bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1399 if (hint_member != iat_member)
1400 {
1401 if (differ == 0)
1402 {
1403 fprintf(file,
1404 "\tThe Import Address Table (difference found)\n");
1405 fprintf(file, "\tvma: Ordinal Member-Name\n");
1406 differ = 1;
1407 }
1408 if (iat_member == 0)
1409 {
1410 fprintf(file,
1411 "\t>>> Ran out of IAT members!\n");
1412 }
1413 else
1414 {
1415 ordinal = bfd_get_16(abfd,
1416 data + iat_member + adj);
1417 member_name = (char *) data + iat_member + adj + 2;
1418 fprintf(file, "\t%04lx\t %4d %s\n",
1419 iat_member, ordinal, member_name);
1420 }
1421 break;
1422 }
1423 if (hint_member == 0)
1424 break;
1425 }
1426 if (differ == 0)
1427 {
1428 fprintf(file,
1429 "\tThe Import Address Table is identical\n");
1430 }
1431 }
1432
1433 fprintf(file, "\n");
1434
1435 }
1436
1437 free (data);
1438
1439 return true;
1440 }
1441
1442 static boolean
1443 pe_print_edata (abfd, vfile)
1444 bfd *abfd;
1445 PTR vfile;
1446 {
1447 FILE *file = (FILE *) vfile;
1448 bfd_byte *data = 0;
1449 asection *section = bfd_get_section_by_name (abfd, ".edata");
1450
1451 bfd_size_type datasize = 0;
1452 bfd_size_type i;
1453
1454 int adj;
1455 struct EDT_type
1456 {
1457 long export_flags; /* reserved - should be zero */
1458 long time_stamp;
1459 short major_ver;
1460 short minor_ver;
1461 bfd_vma name; /* rva - relative to image base */
1462 long base; /* ordinal base */
1463 long num_functions; /* Number in the export address table */
1464 long num_names; /* Number in the name pointer table */
1465 bfd_vma eat_addr; /* rva to the export address table */
1466 bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
1467 bfd_vma ot_addr; /* rva to the Ordinal Table */
1468 } edt;
1469
1470 pe_data_type *pe = pe_data (abfd);
1471 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1472
1473 if (section == 0)
1474 return true;
1475
1476 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1477 section));
1478 datasize = bfd_section_size (abfd, section);
1479
1480 if (data == NULL && datasize != 0)
1481 return false;
1482
1483 bfd_get_section_contents (abfd,
1484 section,
1485 (PTR) data, 0,
1486 bfd_section_size (abfd, section));
1487
1488 /* Go get Export Directory Table */
1489 edt.export_flags = bfd_get_32(abfd, data+0);
1490 edt.time_stamp = bfd_get_32(abfd, data+4);
1491 edt.major_ver = bfd_get_16(abfd, data+8);
1492 edt.minor_ver = bfd_get_16(abfd, data+10);
1493 edt.name = bfd_get_32(abfd, data+12);
1494 edt.base = bfd_get_32(abfd, data+16);
1495 edt.num_functions = bfd_get_32(abfd, data+20);
1496 edt.num_names = bfd_get_32(abfd, data+24);
1497 edt.eat_addr = bfd_get_32(abfd, data+28);
1498 edt.npt_addr = bfd_get_32(abfd, data+32);
1499 edt.ot_addr = bfd_get_32(abfd, data+36);
1500
1501 adj = (extra->ImageBase - section->vma) & 0xffffffff;
1502
1503
1504 /* Dump the EDT first first */
1505 fprintf(file,
1506 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1507
1508 fprintf(file,
1509 "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1510
1511 fprintf(file,
1512 "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1513
1514 fprintf(file,
1515 "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1516
1517 fprintf (file,
1518 "Name \t\t\t\t");
1519 fprintf_vma (file, edt.name);
1520 fprintf (file,
1521 " %s\n", data + edt.name + adj);
1522
1523 fprintf(file,
1524 "Ordinal Base \t\t\t%ld\n", edt.base);
1525
1526 fprintf(file,
1527 "Number in:\n");
1528
1529 fprintf(file,
1530 "\tExport Address Table \t\t%lx\n",
1531 (unsigned long) edt.num_functions);
1532
1533 fprintf(file,
1534 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1535
1536 fprintf(file,
1537 "Table Addresses\n");
1538
1539 fprintf (file,
1540 "\tExport Address Table \t\t");
1541 fprintf_vma (file, edt.eat_addr);
1542 fprintf (file, "\n");
1543
1544 fprintf (file,
1545 "\tName Pointer Table \t\t");
1546 fprintf_vma (file, edt.npt_addr);
1547 fprintf (file, "\n");
1548
1549 fprintf (file,
1550 "\tOrdinal Table \t\t\t");
1551 fprintf_vma (file, edt.ot_addr);
1552 fprintf (file, "\n");
1553
1554
1555 /* The next table to find si the Export Address Table. It's basically
1556 a list of pointers that either locate a function in this dll, or
1557 forward the call to another dll. Something like:
1558 typedef union
1559 {
1560 long export_rva;
1561 long forwarder_rva;
1562 } export_address_table_entry;
1563 */
1564
1565 fprintf(file,
1566 "\nExport Address Table -- Ordinal Base %ld\n",
1567 edt.base);
1568
1569 for (i = 0; i < edt.num_functions; ++i)
1570 {
1571 bfd_vma eat_member = bfd_get_32(abfd,
1572 data + edt.eat_addr + (i*4) + adj);
1573 bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff;
1574 bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1575 bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1576
1577
1578 if (eat_member == 0)
1579 continue;
1580
1581 if (edata_start < eat_actual && eat_actual < edata_end)
1582 {
1583 /* this rva is to a name (forwarding function) in our section */
1584 /* Should locate a function descriptor */
1585 fprintf(file,
1586 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1587 (long) i, (long) (i + edt.base), eat_member,
1588 "Forwarder RVA", data + eat_member + adj);
1589 }
1590 else
1591 {
1592 /* Should locate a function descriptor in the reldata section */
1593 fprintf(file,
1594 "\t[%4ld] +base[%4ld] %04lx %s\n",
1595 (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1596 }
1597 }
1598
1599 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1600 /* Dump them in parallel for clarity */
1601 fprintf(file,
1602 "\n[Ordinal/Name Pointer] Table\n");
1603
1604 for (i = 0; i < edt.num_names; ++i)
1605 {
1606 bfd_vma name_ptr = bfd_get_32(abfd,
1607 data +
1608 edt.npt_addr
1609 + (i*4) + adj);
1610
1611 char *name = (char *) data + name_ptr + adj;
1612
1613 bfd_vma ord = bfd_get_16(abfd,
1614 data +
1615 edt.ot_addr
1616 + (i*2) + adj);
1617 fprintf(file,
1618 "\t[%4ld] %s\n", (long) ord, name);
1619
1620 }
1621
1622 free (data);
1623
1624 return true;
1625 }
1626
1627 static boolean
1628 pe_print_pdata (abfd, vfile)
1629 bfd *abfd;
1630 PTR vfile;
1631 {
1632 FILE *file = (FILE *) vfile;
1633 bfd_byte *data = 0;
1634 asection *section = bfd_get_section_by_name (abfd, ".pdata");
1635 bfd_size_type datasize = 0;
1636 bfd_size_type i;
1637 bfd_size_type start, stop;
1638 int onaline = 20;
1639
1640 if (section == 0)
1641 return true;
1642
1643 stop = bfd_section_size (abfd, section);
1644 if ((stop % onaline) != 0)
1645 fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1646 (long)stop, onaline);
1647
1648 fprintf(file,
1649 "\nThe Function Table (interpreted .pdata section contents)\n");
1650 fprintf(file,
1651 " vma:\t\tBegin End EH EH PrologEnd\n");
1652 fprintf(file,
1653 " \t\tAddress Address Handler Data Address\n");
1654
1655 if (bfd_section_size (abfd, section) == 0)
1656 return true;
1657
1658 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1659 datasize = bfd_section_size (abfd, section);
1660 if (data == NULL && datasize != 0)
1661 return false;
1662
1663 bfd_get_section_contents (abfd,
1664 section,
1665 (PTR) data, 0,
1666 bfd_section_size (abfd, section));
1667
1668 start = 0;
1669
1670 for (i = start; i < stop; i += onaline)
1671 {
1672 bfd_vma begin_addr;
1673 bfd_vma end_addr;
1674 bfd_vma eh_handler;
1675 bfd_vma eh_data;
1676 bfd_vma prolog_end_addr;
1677
1678 if (i+20 > stop)
1679 break;
1680
1681 begin_addr = bfd_get_32(abfd, data+i);
1682 end_addr = bfd_get_32(abfd, data+i+4);
1683 eh_handler = bfd_get_32(abfd, data+i+8);
1684 eh_data = bfd_get_32(abfd, data+i+12);
1685 prolog_end_addr = bfd_get_32(abfd, data+i+16);
1686
1687 if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1688 && eh_data == 0 && prolog_end_addr == 0)
1689 {
1690 /* We are probably into the padding of the
1691 section now */
1692 break;
1693 }
1694
1695 fprintf (file,
1696 " %08lx\t",
1697 (unsigned long int) (i + section->vma));
1698
1699 fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1700 begin_addr,
1701 end_addr,
1702 eh_handler,
1703 eh_data,
1704 prolog_end_addr);
1705
1706 #ifdef POWERPC_LE_PE
1707 if (eh_handler == 0 && eh_data != 0)
1708 {
1709 /* Special bits here, although the meaning may */
1710 /* be a little mysterious. The only one I know */
1711 /* for sure is 0x03. */
1712 /* Code Significance */
1713 /* 0x00 None */
1714 /* 0x01 Register Save Millicode */
1715 /* 0x02 Register Restore Millicode */
1716 /* 0x03 Glue Code Sequence */
1717 switch (eh_data)
1718 {
1719 case 0x01:
1720 fprintf(file, " Register save millicode");
1721 break;
1722 case 0x02:
1723 fprintf(file, " Register restore millicode");
1724 break;
1725 case 0x03:
1726 fprintf(file, " Glue code sequence");
1727 break;
1728 default:
1729 break;
1730 }
1731 }
1732 #endif
1733 fprintf(file, "\n");
1734 }
1735
1736 free (data);
1737
1738 return true;
1739 }
1740
1741 static const char *tbl[6] =
1742 {
1743 "ABSOLUTE",
1744 "HIGH",
1745 "LOW",
1746 "HIGHLOW",
1747 "HIGHADJ",
1748 "MIPS_JMPADDR"
1749 };
1750
1751 static boolean
1752 pe_print_reloc (abfd, vfile)
1753 bfd *abfd;
1754 PTR vfile;
1755 {
1756 FILE *file = (FILE *) vfile;
1757 bfd_byte *data = 0;
1758 asection *section = bfd_get_section_by_name (abfd, ".reloc");
1759 bfd_size_type datasize = 0;
1760 bfd_size_type i;
1761 bfd_size_type start, stop;
1762
1763 if (section == 0)
1764 return true;
1765
1766 if (bfd_section_size (abfd, section) == 0)
1767 return true;
1768
1769 fprintf(file,
1770 "\n\nPE File Base Relocations (interpreted .reloc section contents)\n");
1771
1772 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1773 datasize = bfd_section_size (abfd, section);
1774 if (data == NULL && datasize != 0)
1775 return false;
1776
1777 bfd_get_section_contents (abfd,
1778 section,
1779 (PTR) data, 0,
1780 bfd_section_size (abfd, section));
1781
1782 start = 0;
1783
1784 stop = bfd_section_size (abfd, section);
1785
1786 for (i = start; i < stop;)
1787 {
1788 int j;
1789 bfd_vma virtual_address;
1790 long number, size;
1791
1792 /* The .reloc section is a sequence of blocks, with a header consisting
1793 of two 32 bit quantities, followed by a number of 16 bit entries */
1794
1795 virtual_address = bfd_get_32(abfd, data+i);
1796 size = bfd_get_32(abfd, data+i+4);
1797 number = (size - 8) / 2;
1798
1799 if (size == 0)
1800 {
1801 break;
1802 }
1803
1804 fprintf (file,
1805 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1806 virtual_address, size, size, number);
1807
1808 for (j = 0; j < number; ++j)
1809 {
1810 unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1811 int t = (e & 0xF000) >> 12;
1812 int off = e & 0x0FFF;
1813
1814 if (t > 5)
1815 abort();
1816
1817 fprintf(file,
1818 "\treloc %4d offset %4x [%4lx] %s\n",
1819 j, off, (long) (off + virtual_address), tbl[t]);
1820
1821 }
1822 i += size;
1823 }
1824
1825 free (data);
1826
1827 return true;
1828 }
1829
1830 static boolean
1831 pe_print_private_bfd_data (abfd, vfile)
1832 bfd *abfd;
1833 PTR vfile;
1834 {
1835 FILE *file = (FILE *) vfile;
1836 int j;
1837 pe_data_type *pe = pe_data (abfd);
1838 struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1839
1840 fprintf (file,"\nImageBase\t\t");
1841 fprintf_vma (file, i->ImageBase);
1842 fprintf (file,"\nSectionAlignment\t");
1843 fprintf_vma (file, i->SectionAlignment);
1844 fprintf (file,"\nFileAlignment\t\t");
1845 fprintf_vma (file, i->FileAlignment);
1846 fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1847 fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1848 fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1849 fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1850 fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1851 fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1852 fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1853 fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1854 fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1855 fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1856 fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1857 fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1858 fprintf (file,"SizeOfStackReserve\t");
1859 fprintf_vma (file, i->SizeOfStackReserve);
1860 fprintf (file,"\nSizeOfStackCommit\t");
1861 fprintf_vma (file, i->SizeOfStackCommit);
1862 fprintf (file,"\nSizeOfHeapReserve\t");
1863 fprintf_vma (file, i->SizeOfHeapReserve);
1864 fprintf (file,"\nSizeOfHeapCommit\t");
1865 fprintf_vma (file, i->SizeOfHeapCommit);
1866 fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1867 fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1868
1869 fprintf (file,"\nThe Data Directory\n");
1870 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1871 {
1872 fprintf (file, "Entry %1x ", j);
1873 fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1874 fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1875 fprintf (file, "%s\n", dir_names[j]);
1876 }
1877
1878 pe_print_idata(abfd, vfile);
1879 pe_print_edata(abfd, vfile);
1880 pe_print_pdata(abfd, vfile);
1881 pe_print_reloc(abfd, vfile);
1882
1883 return true;
1884 }
1885
1886 static boolean
1887 pe_mkobject (abfd)
1888 bfd * abfd;
1889 {
1890 pe_data_type *pe;
1891 abfd->tdata.pe_obj_data =
1892 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1893
1894 if (abfd->tdata.pe_obj_data == 0)
1895 return false;
1896
1897 pe = pe_data (abfd);
1898
1899 pe->coff.pe = 1;
1900 pe->in_reloc_p = in_reloc_p;
1901 return true;
1902 }
1903
1904 /* Create the COFF backend specific information. */
1905 static PTR
1906 pe_mkobject_hook (abfd, filehdr, aouthdr)
1907 bfd * abfd;
1908 PTR filehdr;
1909 PTR aouthdr;
1910 {
1911 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1912 pe_data_type *pe;
1913
1914 if (pe_mkobject (abfd) == false)
1915 return NULL;
1916
1917 pe = pe_data (abfd);
1918 pe->coff.sym_filepos = internal_f->f_symptr;
1919 /* These members communicate important constants about the symbol
1920 table to GDB's symbol-reading code. These `constants'
1921 unfortunately vary among coff implementations... */
1922 pe->coff.local_n_btmask = N_BTMASK;
1923 pe->coff.local_n_btshft = N_BTSHFT;
1924 pe->coff.local_n_tmask = N_TMASK;
1925 pe->coff.local_n_tshift = N_TSHIFT;
1926 pe->coff.local_symesz = SYMESZ;
1927 pe->coff.local_auxesz = AUXESZ;
1928 pe->coff.local_linesz = LINESZ;
1929
1930 obj_raw_syment_count (abfd) =
1931 obj_conv_table_size (abfd) =
1932 internal_f->f_nsyms;
1933
1934 pe->real_flags = internal_f->f_flags;
1935
1936 if ((internal_f->f_flags & F_DLL) != 0)
1937 pe->dll = 1;
1938
1939 #ifdef COFF_IMAGE_WITH_PE
1940 if (aouthdr)
1941 {
1942 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1943 }
1944 #endif
1945
1946 return (PTR) pe;
1947 }
1948
1949
1950
1951 /* Copy any private info we understand from the input bfd
1952 to the output bfd. */
1953
1954 #undef coff_bfd_copy_private_bfd_data
1955 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1956
1957 static boolean
1958 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1959 bfd *ibfd, *obfd;
1960 {
1961 /* One day we may try to grok other private data. */
1962 if (ibfd->xvec->flavour != bfd_target_coff_flavour
1963 || obfd->xvec->flavour != bfd_target_coff_flavour)
1964 return true;
1965
1966 pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1967 pe_data (obfd)->dll = pe_data (ibfd)->dll;
1968
1969 return true;
1970 }
1971
1972 #ifdef COFF_IMAGE_WITH_PE
1973
1974 /* Copy private section data. */
1975
1976 #define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
1977
1978 static boolean pe_bfd_copy_private_section_data
1979 PARAMS ((bfd *, asection *, bfd *, asection *));
1980
1981 static boolean
1982 pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
1983 bfd *ibfd;
1984 asection *isec;
1985 bfd *obfd;
1986 asection *osec;
1987 {
1988 if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
1989 || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
1990 return true;
1991
1992 if (coff_section_data (ibfd, isec) != NULL
1993 && pei_section_data (ibfd, isec) != NULL)
1994 {
1995 if (coff_section_data (obfd, osec) == NULL)
1996 {
1997 osec->used_by_bfd =
1998 (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
1999 if (osec->used_by_bfd == NULL)
2000 return false;
2001 }
2002 if (pei_section_data (obfd, osec) == NULL)
2003 {
2004 coff_section_data (obfd, osec)->tdata =
2005 (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
2006 if (coff_section_data (obfd, osec)->tdata == NULL)
2007 return false;
2008 }
2009 pei_section_data (obfd, osec)->virt_size =
2010 pei_section_data (ibfd, isec)->virt_size;
2011 }
2012
2013 return true;
2014 }
2015
2016 #endif