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