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