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