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