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