1 /* Support for the generic parts of most COFF variants, for BFD.
2 Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
22 Most of this hacked by Steve Chamberlain,
26 /* Hey look, some documentation [and in a place you expect to find it]!
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.
33 "Peering Inside the PE: A Tour of the Win32 Portable Executable
34 File Format", MSJ 1994, Volume 9.
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
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.
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.
55 #undef coff_bfd_print_private_bfd_data
56 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
57 #define coff_mkobject pe_mkobject
58 #define coff_mkobject_hook pe_mkobject_hook
60 #ifndef GET_FCN_LNNOPTR
61 #define GET_FCN_LNNOPTR(abfd, ext) \
62 bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
65 #ifndef GET_FCN_ENDNDX
66 #define GET_FCN_ENDNDX(abfd, ext) \
67 bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
70 #ifndef PUT_FCN_LNNOPTR
71 #define PUT_FCN_LNNOPTR(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
73 #ifndef PUT_FCN_ENDNDX
74 #define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
77 #define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
80 #define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
83 #define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno)
86 #define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
88 #ifndef GET_SCN_SCNLEN
89 #define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
91 #ifndef GET_SCN_NRELOC
92 #define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
94 #ifndef GET_SCN_NLINNO
95 #define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
97 #ifndef PUT_SCN_SCNLEN
98 #define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
100 #ifndef PUT_SCN_NRELOC
101 #define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
103 #ifndef PUT_SCN_NLINNO
104 #define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
106 #ifndef GET_LINENO_LNNO
107 #define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
109 #ifndef PUT_LINENO_LNNO
110 #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
113 /* The f_symptr field in the filehdr is sometimes 64 bits. */
114 #ifndef GET_FILEHDR_SYMPTR
115 #define GET_FILEHDR_SYMPTR bfd_h_get_32
117 #ifndef PUT_FILEHDR_SYMPTR
118 #define PUT_FILEHDR_SYMPTR bfd_h_put_32
121 /* Some fields in the aouthdr are sometimes 64 bits. */
122 #ifndef GET_AOUTHDR_TSIZE
123 #define GET_AOUTHDR_TSIZE bfd_h_get_32
125 #ifndef PUT_AOUTHDR_TSIZE
126 #define PUT_AOUTHDR_TSIZE bfd_h_put_32
128 #ifndef GET_AOUTHDR_DSIZE
129 #define GET_AOUTHDR_DSIZE bfd_h_get_32
131 #ifndef PUT_AOUTHDR_DSIZE
132 #define PUT_AOUTHDR_DSIZE bfd_h_put_32
134 #ifndef GET_AOUTHDR_BSIZE
135 #define GET_AOUTHDR_BSIZE bfd_h_get_32
137 #ifndef PUT_AOUTHDR_BSIZE
138 #define PUT_AOUTHDR_BSIZE bfd_h_put_32
140 #ifndef GET_AOUTHDR_ENTRY
141 #define GET_AOUTHDR_ENTRY bfd_h_get_32
143 #ifndef PUT_AOUTHDR_ENTRY
144 #define PUT_AOUTHDR_ENTRY bfd_h_put_32
146 #ifndef GET_AOUTHDR_TEXT_START
147 #define GET_AOUTHDR_TEXT_START bfd_h_get_32
149 #ifndef PUT_AOUTHDR_TEXT_START
150 #define PUT_AOUTHDR_TEXT_START bfd_h_put_32
152 #ifndef GET_AOUTHDR_DATA_START
153 #define GET_AOUTHDR_DATA_START bfd_h_get_32
155 #ifndef PUT_AOUTHDR_DATA_START
156 #define PUT_AOUTHDR_DATA_START bfd_h_put_32
159 /* Some fields in the scnhdr are sometimes 64 bits. */
160 #ifndef GET_SCNHDR_PADDR
161 #define GET_SCNHDR_PADDR bfd_h_get_32
163 #ifndef PUT_SCNHDR_PADDR
164 #define PUT_SCNHDR_PADDR bfd_h_put_32
166 #ifndef GET_SCNHDR_VADDR
167 #define GET_SCNHDR_VADDR bfd_h_get_32
169 #ifndef PUT_SCNHDR_VADDR
170 #define PUT_SCNHDR_VADDR bfd_h_put_32
172 #ifndef GET_SCNHDR_SIZE
173 #define GET_SCNHDR_SIZE bfd_h_get_32
175 #ifndef PUT_SCNHDR_SIZE
176 #define PUT_SCNHDR_SIZE bfd_h_put_32
178 #ifndef GET_SCNHDR_SCNPTR
179 #define GET_SCNHDR_SCNPTR bfd_h_get_32
181 #ifndef PUT_SCNHDR_SCNPTR
182 #define PUT_SCNHDR_SCNPTR bfd_h_put_32
184 #ifndef GET_SCNHDR_RELPTR
185 #define GET_SCNHDR_RELPTR bfd_h_get_32
187 #ifndef PUT_SCNHDR_RELPTR
188 #define PUT_SCNHDR_RELPTR bfd_h_put_32
190 #ifndef GET_SCNHDR_LNNOPTR
191 #define GET_SCNHDR_LNNOPTR bfd_h_get_32
193 #ifndef PUT_SCNHDR_LNNOPTR
194 #define PUT_SCNHDR_LNNOPTR bfd_h_put_32
197 static void coff_swap_reloc_in
PARAMS ((bfd
*, PTR
, PTR
));
198 static unsigned int coff_swap_reloc_out
PARAMS ((bfd
*, PTR
, PTR
));
199 static void coff_swap_filehdr_in
PARAMS ((bfd
*, PTR
, PTR
));
200 static unsigned int coff_swap_filehdr_out
PARAMS ((bfd
*, PTR
, PTR
));
201 static void coff_swap_sym_in
PARAMS ((bfd
*, PTR
, PTR
));
202 static unsigned int coff_swap_sym_out
PARAMS ((bfd
*, PTR
, PTR
));
203 static void coff_swap_aux_in
PARAMS ((bfd
*, PTR
, int, int, int, int, PTR
));
204 static unsigned int coff_swap_aux_out
205 PARAMS ((bfd
*, PTR
, int, int, int, int, PTR
));
206 static void coff_swap_lineno_in
PARAMS ((bfd
*, PTR
, PTR
));
207 static unsigned int coff_swap_lineno_out
PARAMS ((bfd
*, PTR
, PTR
));
208 static void coff_swap_aouthdr_in
PARAMS ((bfd
*, PTR
, PTR
));
209 static void add_data_entry
210 PARAMS ((bfd
*, struct internal_extra_pe_aouthdr
*, int, char *, bfd_vma
));
211 static unsigned int coff_swap_aouthdr_out
PARAMS ((bfd
*, PTR
, PTR
));
212 static void coff_swap_scnhdr_in
PARAMS ((bfd
*, PTR
, PTR
));
213 static unsigned int coff_swap_scnhdr_out
PARAMS ((bfd
*, PTR
, PTR
));
214 static boolean pe_print_idata
PARAMS ((bfd
*, PTR
));
215 static boolean pe_print_edata
PARAMS ((bfd
*, PTR
));
216 static boolean pe_print_pdata
PARAMS ((bfd
*, PTR
));
217 static boolean pe_print_reloc
PARAMS ((bfd
*, PTR
));
218 static boolean pe_print_private_bfd_data
PARAMS ((bfd
*, PTR
));
219 static boolean pe_mkobject
PARAMS ((bfd
*));
220 static PTR pe_mkobject_hook
PARAMS ((bfd
*, PTR
, PTR
));
221 static boolean pe_bfd_copy_private_bfd_data
PARAMS ((bfd
*, bfd
*));
223 /**********************************************************************/
226 coff_swap_reloc_in (abfd
, src
, dst
)
231 RELOC
*reloc_src
= (RELOC
*) src
;
232 struct internal_reloc
*reloc_dst
= (struct internal_reloc
*) dst
;
234 reloc_dst
->r_vaddr
= bfd_h_get_32(abfd
, (bfd_byte
*)reloc_src
->r_vaddr
);
235 reloc_dst
->r_symndx
= bfd_h_get_signed_32(abfd
, (bfd_byte
*) reloc_src
->r_symndx
);
237 reloc_dst
->r_type
= bfd_h_get_16(abfd
, (bfd_byte
*) reloc_src
->r_type
);
239 #ifdef SWAP_IN_RELOC_OFFSET
240 reloc_dst
->r_offset
= SWAP_IN_RELOC_OFFSET(abfd
,
241 (bfd_byte
*) reloc_src
->r_offset
);
247 coff_swap_reloc_out (abfd
, src
, dst
)
252 struct internal_reloc
*reloc_src
= (struct internal_reloc
*)src
;
253 struct external_reloc
*reloc_dst
= (struct external_reloc
*)dst
;
254 bfd_h_put_32(abfd
, reloc_src
->r_vaddr
, (bfd_byte
*) reloc_dst
->r_vaddr
);
255 bfd_h_put_32(abfd
, reloc_src
->r_symndx
, (bfd_byte
*) reloc_dst
->r_symndx
);
257 bfd_h_put_16(abfd
, reloc_src
->r_type
, (bfd_byte
*)
260 #ifdef SWAP_OUT_RELOC_OFFSET
261 SWAP_OUT_RELOC_OFFSET(abfd
,
263 (bfd_byte
*) reloc_dst
->r_offset
);
265 #ifdef SWAP_OUT_RELOC_EXTRA
266 SWAP_OUT_RELOC_EXTRA(abfd
,reloc_src
, reloc_dst
);
273 coff_swap_filehdr_in (abfd
, src
, dst
)
278 FILHDR
*filehdr_src
= (FILHDR
*) src
;
279 struct internal_filehdr
*filehdr_dst
= (struct internal_filehdr
*) dst
;
280 filehdr_dst
->f_magic
= bfd_h_get_16(abfd
, (bfd_byte
*) filehdr_src
->f_magic
);
281 filehdr_dst
->f_nscns
= bfd_h_get_16(abfd
, (bfd_byte
*)filehdr_src
-> f_nscns
);
282 filehdr_dst
->f_timdat
= bfd_h_get_32(abfd
, (bfd_byte
*)filehdr_src
-> f_timdat
);
284 filehdr_dst
->f_nsyms
= bfd_h_get_32(abfd
, (bfd_byte
*)filehdr_src
-> f_nsyms
);
285 filehdr_dst
->f_flags
= bfd_h_get_16(abfd
, (bfd_byte
*)filehdr_src
-> f_flags
);
286 filehdr_dst
->f_symptr
= bfd_h_get_32 (abfd
, (bfd_byte
*) filehdr_src
->f_symptr
);
288 /* Other people's tools sometimes generate headers
289 with an nsyms but a zero symptr. */
290 if (filehdr_dst
->f_nsyms
&& filehdr_dst
->f_symptr
)
292 filehdr_dst
->f_flags
|= HAS_SYMS
;
296 filehdr_dst
->f_nsyms
= 0;
297 filehdr_dst
->f_flags
&= ~HAS_SYMS
;
300 filehdr_dst
->f_opthdr
= bfd_h_get_16(abfd
,
301 (bfd_byte
*)filehdr_src
-> f_opthdr
);
304 #ifdef COFF_IMAGE_WITH_PE
307 coff_swap_filehdr_out (abfd
, in
, out
)
313 struct internal_filehdr
*filehdr_in
= (struct internal_filehdr
*)in
;
314 FILHDR
*filehdr_out
= (FILHDR
*)out
;
316 if (pe_data (abfd
)->has_reloc_section
)
317 filehdr_in
->f_flags
&= ~F_RELFLG
;
319 if (pe_data (abfd
)->dll
)
320 filehdr_in
->f_flags
|= F_DLL
;
322 filehdr_in
->pe
.e_magic
= DOSMAGIC
;
323 filehdr_in
->pe
.e_cblp
= 0x90;
324 filehdr_in
->pe
.e_cp
= 0x3;
325 filehdr_in
->pe
.e_crlc
= 0x0;
326 filehdr_in
->pe
.e_cparhdr
= 0x4;
327 filehdr_in
->pe
.e_minalloc
= 0x0;
328 filehdr_in
->pe
.e_maxalloc
= 0xffff;
329 filehdr_in
->pe
.e_ss
= 0x0;
330 filehdr_in
->pe
.e_sp
= 0xb8;
331 filehdr_in
->pe
.e_csum
= 0x0;
332 filehdr_in
->pe
.e_ip
= 0x0;
333 filehdr_in
->pe
.e_cs
= 0x0;
334 filehdr_in
->pe
.e_lfarlc
= 0x40;
335 filehdr_in
->pe
.e_ovno
= 0x0;
337 for (idx
=0; idx
< 4; idx
++)
338 filehdr_in
->pe
.e_res
[idx
] = 0x0;
340 filehdr_in
->pe
.e_oemid
= 0x0;
341 filehdr_in
->pe
.e_oeminfo
= 0x0;
343 for (idx
=0; idx
< 10; idx
++)
344 filehdr_in
->pe
.e_res2
[idx
] = 0x0;
346 filehdr_in
->pe
.e_lfanew
= 0x80;
348 /* this next collection of data are mostly just characters. It appears
349 to be constant within the headers put on NT exes */
350 filehdr_in
->pe
.dos_message
[0] = 0x0eba1f0e;
351 filehdr_in
->pe
.dos_message
[1] = 0xcd09b400;
352 filehdr_in
->pe
.dos_message
[2] = 0x4c01b821;
353 filehdr_in
->pe
.dos_message
[3] = 0x685421cd;
354 filehdr_in
->pe
.dos_message
[4] = 0x70207369;
355 filehdr_in
->pe
.dos_message
[5] = 0x72676f72;
356 filehdr_in
->pe
.dos_message
[6] = 0x63206d61;
357 filehdr_in
->pe
.dos_message
[7] = 0x6f6e6e61;
358 filehdr_in
->pe
.dos_message
[8] = 0x65622074;
359 filehdr_in
->pe
.dos_message
[9] = 0x6e757220;
360 filehdr_in
->pe
.dos_message
[10] = 0x206e6920;
361 filehdr_in
->pe
.dos_message
[11] = 0x20534f44;
362 filehdr_in
->pe
.dos_message
[12] = 0x65646f6d;
363 filehdr_in
->pe
.dos_message
[13] = 0x0a0d0d2e;
364 filehdr_in
->pe
.dos_message
[14] = 0x24;
365 filehdr_in
->pe
.dos_message
[15] = 0x0;
366 filehdr_in
->pe
.nt_signature
= NT_SIGNATURE
;
370 bfd_h_put_16(abfd
, filehdr_in
->f_magic
, (bfd_byte
*) filehdr_out
->f_magic
);
371 bfd_h_put_16(abfd
, filehdr_in
->f_nscns
, (bfd_byte
*) filehdr_out
->f_nscns
);
373 bfd_h_put_32(abfd
, time (0), (bfd_byte
*) filehdr_out
->f_timdat
);
374 PUT_FILEHDR_SYMPTR (abfd
, (bfd_vma
) filehdr_in
->f_symptr
,
375 (bfd_byte
*) filehdr_out
->f_symptr
);
376 bfd_h_put_32(abfd
, filehdr_in
->f_nsyms
, (bfd_byte
*) filehdr_out
->f_nsyms
);
377 bfd_h_put_16(abfd
, filehdr_in
->f_opthdr
, (bfd_byte
*) filehdr_out
->f_opthdr
);
378 bfd_h_put_16(abfd
, filehdr_in
->f_flags
, (bfd_byte
*) filehdr_out
->f_flags
);
380 /* put in extra dos header stuff. This data remains essentially
381 constant, it just has to be tacked on to the beginning of all exes
383 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_magic
, (bfd_byte
*) filehdr_out
->e_magic
);
384 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_cblp
, (bfd_byte
*) filehdr_out
->e_cblp
);
385 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_cp
, (bfd_byte
*) filehdr_out
->e_cp
);
386 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_crlc
, (bfd_byte
*) filehdr_out
->e_crlc
);
387 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_cparhdr
,
388 (bfd_byte
*) filehdr_out
->e_cparhdr
);
389 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_minalloc
,
390 (bfd_byte
*) filehdr_out
->e_minalloc
);
391 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_maxalloc
,
392 (bfd_byte
*) filehdr_out
->e_maxalloc
);
393 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_ss
, (bfd_byte
*) filehdr_out
->e_ss
);
394 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_sp
, (bfd_byte
*) filehdr_out
->e_sp
);
395 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_csum
, (bfd_byte
*) filehdr_out
->e_csum
);
396 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_ip
, (bfd_byte
*) filehdr_out
->e_ip
);
397 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_cs
, (bfd_byte
*) filehdr_out
->e_cs
);
398 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_lfarlc
, (bfd_byte
*) filehdr_out
->e_lfarlc
);
399 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_ovno
, (bfd_byte
*) filehdr_out
->e_ovno
);
402 for (idx
=0; idx
< 4; idx
++)
403 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_res
[idx
],
404 (bfd_byte
*) filehdr_out
->e_res
[idx
]);
406 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_oemid
, (bfd_byte
*) filehdr_out
->e_oemid
);
407 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_oeminfo
,
408 (bfd_byte
*) filehdr_out
->e_oeminfo
);
411 for (idx
=0; idx
< 10; idx
++)
412 bfd_h_put_16(abfd
, filehdr_in
->pe
.e_res2
[idx
],
413 (bfd_byte
*) filehdr_out
->e_res2
[idx
]);
415 bfd_h_put_32(abfd
, filehdr_in
->pe
.e_lfanew
, (bfd_byte
*) filehdr_out
->e_lfanew
);
419 for (idx
=0; idx
< 16; idx
++)
420 bfd_h_put_32(abfd
, filehdr_in
->pe
.dos_message
[idx
],
421 (bfd_byte
*) filehdr_out
->dos_message
[idx
]);
424 /* also put in the NT signature */
425 bfd_h_put_32(abfd
, filehdr_in
->pe
.nt_signature
,
426 (bfd_byte
*) filehdr_out
->nt_signature
);
436 coff_swap_filehdr_out (abfd
, in
, out
)
441 struct internal_filehdr
*filehdr_in
= (struct internal_filehdr
*)in
;
442 FILHDR
*filehdr_out
= (FILHDR
*)out
;
444 bfd_h_put_16(abfd
, filehdr_in
->f_magic
, (bfd_byte
*) filehdr_out
->f_magic
);
445 bfd_h_put_16(abfd
, filehdr_in
->f_nscns
, (bfd_byte
*) filehdr_out
->f_nscns
);
446 bfd_h_put_32(abfd
, filehdr_in
->f_timdat
, (bfd_byte
*) filehdr_out
->f_timdat
);
447 PUT_FILEHDR_SYMPTR (abfd
, (bfd_vma
) filehdr_in
->f_symptr
,
448 (bfd_byte
*) filehdr_out
->f_symptr
);
449 bfd_h_put_32(abfd
, filehdr_in
->f_nsyms
, (bfd_byte
*) filehdr_out
->f_nsyms
);
450 bfd_h_put_16(abfd
, filehdr_in
->f_opthdr
, (bfd_byte
*) filehdr_out
->f_opthdr
);
451 bfd_h_put_16(abfd
, filehdr_in
->f_flags
, (bfd_byte
*) filehdr_out
->f_flags
);
460 coff_swap_sym_in (abfd
, ext1
, in1
)
465 SYMENT
*ext
= (SYMENT
*)ext1
;
466 struct internal_syment
*in
= (struct internal_syment
*)in1
;
468 if( ext
->e
.e_name
[0] == 0) {
469 in
->_n
._n_n
._n_zeroes
= 0;
470 in
->_n
._n_n
._n_offset
= bfd_h_get_32(abfd
, (bfd_byte
*) ext
->e
.e
.e_offset
);
473 #if SYMNMLEN != E_SYMNMLEN
474 -> Error
, we need to cope with truncating
or extending SYMNMLEN
!;
476 memcpy(in
->_n
._n_name
, ext
->e
.e_name
, SYMNMLEN
);
480 in
->n_value
= bfd_h_get_32(abfd
, (bfd_byte
*) ext
->e_value
);
481 in
->n_scnum
= bfd_h_get_16(abfd
, (bfd_byte
*) ext
->e_scnum
);
482 if (sizeof(ext
->e_type
) == 2){
483 in
->n_type
= bfd_h_get_16(abfd
, (bfd_byte
*) ext
->e_type
);
486 in
->n_type
= bfd_h_get_32(abfd
, (bfd_byte
*) ext
->e_type
);
488 in
->n_sclass
= bfd_h_get_8(abfd
, ext
->e_sclass
);
489 in
->n_numaux
= bfd_h_get_8(abfd
, ext
->e_numaux
);
491 /* The section symbols for the .idata$ sections have class 68, which MS
492 documentation indicates is a section symbol. The problem is that the
493 value field in the symbol is simply a copy of the .idata section's flags
494 rather than something useful. When these symbols are encountered, change
495 the value to 0 and the section number to 1 so that they will be handled
496 somewhat correctly in the bfd code. */
497 if (in
->n_sclass
== 0x68) {
500 /* I have tried setting the class to 3 and using the following to set
501 the section number. This will put the address of the pointer to the
502 string kernel32.dll at addresses 0 and 0x10 off start of idata section
503 which is not correct */
504 /* if (strcmp (in->_n._n_name, ".idata$4") == 0) */
505 /* in->n_scnum = 3; */
507 /* in->n_scnum = 2; */
510 #ifdef coff_swap_sym_in_hook
511 coff_swap_sym_in_hook(abfd
, ext1
, in1
);
516 coff_swap_sym_out (abfd
, inp
, extp
)
521 struct internal_syment
*in
= (struct internal_syment
*)inp
;
522 SYMENT
*ext
=(SYMENT
*)extp
;
523 if(in
->_n
._n_name
[0] == 0) {
524 bfd_h_put_32(abfd
, 0, (bfd_byte
*) ext
->e
.e
.e_zeroes
);
525 bfd_h_put_32(abfd
, in
->_n
._n_n
._n_offset
, (bfd_byte
*) ext
->e
.e
.e_offset
);
528 #if SYMNMLEN != E_SYMNMLEN
529 -> Error
, we need to cope with truncating
or extending SYMNMLEN
!;
531 memcpy(ext
->e
.e_name
, in
->_n
._n_name
, SYMNMLEN
);
535 bfd_h_put_32(abfd
, in
->n_value
, (bfd_byte
*) ext
->e_value
);
536 bfd_h_put_16(abfd
, in
->n_scnum
, (bfd_byte
*) ext
->e_scnum
);
537 if (sizeof(ext
->e_type
) == 2)
539 bfd_h_put_16(abfd
, in
->n_type
, (bfd_byte
*) ext
->e_type
);
543 bfd_h_put_32(abfd
, in
->n_type
, (bfd_byte
*) ext
->e_type
);
545 bfd_h_put_8(abfd
, in
->n_sclass
, ext
->e_sclass
);
546 bfd_h_put_8(abfd
, in
->n_numaux
, ext
->e_numaux
);
552 coff_swap_aux_in (abfd
, ext1
, type
, class, indx
, numaux
, in1
)
561 AUXENT
*ext
= (AUXENT
*)ext1
;
562 union internal_auxent
*in
= (union internal_auxent
*)in1
;
566 if (ext
->x_file
.x_fname
[0] == 0) {
567 in
->x_file
.x_n
.x_zeroes
= 0;
568 in
->x_file
.x_n
.x_offset
=
569 bfd_h_get_32(abfd
, (bfd_byte
*) ext
->x_file
.x_n
.x_offset
);
571 #if FILNMLEN != E_FILNMLEN
572 -> Error
, we need to cope with truncating
or extending FILNMLEN
!;
574 memcpy (in
->x_file
.x_fname
, ext
->x_file
.x_fname
, FILNMLEN
);
585 if (type
== T_NULL
) {
586 in
->x_scn
.x_scnlen
= GET_SCN_SCNLEN(abfd
, ext
);
587 in
->x_scn
.x_nreloc
= GET_SCN_NRELOC(abfd
, ext
);
588 in
->x_scn
.x_nlinno
= GET_SCN_NLINNO(abfd
, ext
);
589 in
->x_scn
.x_checksum
= bfd_h_get_32 (abfd
,
590 (bfd_byte
*) ext
->x_scn
.x_checksum
);
591 in
->x_scn
.x_associated
=
592 bfd_h_get_16 (abfd
, (bfd_byte
*) ext
->x_scn
.x_associated
);
593 in
->x_scn
.x_comdat
= bfd_h_get_8 (abfd
,
594 (bfd_byte
*) ext
->x_scn
.x_comdat
);
600 in
->x_sym
.x_tagndx
.l
= bfd_h_get_32(abfd
, (bfd_byte
*) ext
->x_sym
.x_tagndx
);
602 in
->x_sym
.x_tvndx
= bfd_h_get_16(abfd
, (bfd_byte
*) ext
->x_sym
.x_tvndx
);
605 if (class == C_BLOCK
|| class == C_FCN
|| ISFCN (type
) || ISTAG (class))
607 in
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
= GET_FCN_LNNOPTR (abfd
, ext
);
608 in
->x_sym
.x_fcnary
.x_fcn
.x_endndx
.l
= GET_FCN_ENDNDX (abfd
, ext
);
612 #if DIMNUM != E_DIMNUM
613 #error we need to cope with truncating or extending DIMNUM
615 in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[0] =
616 bfd_h_get_16 (abfd
, (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[0]);
617 in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[1] =
618 bfd_h_get_16 (abfd
, (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[1]);
619 in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[2] =
620 bfd_h_get_16 (abfd
, (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[2]);
621 in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[3] =
622 bfd_h_get_16 (abfd
, (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[3]);
626 in
->x_sym
.x_misc
.x_fsize
= bfd_h_get_32(abfd
, (bfd_byte
*) ext
->x_sym
.x_misc
.x_fsize
);
629 in
->x_sym
.x_misc
.x_lnsz
.x_lnno
= GET_LNSZ_LNNO(abfd
, ext
);
630 in
->x_sym
.x_misc
.x_lnsz
.x_size
= GET_LNSZ_SIZE(abfd
, ext
);
635 coff_swap_aux_out (abfd
, inp
, type
, class, indx
, numaux
, extp
)
644 union internal_auxent
*in
= (union internal_auxent
*)inp
;
645 AUXENT
*ext
= (AUXENT
*)extp
;
647 memset((PTR
)ext
, 0, AUXESZ
);
650 if (in
->x_file
.x_fname
[0] == 0) {
651 bfd_h_put_32(abfd
, 0, (bfd_byte
*) ext
->x_file
.x_n
.x_zeroes
);
653 in
->x_file
.x_n
.x_offset
,
654 (bfd_byte
*) ext
->x_file
.x_n
.x_offset
);
657 #if FILNMLEN != E_FILNMLEN
658 -> Error
, we need to cope with truncating
or extending FILNMLEN
!;
660 memcpy (ext
->x_file
.x_fname
, in
->x_file
.x_fname
, FILNMLEN
);
671 if (type
== T_NULL
) {
672 PUT_SCN_SCNLEN(abfd
, in
->x_scn
.x_scnlen
, ext
);
673 PUT_SCN_NRELOC(abfd
, in
->x_scn
.x_nreloc
, ext
);
674 PUT_SCN_NLINNO(abfd
, in
->x_scn
.x_nlinno
, ext
);
675 bfd_h_put_32 (abfd
, in
->x_scn
.x_checksum
,
676 (bfd_byte
*) ext
->x_scn
.x_checksum
);
677 bfd_h_put_16 (abfd
, in
->x_scn
.x_associated
,
678 (bfd_byte
*) ext
->x_scn
.x_associated
);
679 bfd_h_put_8 (abfd
, in
->x_scn
.x_comdat
,
680 (bfd_byte
*) ext
->x_scn
.x_comdat
);
686 bfd_h_put_32(abfd
, in
->x_sym
.x_tagndx
.l
, (bfd_byte
*) ext
->x_sym
.x_tagndx
);
688 bfd_h_put_16(abfd
, in
->x_sym
.x_tvndx
, (bfd_byte
*) ext
->x_sym
.x_tvndx
);
691 if (class == C_BLOCK
|| class == C_FCN
|| ISFCN (type
) || ISTAG (class))
693 PUT_FCN_LNNOPTR(abfd
, in
->x_sym
.x_fcnary
.x_fcn
.x_lnnoptr
, ext
);
694 PUT_FCN_ENDNDX(abfd
, in
->x_sym
.x_fcnary
.x_fcn
.x_endndx
.l
, ext
);
698 #if DIMNUM != E_DIMNUM
699 #error we need to cope with truncating or extending DIMNUM
701 bfd_h_put_16 (abfd
, in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[0],
702 (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[0]);
703 bfd_h_put_16 (abfd
, in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[1],
704 (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[1]);
705 bfd_h_put_16 (abfd
, in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[2],
706 (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[2]);
707 bfd_h_put_16 (abfd
, in
->x_sym
.x_fcnary
.x_ary
.x_dimen
[3],
708 (bfd_byte
*) ext
->x_sym
.x_fcnary
.x_ary
.x_dimen
[3]);
712 bfd_h_put_32 (abfd
, in
->x_sym
.x_misc
.x_fsize
,
713 (bfd_byte
*) ext
->x_sym
.x_misc
.x_fsize
);
716 PUT_LNSZ_LNNO (abfd
, in
->x_sym
.x_misc
.x_lnsz
.x_lnno
, ext
);
717 PUT_LNSZ_SIZE (abfd
, in
->x_sym
.x_misc
.x_lnsz
.x_size
, ext
);
725 coff_swap_lineno_in (abfd
, ext1
, in1
)
730 LINENO
*ext
= (LINENO
*)ext1
;
731 struct internal_lineno
*in
= (struct internal_lineno
*)in1
;
733 in
->l_addr
.l_symndx
= bfd_h_get_32(abfd
, (bfd_byte
*) ext
->l_addr
.l_symndx
);
734 in
->l_lnno
= GET_LINENO_LNNO(abfd
, ext
);
738 coff_swap_lineno_out (abfd
, inp
, outp
)
743 struct internal_lineno
*in
= (struct internal_lineno
*)inp
;
744 struct external_lineno
*ext
= (struct external_lineno
*)outp
;
745 bfd_h_put_32(abfd
, in
->l_addr
.l_symndx
, (bfd_byte
*)
746 ext
->l_addr
.l_symndx
);
748 PUT_LINENO_LNNO (abfd
, in
->l_lnno
, ext
);
755 coff_swap_aouthdr_in (abfd
, aouthdr_ext1
, aouthdr_int1
)
760 struct internal_extra_pe_aouthdr
*a
;
761 PEAOUTHDR
*src
= (PEAOUTHDR
*)(aouthdr_ext1
);
762 AOUTHDR
*aouthdr_ext
= (AOUTHDR
*) aouthdr_ext1
;
763 struct internal_aouthdr
*aouthdr_int
= (struct internal_aouthdr
*)aouthdr_int1
;
765 aouthdr_int
->magic
= bfd_h_get_16(abfd
, (bfd_byte
*) aouthdr_ext
->magic
);
766 aouthdr_int
->vstamp
= bfd_h_get_16(abfd
, (bfd_byte
*) aouthdr_ext
->vstamp
);
768 GET_AOUTHDR_TSIZE (abfd
, (bfd_byte
*) aouthdr_ext
->tsize
);
770 GET_AOUTHDR_DSIZE (abfd
, (bfd_byte
*) aouthdr_ext
->dsize
);
772 GET_AOUTHDR_BSIZE (abfd
, (bfd_byte
*) aouthdr_ext
->bsize
);
774 GET_AOUTHDR_ENTRY (abfd
, (bfd_byte
*) aouthdr_ext
->entry
);
775 aouthdr_int
->text_start
=
776 GET_AOUTHDR_TEXT_START (abfd
, (bfd_byte
*) aouthdr_ext
->text_start
);
777 aouthdr_int
->data_start
=
778 GET_AOUTHDR_DATA_START (abfd
, (bfd_byte
*) aouthdr_ext
->data_start
);
780 a
= &aouthdr_int
->pe
;
781 a
->ImageBase
= bfd_h_get_32 (abfd
, src
->ImageBase
);
782 a
->SectionAlignment
= bfd_h_get_32 (abfd
, src
->SectionAlignment
);
783 a
->FileAlignment
= bfd_h_get_32 (abfd
, src
->FileAlignment
);
784 a
->MajorOperatingSystemVersion
=
785 bfd_h_get_16 (abfd
, src
->MajorOperatingSystemVersion
);
786 a
->MinorOperatingSystemVersion
=
787 bfd_h_get_16 (abfd
, src
->MinorOperatingSystemVersion
);
788 a
->MajorImageVersion
= bfd_h_get_16 (abfd
, src
->MajorImageVersion
);
789 a
->MinorImageVersion
= bfd_h_get_16 (abfd
, src
->MinorImageVersion
);
790 a
->MajorSubsystemVersion
= bfd_h_get_16 (abfd
, src
->MajorSubsystemVersion
);
791 a
->MinorSubsystemVersion
= bfd_h_get_16 (abfd
, src
->MinorSubsystemVersion
);
792 a
->Reserved1
= bfd_h_get_32 (abfd
, src
->Reserved1
);
793 a
->SizeOfImage
= bfd_h_get_32 (abfd
, src
->SizeOfImage
);
794 a
->SizeOfHeaders
= bfd_h_get_32 (abfd
, src
->SizeOfHeaders
);
795 a
->CheckSum
= bfd_h_get_32 (abfd
, src
->CheckSum
);
796 a
->Subsystem
= bfd_h_get_16 (abfd
, src
->Subsystem
);
797 a
->DllCharacteristics
= bfd_h_get_16 (abfd
, src
->DllCharacteristics
);
798 a
->SizeOfStackReserve
= bfd_h_get_32 (abfd
, src
->SizeOfStackReserve
);
799 a
->SizeOfStackCommit
= bfd_h_get_32 (abfd
, src
->SizeOfStackCommit
);
800 a
->SizeOfHeapReserve
= bfd_h_get_32 (abfd
, src
->SizeOfHeapReserve
);
801 a
->SizeOfHeapCommit
= bfd_h_get_32 (abfd
, src
->SizeOfHeapCommit
);
802 a
->LoaderFlags
= bfd_h_get_32 (abfd
, src
->LoaderFlags
);
803 a
->NumberOfRvaAndSizes
= bfd_h_get_32 (abfd
, src
->NumberOfRvaAndSizes
);
807 for (idx
=0; idx
< 16; idx
++)
809 a
->DataDirectory
[idx
].VirtualAddress
=
810 bfd_h_get_32 (abfd
, src
->DataDirectory
[idx
][0]);
811 a
->DataDirectory
[idx
].Size
=
812 bfd_h_get_32 (abfd
, src
->DataDirectory
[idx
][1]);
816 if (aouthdr_int
->entry
)
818 aouthdr_int
->entry
+= a
->ImageBase
;
819 aouthdr_int
->entry
&= 0xffffffff;
821 if (aouthdr_int
->tsize
)
823 aouthdr_int
->text_start
+= a
->ImageBase
;
824 aouthdr_int
->text_start
&= 0xffffffff;
826 if (aouthdr_int
->dsize
)
828 aouthdr_int
->data_start
+= a
->ImageBase
;
829 aouthdr_int
->data_start
&= 0xffffffff;
833 /* These three fields are normally set up by ppc_relocate_section.
834 In the case of reading a file in, we can pick them up from
837 first_thunk_address
= a
->DataDirectory
[12].VirtualAddress
;
838 thunk_size
= a
->DataDirectory
[12].Size
;
839 import_table_size
= a
->DataDirectory
[1].Size
;
844 static void add_data_entry (abfd
, aout
, idx
, name
, base
)
846 struct internal_extra_pe_aouthdr
*aout
;
851 asection
*sec
= bfd_get_section_by_name (abfd
, name
);
853 /* add import directory information if it exists */
856 aout
->DataDirectory
[idx
].VirtualAddress
= (sec
->vma
- base
) & 0xffffffff;
857 aout
->DataDirectory
[idx
].Size
= pei_section_data (abfd
, sec
)->virt_size
;
858 sec
->flags
|= SEC_DATA
;
863 coff_swap_aouthdr_out (abfd
, in
, out
)
868 struct internal_aouthdr
*aouthdr_in
= (struct internal_aouthdr
*)in
;
869 struct internal_extra_pe_aouthdr
*extra
= &pe_data (abfd
)->pe_opthdr
;
870 PEAOUTHDR
*aouthdr_out
= (PEAOUTHDR
*)out
;
872 bfd_vma sa
= extra
->SectionAlignment
;
873 bfd_vma fa
= extra
->FileAlignment
;
874 bfd_vma ib
= extra
->ImageBase
;
876 if (aouthdr_in
->tsize
)
878 aouthdr_in
->text_start
-= ib
;
879 aouthdr_in
->text_start
&= 0xffffffff;
881 if (aouthdr_in
->dsize
)
883 aouthdr_in
->data_start
-= ib
;
884 aouthdr_in
->data_start
&= 0xffffffff;
886 if (aouthdr_in
->entry
)
888 aouthdr_in
->entry
-= ib
;
889 aouthdr_in
->entry
&= 0xffffffff;
892 #define FA(x) (((x) + fa -1 ) & (- fa))
893 #define SA(x) (((x) + sa -1 ) & (- sa))
895 /* We like to have the sizes aligned */
897 aouthdr_in
->bsize
= FA (aouthdr_in
->bsize
);
900 extra
->NumberOfRvaAndSizes
= IMAGE_NUMBEROF_DIRECTORY_ENTRIES
;
902 /* first null out all data directory entries .. */
903 memset (extra
->DataDirectory
, sizeof (extra
->DataDirectory
), 0);
905 add_data_entry (abfd
, extra
, 0, ".edata", ib
);
906 add_data_entry (abfd
, extra
, 1, ".idata", ib
);
907 add_data_entry (abfd
, extra
, 2, ".rsrc" ,ib
);
910 /* FIXME: do other PE platforms use this? */
911 add_data_entry (abfd
, extra
, 3, ".pdata" ,ib
);
914 add_data_entry (abfd
, extra
, 5, ".reloc", ib
);
917 /* On the PPC NT system, this field is set up as follows. It is
918 not an "officially" reserved field, so it currently has no title.
919 first_thunk_address is idata$5, and the thunk_size is the size
920 of the idata$5 chunk of the idata section.
922 extra
->DataDirectory
[12].VirtualAddress
= first_thunk_address
;
923 extra
->DataDirectory
[12].Size
= thunk_size
;
925 /* On the PPC NT system, the size of the directory entry is not the
926 size of the entire section. It's actually offset to the end of
927 the idata$3 component of the idata section. This is the size of
928 the entire import table. (also known as the start of idata$4)
930 extra
->DataDirectory
[1].Size
= import_table_size
;
936 bfd_vma isize
= SA(abfd
->sections
->filepos
);
939 for (sec
= abfd
->sections
; sec
; sec
= sec
->next
)
941 int rounded
= FA(sec
->_raw_size
);
943 if (sec
->flags
& SEC_DATA
)
945 if (sec
->flags
& SEC_CODE
)
947 isize
+= SA(rounded
);
950 aouthdr_in
->dsize
= dsize
;
951 aouthdr_in
->tsize
= tsize
;
952 extra
->SizeOfImage
= isize
;
955 extra
->SizeOfHeaders
= abfd
->sections
->filepos
;
956 bfd_h_put_16(abfd
, aouthdr_in
->magic
, (bfd_byte
*) aouthdr_out
->standard
.magic
);
959 /* this little piece of magic sets the "linker version" field to 2.60 */
960 bfd_h_put_16(abfd
, 2 + 60 * 256, (bfd_byte
*) aouthdr_out
->standard
.vstamp
);
962 /* this little piece of magic sets the "linker version" field to 2.55 */
963 bfd_h_put_16(abfd
, 2 + 55 * 256, (bfd_byte
*) aouthdr_out
->standard
.vstamp
);
966 PUT_AOUTHDR_TSIZE (abfd
, aouthdr_in
->tsize
, (bfd_byte
*) aouthdr_out
->standard
.tsize
);
967 PUT_AOUTHDR_DSIZE (abfd
, aouthdr_in
->dsize
, (bfd_byte
*) aouthdr_out
->standard
.dsize
);
968 PUT_AOUTHDR_BSIZE (abfd
, aouthdr_in
->bsize
, (bfd_byte
*) aouthdr_out
->standard
.bsize
);
969 PUT_AOUTHDR_ENTRY (abfd
, aouthdr_in
->entry
, (bfd_byte
*) aouthdr_out
->standard
.entry
);
970 PUT_AOUTHDR_TEXT_START (abfd
, aouthdr_in
->text_start
,
971 (bfd_byte
*) aouthdr_out
->standard
.text_start
);
973 PUT_AOUTHDR_DATA_START (abfd
, aouthdr_in
->data_start
,
974 (bfd_byte
*) aouthdr_out
->standard
.data_start
);
977 bfd_h_put_32 (abfd
, extra
->ImageBase
,
978 (bfd_byte
*) aouthdr_out
->ImageBase
);
979 bfd_h_put_32 (abfd
, extra
->SectionAlignment
,
980 (bfd_byte
*) aouthdr_out
->SectionAlignment
);
981 bfd_h_put_32 (abfd
, extra
->FileAlignment
,
982 (bfd_byte
*) aouthdr_out
->FileAlignment
);
983 bfd_h_put_16 (abfd
, extra
->MajorOperatingSystemVersion
,
984 (bfd_byte
*) aouthdr_out
->MajorOperatingSystemVersion
);
985 bfd_h_put_16 (abfd
, extra
->MinorOperatingSystemVersion
,
986 (bfd_byte
*) aouthdr_out
->MinorOperatingSystemVersion
);
987 bfd_h_put_16 (abfd
, extra
->MajorImageVersion
,
988 (bfd_byte
*) aouthdr_out
->MajorImageVersion
);
989 bfd_h_put_16 (abfd
, extra
->MinorImageVersion
,
990 (bfd_byte
*) aouthdr_out
->MinorImageVersion
);
991 bfd_h_put_16 (abfd
, extra
->MajorSubsystemVersion
,
992 (bfd_byte
*) aouthdr_out
->MajorSubsystemVersion
);
993 bfd_h_put_16 (abfd
, extra
->MinorSubsystemVersion
,
994 (bfd_byte
*) aouthdr_out
->MinorSubsystemVersion
);
995 bfd_h_put_32 (abfd
, extra
->Reserved1
,
996 (bfd_byte
*) aouthdr_out
->Reserved1
);
997 bfd_h_put_32 (abfd
, extra
->SizeOfImage
,
998 (bfd_byte
*) aouthdr_out
->SizeOfImage
);
999 bfd_h_put_32 (abfd
, extra
->SizeOfHeaders
,
1000 (bfd_byte
*) aouthdr_out
->SizeOfHeaders
);
1001 bfd_h_put_32 (abfd
, extra
->CheckSum
,
1002 (bfd_byte
*) aouthdr_out
->CheckSum
);
1003 bfd_h_put_16 (abfd
, extra
->Subsystem
,
1004 (bfd_byte
*) aouthdr_out
->Subsystem
);
1005 bfd_h_put_16 (abfd
, extra
->DllCharacteristics
,
1006 (bfd_byte
*) aouthdr_out
->DllCharacteristics
);
1007 bfd_h_put_32 (abfd
, extra
->SizeOfStackReserve
,
1008 (bfd_byte
*) aouthdr_out
->SizeOfStackReserve
);
1009 bfd_h_put_32 (abfd
, extra
->SizeOfStackCommit
,
1010 (bfd_byte
*) aouthdr_out
->SizeOfStackCommit
);
1011 bfd_h_put_32 (abfd
, extra
->SizeOfHeapReserve
,
1012 (bfd_byte
*) aouthdr_out
->SizeOfHeapReserve
);
1013 bfd_h_put_32 (abfd
, extra
->SizeOfHeapCommit
,
1014 (bfd_byte
*) aouthdr_out
->SizeOfHeapCommit
);
1015 bfd_h_put_32 (abfd
, extra
->LoaderFlags
,
1016 (bfd_byte
*) aouthdr_out
->LoaderFlags
);
1017 bfd_h_put_32 (abfd
, extra
->NumberOfRvaAndSizes
,
1018 (bfd_byte
*) aouthdr_out
->NumberOfRvaAndSizes
);
1021 for (idx
=0; idx
< 16; idx
++)
1023 bfd_h_put_32 (abfd
, extra
->DataDirectory
[idx
].VirtualAddress
,
1024 (bfd_byte
*) aouthdr_out
->DataDirectory
[idx
][0]);
1025 bfd_h_put_32 (abfd
, extra
->DataDirectory
[idx
].Size
,
1026 (bfd_byte
*) aouthdr_out
->DataDirectory
[idx
][1]);
1034 coff_swap_scnhdr_in (abfd
, ext
, in
)
1039 SCNHDR
*scnhdr_ext
= (SCNHDR
*) ext
;
1040 struct internal_scnhdr
*scnhdr_int
= (struct internal_scnhdr
*) in
;
1042 memcpy(scnhdr_int
->s_name
, scnhdr_ext
->s_name
, sizeof(scnhdr_int
->s_name
));
1043 scnhdr_int
->s_vaddr
=
1044 GET_SCNHDR_VADDR (abfd
, (bfd_byte
*) scnhdr_ext
->s_vaddr
);
1045 scnhdr_int
->s_paddr
=
1046 GET_SCNHDR_PADDR (abfd
, (bfd_byte
*) scnhdr_ext
->s_paddr
);
1047 scnhdr_int
->s_size
=
1048 GET_SCNHDR_SIZE (abfd
, (bfd_byte
*) scnhdr_ext
->s_size
);
1049 scnhdr_int
->s_scnptr
=
1050 GET_SCNHDR_SCNPTR (abfd
, (bfd_byte
*) scnhdr_ext
->s_scnptr
);
1051 scnhdr_int
->s_relptr
=
1052 GET_SCNHDR_RELPTR (abfd
, (bfd_byte
*) scnhdr_ext
->s_relptr
);
1053 scnhdr_int
->s_lnnoptr
=
1054 GET_SCNHDR_LNNOPTR (abfd
, (bfd_byte
*) scnhdr_ext
->s_lnnoptr
);
1055 scnhdr_int
->s_flags
= bfd_h_get_32(abfd
, (bfd_byte
*) scnhdr_ext
->s_flags
);
1057 scnhdr_int
->s_nreloc
= bfd_h_get_16(abfd
, (bfd_byte
*) scnhdr_ext
->s_nreloc
);
1058 scnhdr_int
->s_nlnno
= bfd_h_get_16(abfd
, (bfd_byte
*) scnhdr_ext
->s_nlnno
);
1060 if (scnhdr_int
->s_vaddr
!= 0)
1062 scnhdr_int
->s_vaddr
+= pe_data (abfd
)->pe_opthdr
.ImageBase
;
1063 scnhdr_int
->s_vaddr
&= 0xffffffff;
1065 if (strcmp (scnhdr_int
->s_name
, _BSS
) == 0)
1067 scnhdr_int
->s_size
= scnhdr_int
->s_paddr
;
1068 scnhdr_int
->s_paddr
= 0;
1073 coff_swap_scnhdr_out (abfd
, in
, out
)
1078 struct internal_scnhdr
*scnhdr_int
= (struct internal_scnhdr
*)in
;
1079 SCNHDR
*scnhdr_ext
= (SCNHDR
*)out
;
1080 unsigned int ret
= SCNHSZ
;
1084 memcpy(scnhdr_ext
->s_name
, scnhdr_int
->s_name
, sizeof(scnhdr_int
->s_name
));
1086 PUT_SCNHDR_VADDR (abfd
,
1087 ((scnhdr_int
->s_vaddr
1088 - pe_data(abfd
)->pe_opthdr
.ImageBase
)
1090 (bfd_byte
*) scnhdr_ext
->s_vaddr
);
1092 /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1093 value except for the BSS section, its s_size should be 0 */
1096 if (strcmp (scnhdr_int
->s_name
, _BSS
) == 0)
1098 ps
= scnhdr_int
->s_size
;
1103 ps
= scnhdr_int
->s_paddr
;
1104 ss
= scnhdr_int
->s_size
;
1107 PUT_SCNHDR_SIZE (abfd
, ss
,
1108 (bfd_byte
*) scnhdr_ext
->s_size
);
1111 PUT_SCNHDR_PADDR (abfd
, ps
, (bfd_byte
*) scnhdr_ext
->s_paddr
);
1113 PUT_SCNHDR_SCNPTR (abfd
, scnhdr_int
->s_scnptr
,
1114 (bfd_byte
*) scnhdr_ext
->s_scnptr
);
1115 PUT_SCNHDR_RELPTR (abfd
, scnhdr_int
->s_relptr
,
1116 (bfd_byte
*) scnhdr_ext
->s_relptr
);
1117 PUT_SCNHDR_LNNOPTR (abfd
, scnhdr_int
->s_lnnoptr
,
1118 (bfd_byte
*) scnhdr_ext
->s_lnnoptr
);
1120 /* Extra flags must be set when dealing with NT. All sections should also
1121 have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
1122 .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1123 sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1124 (this is especially important when dealing with the .idata section since
1125 the addresses for routines from .dlls must be overwritten). If .reloc
1126 section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1127 (0x02000000). Also, the resource data should also be read and
1130 /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1131 /* FIXME: even worse, I don't see how to get the original alignment field*/
1134 /* FIXME: Basing this on section names is bogus. Also, this should
1135 be in sec_to_styp_flags. */
1138 int flags
= scnhdr_int
->s_flags
;
1139 if (strcmp (scnhdr_int
->s_name
, ".data") == 0 ||
1140 strcmp (scnhdr_int
->s_name
, ".CRT") == 0 ||
1141 strcmp (scnhdr_int
->s_name
, ".rsrc") == 0 ||
1142 strcmp (scnhdr_int
->s_name
, ".bss") == 0)
1143 flags
|= IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_WRITE
;
1144 else if (strcmp (scnhdr_int
->s_name
, ".text") == 0)
1145 flags
|= IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_EXECUTE
;
1146 else if (strcmp (scnhdr_int
->s_name
, ".reloc") == 0)
1147 flags
= SEC_DATA
| IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_DISCARDABLE
;
1148 else if (strcmp (scnhdr_int
->s_name
, ".idata") == 0)
1149 flags
= IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_WRITE
| SEC_DATA
;
1150 else if (strcmp (scnhdr_int
->s_name
, ".rdata") == 0
1151 || strcmp (scnhdr_int
->s_name
, ".edata") == 0)
1152 flags
= IMAGE_SCN_MEM_READ
| SEC_DATA
;
1153 else if (strcmp (scnhdr_int
->s_name
, ".pdata") == 0)
1154 flags
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_ALIGN_4BYTES
|
1155 IMAGE_SCN_MEM_READ
;
1156 /* Remember this field is a max of 8 chars, so the null is _not_ there
1157 for an 8 character name like ".reldata". (yep. Stupid bug) */
1158 else if (strncmp (scnhdr_int
->s_name
, ".reldata", 8) == 0)
1159 flags
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_ALIGN_8BYTES
|
1160 IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_WRITE
;
1161 else if (strcmp (scnhdr_int
->s_name
, ".ydata") == 0)
1162 flags
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_ALIGN_8BYTES
|
1163 IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_WRITE
;
1164 else if (strncmp (scnhdr_int
->s_name
, ".drectve", 8) == 0)
1165 flags
= IMAGE_SCN_LNK_INFO
| IMAGE_SCN_LNK_REMOVE
;
1166 else if (strncmp (scnhdr_int
->s_name
, ".stab", 5) == 0)
1167 flags
|= IMAGE_SCN_LNK_INFO
| IMAGE_SCN_MEM_DISCARDABLE
;
1169 flags
= IMAGE_SCN_MEM_READ
;
1171 bfd_h_put_32(abfd
, flags
, (bfd_byte
*) scnhdr_ext
->s_flags
);
1174 if (scnhdr_int
->s_nlnno
<= 0xffff)
1175 bfd_h_put_16(abfd
, scnhdr_int
->s_nlnno
, (bfd_byte
*) scnhdr_ext
->s_nlnno
);
1178 (*_bfd_error_handler
) ("%s: line number overflow: 0x%lx > 0xffff",
1179 bfd_get_filename (abfd
),
1180 scnhdr_int
->s_nlnno
);
1181 bfd_set_error (bfd_error_file_truncated
);
1182 bfd_h_put_16 (abfd
, 0xffff, (bfd_byte
*) scnhdr_ext
->s_nlnno
);
1185 if (scnhdr_int
->s_nreloc
<= 0xffff)
1186 bfd_h_put_16(abfd
, scnhdr_int
->s_nreloc
, (bfd_byte
*) scnhdr_ext
->s_nreloc
);
1189 (*_bfd_error_handler
) ("%s: reloc overflow: 0x%lx > 0xffff",
1190 bfd_get_filename (abfd
),
1191 scnhdr_int
->s_nreloc
);
1192 bfd_set_error (bfd_error_file_truncated
);
1193 bfd_h_put_16 (abfd
, 0xffff, (bfd_byte
*) scnhdr_ext
->s_nreloc
);
1199 static char * dir_names
[IMAGE_NUMBEROF_DIRECTORY_ENTRIES
] =
1201 "Export Directory [.edata (or where ever we found it)]",
1202 "Import Directory [parts of .idata]",
1203 "Resource Directory [.rsrc]",
1204 "Exception Directory [.pdata]",
1205 "Security Directory",
1206 "Base Relocation Directory [.reloc]",
1208 "Description Directory",
1209 "Special Directory",
1210 "Thread Storage Directory [.tls]",
1211 "Load Configuration Directory",
1212 "Bound Import Directory",
1213 "Import Address Table Directory",
1219 /**********************************************************************/
1221 pe_print_idata(abfd
, vfile
)
1225 FILE *file
= (FILE *) vfile
;
1227 asection
*section
= bfd_get_section_by_name (abfd
, ".idata");
1229 #ifdef POWERPC_LE_PE
1230 asection
*rel_section
= bfd_get_section_by_name (abfd
, ".reldata");
1233 bfd_size_type datasize
= 0;
1235 bfd_size_type start
, stop
;
1238 pe_data_type
*pe
= pe_data (abfd
);
1239 struct internal_extra_pe_aouthdr
*extra
= &pe
->pe_opthdr
;
1244 #ifdef POWERPC_LE_PE
1245 if (rel_section
!= 0 && bfd_section_size (abfd
, rel_section
) != 0)
1247 /* The toc address can be found by taking the starting address,
1248 which on the PPC locates a function descriptor. The descriptor
1249 consists of the function code starting address followed by the
1250 address of the toc. The starting address we get from the bfd,
1251 and the descriptor is supposed to be in the .reldata section.
1254 bfd_vma loadable_toc_address
;
1255 bfd_vma toc_address
;
1256 bfd_vma start_address
;
1259 data
= (bfd_byte
*) bfd_malloc ((size_t) bfd_section_size (abfd
,
1261 if (data
== NULL
&& bfd_section_size (abfd
, rel_section
) != 0)
1264 datasize
= bfd_section_size (abfd
, rel_section
);
1266 bfd_get_section_contents (abfd
,
1269 bfd_section_size (abfd
, rel_section
));
1271 offset
= abfd
->start_address
- rel_section
->vma
;
1273 start_address
= bfd_get_32(abfd
, data
+offset
);
1274 loadable_toc_address
= bfd_get_32(abfd
, data
+offset
+4);
1275 toc_address
= loadable_toc_address
- 32768;
1278 "\nFunction descriptor located at the start address: %04lx\n",
1279 (unsigned long int) (abfd
->start_address
));
1281 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
1282 start_address
, loadable_toc_address
, toc_address
);
1287 "\nNo reldata section! Function descriptor not decoded.\n");
1292 "\nThe Import Tables (interpreted .idata section contents)\n");
1294 " vma: Hint Time Forward DLL First\n");
1296 " Table Stamp Chain Name Thunk\n");
1298 if (bfd_section_size (abfd
, section
) == 0)
1301 data
= (bfd_byte
*) bfd_malloc ((size_t) bfd_section_size (abfd
, section
));
1302 datasize
= bfd_section_size (abfd
, section
);
1303 if (data
== NULL
&& datasize
!= 0)
1306 bfd_get_section_contents (abfd
,
1309 bfd_section_size (abfd
, section
));
1313 stop
= bfd_section_size (abfd
, section
);
1315 for (i
= start
; i
< stop
; i
+= onaline
)
1319 bfd_vma forward_chain
;
1321 bfd_vma first_thunk
;
1325 int adj
= (extra
->ImageBase
- section
->vma
) & 0xffffffff;
1329 (unsigned long int) (i
+ section
->vma
));
1337 hint_addr
= bfd_get_32(abfd
, data
+i
);
1338 time_stamp
= bfd_get_32(abfd
, data
+i
+4);
1339 forward_chain
= bfd_get_32(abfd
, data
+i
+8);
1340 dll_name
= bfd_get_32(abfd
, data
+i
+12);
1341 first_thunk
= bfd_get_32(abfd
, data
+i
+16);
1343 fprintf(file
, "%08lx %08lx %08lx %08lx %08lx\n",
1355 /* the image base is present in the section->vma */
1356 dll
= (char *) data
+ dll_name
+ adj
;
1357 fprintf(file
, "\n\tDLL Name: %s\n", dll
);
1358 fprintf(file
, "\tvma: Ordinal Member-Name\n");
1360 idx
= hint_addr
+ adj
;
1362 for (j
=0;j
<stop
;j
+=4)
1366 bfd_vma member
= bfd_get_32(abfd
, data
+ idx
+ j
);
1369 ordinal
= bfd_get_16(abfd
,
1370 data
+ member
+ adj
);
1371 member_name
= (char *) data
+ member
+ adj
+ 2;
1372 fprintf(file
, "\t%04lx\t %4d %s\n",
1373 member
, ordinal
, member_name
);
1376 if (hint_addr
!= first_thunk
)
1381 idx2
= first_thunk
+ adj
;
1383 for (j
=0;j
<stop
;j
+=4)
1387 bfd_vma hint_member
= bfd_get_32(abfd
, data
+ idx
+ j
);
1388 bfd_vma iat_member
= bfd_get_32(abfd
, data
+ idx2
+ j
);
1389 if (hint_member
!= iat_member
)
1394 "\tThe Import Address Table (difference found)\n");
1395 fprintf(file
, "\tvma: Ordinal Member-Name\n");
1398 if (iat_member
== 0)
1401 "\t>>> Ran out of IAT members!\n");
1405 ordinal
= bfd_get_16(abfd
,
1406 data
+ iat_member
+ adj
);
1407 member_name
= (char *) data
+ iat_member
+ adj
+ 2;
1408 fprintf(file
, "\t%04lx\t %4d %s\n",
1409 iat_member
, ordinal
, member_name
);
1413 if (hint_member
== 0)
1419 "\tThe Import Address Table is identical\n");
1423 fprintf(file
, "\n");
1433 pe_print_edata (abfd
, vfile
)
1437 FILE *file
= (FILE *) vfile
;
1439 asection
*section
= bfd_get_section_by_name (abfd
, ".edata");
1441 bfd_size_type datasize
= 0;
1447 long export_flags
; /* reserved - should be zero */
1451 bfd_vma name
; /* rva - relative to image base */
1452 long base
; /* ordinal base */
1453 long num_functions
; /* Number in the export address table */
1454 long num_names
; /* Number in the name pointer table */
1455 bfd_vma eat_addr
; /* rva to the export address table */
1456 bfd_vma npt_addr
; /* rva to the Export Name Pointer Table */
1457 bfd_vma ot_addr
; /* rva to the Ordinal Table */
1460 pe_data_type
*pe
= pe_data (abfd
);
1461 struct internal_extra_pe_aouthdr
*extra
= &pe
->pe_opthdr
;
1466 data
= (bfd_byte
*) bfd_malloc ((size_t) bfd_section_size (abfd
,
1468 datasize
= bfd_section_size (abfd
, section
);
1470 if (data
== NULL
&& datasize
!= 0)
1473 bfd_get_section_contents (abfd
,
1476 bfd_section_size (abfd
, section
));
1478 /* Go get Export Directory Table */
1479 edt
.export_flags
= bfd_get_32(abfd
, data
+0);
1480 edt
.time_stamp
= bfd_get_32(abfd
, data
+4);
1481 edt
.major_ver
= bfd_get_16(abfd
, data
+8);
1482 edt
.minor_ver
= bfd_get_16(abfd
, data
+10);
1483 edt
.name
= bfd_get_32(abfd
, data
+12);
1484 edt
.base
= bfd_get_32(abfd
, data
+16);
1485 edt
.num_functions
= bfd_get_32(abfd
, data
+20);
1486 edt
.num_names
= bfd_get_32(abfd
, data
+24);
1487 edt
.eat_addr
= bfd_get_32(abfd
, data
+28);
1488 edt
.npt_addr
= bfd_get_32(abfd
, data
+32);
1489 edt
.ot_addr
= bfd_get_32(abfd
, data
+36);
1491 adj
= (extra
->ImageBase
- section
->vma
) & 0xffffffff;
1494 /* Dump the EDT first first */
1496 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1499 "Export Flags \t\t\t%lx\n", (unsigned long) edt
.export_flags
);
1502 "Time/Date stamp \t\t%lx\n", (unsigned long) edt
.time_stamp
);
1505 "Major/Minor \t\t\t%d/%d\n", edt
.major_ver
, edt
.minor_ver
);
1509 fprintf_vma (file
, edt
.name
);
1511 " %s\n", data
+ edt
.name
+ adj
);
1514 "Ordinal Base \t\t\t%ld\n", edt
.base
);
1520 "\tExport Address Table \t\t%lx\n",
1521 (unsigned long) edt
.num_functions
);
1524 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt
.num_names
);
1527 "Table Addresses\n");
1530 "\tExport Address Table \t\t");
1531 fprintf_vma (file
, edt
.eat_addr
);
1532 fprintf (file
, "\n");
1535 "\tName Pointer Table \t\t");
1536 fprintf_vma (file
, edt
.npt_addr
);
1537 fprintf (file
, "\n");
1540 "\tOrdinal Table \t\t\t");
1541 fprintf_vma (file
, edt
.ot_addr
);
1542 fprintf (file
, "\n");
1545 /* The next table to find si the Export Address Table. It's basically
1546 a list of pointers that either locate a function in this dll, or
1547 forward the call to another dll. Something like:
1552 } export_address_table_entry;
1556 "\nExport Address Table -- Ordinal Base %ld\n",
1559 for (i
= 0; i
< edt
.num_functions
; ++i
)
1561 bfd_vma eat_member
= bfd_get_32(abfd
,
1562 data
+ edt
.eat_addr
+ (i
*4) + adj
);
1563 bfd_vma eat_actual
= (extra
->ImageBase
+ eat_member
) & 0xffffffff;
1564 bfd_vma edata_start
= bfd_get_section_vma(abfd
,section
);
1565 bfd_vma edata_end
= edata_start
+ bfd_section_size (abfd
, section
);
1568 if (eat_member
== 0)
1571 if (edata_start
< eat_actual
&& eat_actual
< edata_end
)
1573 /* this rva is to a name (forwarding function) in our section */
1574 /* Should locate a function descriptor */
1576 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1577 (long) i
, (long) (i
+ edt
.base
), eat_member
,
1578 "Forwarder RVA", data
+ eat_member
+ adj
);
1582 /* Should locate a function descriptor in the reldata section */
1584 "\t[%4ld] +base[%4ld] %04lx %s\n",
1585 (long) i
, (long) (i
+ edt
.base
), eat_member
, "Export RVA");
1589 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1590 /* Dump them in parallel for clarity */
1592 "\n[Ordinal/Name Pointer] Table\n");
1594 for (i
= 0; i
< edt
.num_names
; ++i
)
1596 bfd_vma name_ptr
= bfd_get_32(abfd
,
1601 char *name
= (char *) data
+ name_ptr
+ adj
;
1603 bfd_vma ord
= bfd_get_16(abfd
,
1608 "\t[%4ld] %s\n", (long) ord
, name
);
1618 pe_print_pdata (abfd
, vfile
)
1622 FILE *file
= (FILE *) vfile
;
1624 asection
*section
= bfd_get_section_by_name (abfd
, ".pdata");
1625 bfd_size_type datasize
= 0;
1627 bfd_size_type start
, stop
;
1633 stop
= bfd_section_size (abfd
, section
);
1634 if ((stop
% onaline
) != 0)
1635 fprintf (file
, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1636 (long)stop
, onaline
);
1639 "\nThe Function Table (interpreted .pdata section contents)\n");
1641 " vma:\t\tBegin End EH EH PrologEnd\n");
1643 " \t\tAddress Address Handler Data Address\n");
1645 if (bfd_section_size (abfd
, section
) == 0)
1648 data
= (bfd_byte
*) bfd_malloc ((size_t) bfd_section_size (abfd
, section
));
1649 datasize
= bfd_section_size (abfd
, section
);
1650 if (data
== NULL
&& datasize
!= 0)
1653 bfd_get_section_contents (abfd
,
1656 bfd_section_size (abfd
, section
));
1660 for (i
= start
; i
< stop
; i
+= onaline
)
1666 bfd_vma prolog_end_addr
;
1671 begin_addr
= bfd_get_32(abfd
, data
+i
);
1672 end_addr
= bfd_get_32(abfd
, data
+i
+4);
1673 eh_handler
= bfd_get_32(abfd
, data
+i
+8);
1674 eh_data
= bfd_get_32(abfd
, data
+i
+12);
1675 prolog_end_addr
= bfd_get_32(abfd
, data
+i
+16);
1677 if (begin_addr
== 0 && end_addr
== 0 && eh_handler
== 0
1678 && eh_data
== 0 && prolog_end_addr
== 0)
1680 /* We are probably into the padding of the
1687 (unsigned long int) (i
+ section
->vma
));
1689 fprintf(file
, "%08lx %08lx %08lx %08lx %08lx",
1696 #ifdef POWERPC_LE_PE
1697 if (eh_handler
== 0 && eh_data
!= 0)
1699 /* Special bits here, although the meaning may */
1700 /* be a little mysterious. The only one I know */
1701 /* for sure is 0x03. */
1702 /* Code Significance */
1704 /* 0x01 Register Save Millicode */
1705 /* 0x02 Register Restore Millicode */
1706 /* 0x03 Glue Code Sequence */
1710 fprintf(file
, " Register save millicode");
1713 fprintf(file
, " Register restore millicode");
1716 fprintf(file
, " Glue code sequence");
1723 fprintf(file
, "\n");
1731 static const char *tbl
[6] =
1742 pe_print_reloc (abfd
, vfile
)
1746 FILE *file
= (FILE *) vfile
;
1748 asection
*section
= bfd_get_section_by_name (abfd
, ".reloc");
1749 bfd_size_type datasize
= 0;
1751 bfd_size_type start
, stop
;
1756 if (bfd_section_size (abfd
, section
) == 0)
1760 "\n\nPE File Base Relocations (interpreted .reloc section contents)\n");
1762 data
= (bfd_byte
*) bfd_malloc ((size_t) bfd_section_size (abfd
, section
));
1763 datasize
= bfd_section_size (abfd
, section
);
1764 if (data
== NULL
&& datasize
!= 0)
1767 bfd_get_section_contents (abfd
,
1770 bfd_section_size (abfd
, section
));
1774 stop
= bfd_section_size (abfd
, section
);
1776 for (i
= start
; i
< stop
;)
1779 bfd_vma virtual_address
;
1782 /* The .reloc section is a sequence of blocks, with a header consisting
1783 of two 32 bit quantities, followed by a number of 16 bit entries */
1785 virtual_address
= bfd_get_32(abfd
, data
+i
);
1786 size
= bfd_get_32(abfd
, data
+i
+4);
1787 number
= (size
- 8) / 2;
1795 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1796 virtual_address
, size
, size
, number
);
1798 for (j
= 0; j
< number
; ++j
)
1800 unsigned short e
= bfd_get_16(abfd
, data
+ i
+ 8 + j
*2);
1801 int t
= (e
& 0xF000) >> 12;
1802 int off
= e
& 0x0FFF;
1808 "\treloc %4d offset %4x [%4lx] %s\n",
1809 j
, off
, (long) (off
+ virtual_address
), tbl
[t
]);
1821 pe_print_private_bfd_data (abfd
, vfile
)
1825 FILE *file
= (FILE *) vfile
;
1827 pe_data_type
*pe
= pe_data (abfd
);
1828 struct internal_extra_pe_aouthdr
*i
= &pe
->pe_opthdr
;
1830 fprintf (file
,"\nImageBase\t\t");
1831 fprintf_vma (file
, i
->ImageBase
);
1832 fprintf (file
,"\nSectionAlignment\t");
1833 fprintf_vma (file
, i
->SectionAlignment
);
1834 fprintf (file
,"\nFileAlignment\t\t");
1835 fprintf_vma (file
, i
->FileAlignment
);
1836 fprintf (file
,"\nMajorOSystemVersion\t%d\n", i
->MajorOperatingSystemVersion
);
1837 fprintf (file
,"MinorOSystemVersion\t%d\n", i
->MinorOperatingSystemVersion
);
1838 fprintf (file
,"MajorImageVersion\t%d\n", i
->MajorImageVersion
);
1839 fprintf (file
,"MinorImageVersion\t%d\n", i
->MinorImageVersion
);
1840 fprintf (file
,"MajorSubsystemVersion\t%d\n", i
->MajorSubsystemVersion
);
1841 fprintf (file
,"MinorSubsystemVersion\t%d\n", i
->MinorSubsystemVersion
);
1842 fprintf (file
,"Reserved1\t\t%08lx\n", i
->Reserved1
);
1843 fprintf (file
,"SizeOfImage\t\t%08lx\n", i
->SizeOfImage
);
1844 fprintf (file
,"SizeOfHeaders\t\t%08lx\n", i
->SizeOfHeaders
);
1845 fprintf (file
,"CheckSum\t\t%08lx\n", i
->CheckSum
);
1846 fprintf (file
,"Subsystem\t\t%08x\n", i
->Subsystem
);
1847 fprintf (file
,"DllCharacteristics\t%08x\n", i
->DllCharacteristics
);
1848 fprintf (file
,"SizeOfStackReserve\t");
1849 fprintf_vma (file
, i
->SizeOfStackReserve
);
1850 fprintf (file
,"\nSizeOfStackCommit\t");
1851 fprintf_vma (file
, i
->SizeOfStackCommit
);
1852 fprintf (file
,"\nSizeOfHeapReserve\t");
1853 fprintf_vma (file
, i
->SizeOfHeapReserve
);
1854 fprintf (file
,"\nSizeOfHeapCommit\t");
1855 fprintf_vma (file
, i
->SizeOfHeapCommit
);
1856 fprintf (file
,"\nLoaderFlags\t\t%08lx\n", i
->LoaderFlags
);
1857 fprintf (file
,"NumberOfRvaAndSizes\t%08lx\n", i
->NumberOfRvaAndSizes
);
1859 fprintf (file
,"\nThe Data Directory\n");
1860 for (j
= 0; j
< IMAGE_NUMBEROF_DIRECTORY_ENTRIES
; j
++)
1862 fprintf (file
, "Entry %1x ", j
);
1863 fprintf_vma (file
, i
->DataDirectory
[j
].VirtualAddress
);
1864 fprintf (file
, " %08lx ", i
->DataDirectory
[j
].Size
);
1865 fprintf (file
, "%s\n", dir_names
[j
]);
1868 pe_print_idata(abfd
, vfile
);
1869 pe_print_edata(abfd
, vfile
);
1870 pe_print_pdata(abfd
, vfile
);
1871 pe_print_reloc(abfd
, vfile
);
1881 abfd
->tdata
.pe_obj_data
=
1882 (struct pe_tdata
*) bfd_zalloc (abfd
, sizeof (pe_data_type
));
1884 if (abfd
->tdata
.pe_obj_data
== 0)
1887 pe
= pe_data (abfd
);
1890 pe
->in_reloc_p
= in_reloc_p
;
1894 /* Create the COFF backend specific information. */
1896 pe_mkobject_hook (abfd
, filehdr
, aouthdr
)
1901 struct internal_filehdr
*internal_f
= (struct internal_filehdr
*) filehdr
;
1904 if (pe_mkobject (abfd
) == false)
1907 pe
= pe_data (abfd
);
1908 pe
->coff
.sym_filepos
= internal_f
->f_symptr
;
1909 /* These members communicate important constants about the symbol
1910 table to GDB's symbol-reading code. These `constants'
1911 unfortunately vary among coff implementations... */
1912 pe
->coff
.local_n_btmask
= N_BTMASK
;
1913 pe
->coff
.local_n_btshft
= N_BTSHFT
;
1914 pe
->coff
.local_n_tmask
= N_TMASK
;
1915 pe
->coff
.local_n_tshift
= N_TSHIFT
;
1916 pe
->coff
.local_symesz
= SYMESZ
;
1917 pe
->coff
.local_auxesz
= AUXESZ
;
1918 pe
->coff
.local_linesz
= LINESZ
;
1920 obj_raw_syment_count (abfd
) =
1921 obj_conv_table_size (abfd
) =
1922 internal_f
->f_nsyms
;
1924 pe
->real_flags
= internal_f
->f_flags
;
1926 if ((internal_f
->f_flags
& F_DLL
) != 0)
1929 #ifdef COFF_IMAGE_WITH_PE
1932 pe
->pe_opthdr
= ((struct internal_aouthdr
*)aouthdr
)->pe
;
1941 /* Copy any private info we understand from the input bfd
1942 to the output bfd. */
1944 #undef coff_bfd_copy_private_bfd_data
1945 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1948 pe_bfd_copy_private_bfd_data (ibfd
, obfd
)
1951 /* One day we may try to grok other private data. */
1952 if (ibfd
->xvec
->flavour
!= bfd_target_coff_flavour
1953 || obfd
->xvec
->flavour
!= bfd_target_coff_flavour
)
1956 pe_data (obfd
)->pe_opthdr
= pe_data (ibfd
)->pe_opthdr
;
1957 pe_data (obfd
)->dll
= pe_data (ibfd
)->dll
;
1962 #ifdef COFF_IMAGE_WITH_PE
1964 /* Copy private section data. */
1966 #define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
1968 static boolean pe_bfd_copy_private_section_data
1969 PARAMS ((bfd
*, asection
*, bfd
*, asection
*));
1972 pe_bfd_copy_private_section_data (ibfd
, isec
, obfd
, osec
)
1978 if (bfd_get_flavour (ibfd
) != bfd_target_coff_flavour
1979 || bfd_get_flavour (obfd
) != bfd_target_coff_flavour
)
1982 if (coff_section_data (ibfd
, isec
) != NULL
1983 && pei_section_data (ibfd
, isec
) != NULL
)
1985 if (coff_section_data (obfd
, osec
) == NULL
)
1988 (PTR
) bfd_zalloc (obfd
, sizeof (struct coff_section_tdata
));
1989 if (osec
->used_by_bfd
== NULL
)
1992 if (pei_section_data (obfd
, osec
) == NULL
)
1994 coff_section_data (obfd
, osec
)->tdata
=
1995 (PTR
) bfd_zalloc (obfd
, sizeof (struct pei_section_tdata
));
1996 if (coff_section_data (obfd
, osec
)->tdata
== NULL
)
1999 pei_section_data (obfd
, osec
)->virt_size
=
2000 pei_section_data (ibfd
, isec
)->virt_size
;