3b8091e623a68d638a3f9496e4238bab1897bd56
[deliverable/binutils-gdb.git] / bfd / peicode.h
1 /* Support for the generic parts of most COFF variants, for BFD.
2 Copyright 1995 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 (strcmp(sec->name,".junk") == 0)
865 {
866 continue;
867 }
868
869 if (sec->flags & SEC_DATA)
870 dsize += rounded;
871 if (sec->flags & SEC_CODE)
872 tsize += rounded;
873 isize += SA(rounded);
874 }
875
876 aouthdr_in->dsize = dsize;
877 aouthdr_in->tsize = tsize;
878 extra->SizeOfImage = isize;
879 }
880
881 extra->SizeOfHeaders = abfd->sections->filepos;
882 bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
883
884 #ifdef POWERPC_LE_PE
885 /* this little piece of magic sets the "linker version" field to 2.60 */
886 bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
887 #else
888 /* this little piece of magic sets the "linker version" field to 2.55 */
889 bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
890 #endif
891
892 PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
893 PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
894 PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
895 PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
896 PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
897 (bfd_byte *) aouthdr_out->standard.text_start);
898
899 PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
900 (bfd_byte *) aouthdr_out->standard.data_start);
901
902
903 bfd_h_put_32 (abfd, extra->ImageBase,
904 (bfd_byte *) aouthdr_out->ImageBase);
905 bfd_h_put_32 (abfd, extra->SectionAlignment,
906 (bfd_byte *) aouthdr_out->SectionAlignment);
907 bfd_h_put_32 (abfd, extra->FileAlignment,
908 (bfd_byte *) aouthdr_out->FileAlignment);
909 bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
910 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
911 bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
912 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
913 bfd_h_put_16 (abfd, extra->MajorImageVersion,
914 (bfd_byte *) aouthdr_out->MajorImageVersion);
915 bfd_h_put_16 (abfd, extra->MinorImageVersion,
916 (bfd_byte *) aouthdr_out->MinorImageVersion);
917 bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
918 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
919 bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
920 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
921 bfd_h_put_32 (abfd, extra->Reserved1,
922 (bfd_byte *) aouthdr_out->Reserved1);
923 bfd_h_put_32 (abfd, extra->SizeOfImage,
924 (bfd_byte *) aouthdr_out->SizeOfImage);
925 bfd_h_put_32 (abfd, extra->SizeOfHeaders,
926 (bfd_byte *) aouthdr_out->SizeOfHeaders);
927 bfd_h_put_32 (abfd, extra->CheckSum,
928 (bfd_byte *) aouthdr_out->CheckSum);
929 bfd_h_put_16 (abfd, extra->Subsystem,
930 (bfd_byte *) aouthdr_out->Subsystem);
931 bfd_h_put_16 (abfd, extra->DllCharacteristics,
932 (bfd_byte *) aouthdr_out->DllCharacteristics);
933 bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
934 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
935 bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
936 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
937 bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
938 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
939 bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
940 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
941 bfd_h_put_32 (abfd, extra->LoaderFlags,
942 (bfd_byte *) aouthdr_out->LoaderFlags);
943 bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
944 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
945 {
946 int idx;
947 for (idx=0; idx < 16; idx++)
948 {
949 bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
950 (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
951 bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
952 (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
953 }
954 }
955
956 return sizeof(AOUTHDR);
957 }
958
959 static void
960 coff_swap_scnhdr_in (abfd, ext, in)
961 bfd *abfd;
962 PTR ext;
963 PTR in;
964 {
965 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
966 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
967
968 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
969 scnhdr_int->s_vaddr =
970 GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
971 scnhdr_int->s_paddr =
972 GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
973 scnhdr_int->s_size =
974 GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
975 scnhdr_int->s_scnptr =
976 GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
977 scnhdr_int->s_relptr =
978 GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
979 scnhdr_int->s_lnnoptr =
980 GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
981 scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
982
983 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
984 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
985
986 if (scnhdr_int->s_vaddr != 0)
987 {
988 scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
989 }
990 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
991 {
992 scnhdr_int->s_size = scnhdr_int->s_paddr;
993 scnhdr_int->s_paddr = 0;
994 }
995 }
996
997 static unsigned int
998 coff_swap_scnhdr_out (abfd, in, out)
999 bfd *abfd;
1000 PTR in;
1001 PTR out;
1002 {
1003 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
1004 SCNHDR *scnhdr_ext = (SCNHDR *)out;
1005 unsigned int ret = sizeof (SCNHDR);
1006 bfd_vma ps;
1007 bfd_vma ss;
1008
1009 memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
1010
1011 PUT_SCNHDR_VADDR (abfd,
1012 (scnhdr_int->s_vaddr
1013 - pe_data(abfd)->pe_opthdr.ImageBase),
1014 (bfd_byte *) scnhdr_ext->s_vaddr);
1015
1016 /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1017 value except for the BSS section, its s_size should be 0 */
1018
1019
1020 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
1021 {
1022 ps = scnhdr_int->s_size;
1023 ss = 0;
1024 }
1025 else
1026 {
1027 ps = scnhdr_int->s_paddr;
1028 ss = scnhdr_int->s_size;
1029 }
1030
1031 PUT_SCNHDR_SIZE (abfd, ss,
1032 (bfd_byte *) scnhdr_ext->s_size);
1033
1034
1035 PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
1036
1037 PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
1038 (bfd_byte *) scnhdr_ext->s_scnptr);
1039 PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
1040 (bfd_byte *) scnhdr_ext->s_relptr);
1041 PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
1042 (bfd_byte *) scnhdr_ext->s_lnnoptr);
1043
1044 /* Extra flags must be set when dealing with NT. All sections should also
1045 have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
1046 .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1047 sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1048 (this is especially important when dealing with the .idata section since
1049 the addresses for routines from .dlls must be overwritten). If .reloc
1050 section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1051 (0x02000000). Also, the resource data should also be read and
1052 writable. */
1053
1054 /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1055 /* FIXME: even worse, I don't see how to get the original alignment field*/
1056 /* back... */
1057
1058 {
1059 int flags = scnhdr_int->s_flags;
1060 if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
1061 strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
1062 strcmp (scnhdr_int->s_name, ".rsrc") == 0 ||
1063 strcmp (scnhdr_int->s_name, ".bss") == 0)
1064 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1065 else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1066 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1067 else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1068 flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
1069 else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1070 flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
1071 else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1072 || strcmp (scnhdr_int->s_name, ".edata") == 0)
1073 flags = IMAGE_SCN_MEM_READ | SEC_DATA;
1074 /* ppc-nt additions */
1075 else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1076 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1077 IMAGE_SCN_MEM_READ ;
1078 /* Remember this field is a max of 8 chars, so the null is _not_ there
1079 for an 8 character name like ".reldata". (yep. Stupid bug) */
1080 else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
1081 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1082 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1083 else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1084 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1085 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1086 else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1087 flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1088 /* end of ppc-nt additions */
1089 #ifdef POWERPC_LE_PE
1090 else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0)
1091 {
1092 flags = IMAGE_SCN_LNK_INFO;
1093 }
1094 else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1095 {
1096 flags = IMAGE_SCN_LNK_INFO;
1097 }
1098 #endif
1099
1100 bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1101 }
1102
1103 if (scnhdr_int->s_nlnno <= 0xffff)
1104 bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1105 else
1106 {
1107 (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1108 bfd_get_filename (abfd),
1109 scnhdr_int->s_nlnno);
1110 bfd_set_error (bfd_error_file_truncated);
1111 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1112 ret = 0;
1113 }
1114 if (scnhdr_int->s_nreloc <= 0xffff)
1115 bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1116 else
1117 {
1118 (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1119 bfd_get_filename (abfd),
1120 scnhdr_int->s_nreloc);
1121 bfd_set_error (bfd_error_file_truncated);
1122 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1123 ret = 0;
1124 }
1125 return ret;
1126 }
1127
1128 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1129 {
1130 "Export Directory [.edata]",
1131 "Import Directory [parts of .idata]",
1132 "Resource Directory [.rsrc]",
1133 "Exception Directory [.pdata]",
1134 "Security Directory",
1135 "Base Relocation Directory [.reloc]",
1136 "Debug Directory",
1137 "Description Directory",
1138 "Special Directory",
1139 "Thread Storage Directory [.tls]",
1140 "Load Configuration Directory",
1141 "Bound Import Directory",
1142 "Import Address Table Directory",
1143 "Reserved",
1144 "Reserved",
1145 "Reserved"
1146 };
1147
1148 /**********************************************************************/
1149 static boolean
1150 pe_print_idata(abfd, vfile)
1151 bfd*abfd;
1152 void *vfile;
1153 {
1154 FILE *file = vfile;
1155 bfd_byte *data = 0;
1156 asection *section = bfd_get_section_by_name (abfd, ".idata");
1157
1158 #ifdef POWERPC_LE_PE
1159 asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1160 #endif
1161
1162 bfd_size_type datasize = 0;
1163 bfd_size_type i;
1164 bfd_size_type start, stop;
1165 int onaline = 20;
1166
1167 pe_data_type *pe = pe_data (abfd);
1168 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1169
1170 if (section == 0)
1171 return true;
1172
1173 #ifdef POWERPC_LE_PE
1174 if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1175 {
1176 /* The toc address can be found by taking the starting address,
1177 which on the PPC locates a function descriptor. The descriptor
1178 consists of the function code starting address followed by the
1179 address of the toc. The starting address we get from the bfd,
1180 and the descriptor is supposed to be in the .reldata section.
1181 */
1182
1183 bfd_vma loadable_toc_address;
1184 bfd_vma toc_address;
1185 bfd_vma start_address;
1186 bfd_byte *data = 0;
1187 int offset;
1188 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1189 rel_section));
1190 if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1191 return false;
1192
1193 datasize = bfd_section_size (abfd, rel_section);
1194
1195 bfd_get_section_contents (abfd,
1196 rel_section,
1197 (PTR) data, 0,
1198 bfd_section_size (abfd, rel_section));
1199
1200 offset = abfd->start_address - rel_section->vma;
1201
1202 start_address = bfd_get_32(abfd, data+offset);
1203 loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1204 toc_address = loadable_toc_address - 32768;
1205
1206 fprintf(file,
1207 "\nFunction descriptor located at the start address: %04lx\n",
1208 (unsigned long int) (abfd->start_address));
1209 fprintf (file,
1210 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
1211 start_address, loadable_toc_address, toc_address);
1212 }
1213 #endif
1214
1215 fprintf(file,
1216 "\nThe Import Tables (interpreted .idata section contents)\n");
1217 fprintf(file,
1218 " vma: Hint Time Forward DLL First\n");
1219 fprintf(file,
1220 " Table Stamp Chain Name Thunk\n");
1221
1222 if (bfd_section_size (abfd, section) == 0)
1223 return true;
1224
1225 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1226 datasize = bfd_section_size (abfd, section);
1227 if (data == NULL && datasize != 0)
1228 return false;
1229
1230 bfd_get_section_contents (abfd,
1231 section,
1232 (PTR) data, 0,
1233 bfd_section_size (abfd, section));
1234
1235 start = 0;
1236
1237 stop = bfd_section_size (abfd, section);
1238
1239 for (i = start; i < stop; i += onaline)
1240 {
1241 bfd_vma hint_addr;
1242 bfd_vma time_stamp;
1243 bfd_vma forward_chain;
1244 bfd_vma dll_name;
1245 bfd_vma first_thunk;
1246 int idx;
1247 int j;
1248 char *dll;
1249 int adj = extra->ImageBase - section->vma;
1250
1251 fprintf (file,
1252 " %04lx\t",
1253 (unsigned long int) (i + section->vma));
1254
1255 if (i+20 > stop)
1256 {
1257 /* check stuff */
1258 ;
1259 }
1260
1261 hint_addr = bfd_get_32(abfd, data+i);
1262 time_stamp = bfd_get_32(abfd, data+i+4);
1263 forward_chain = bfd_get_32(abfd, data+i+8);
1264 dll_name = bfd_get_32(abfd, data+i+12);
1265 first_thunk = bfd_get_32(abfd, data+i+16);
1266
1267 fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1268 hint_addr,
1269 time_stamp,
1270 forward_chain,
1271 dll_name,
1272 first_thunk);
1273
1274 if (hint_addr ==0)
1275 {
1276 break;
1277 }
1278
1279 /* the image base is present in the section->vma */
1280 dll = data + dll_name + adj;
1281 fprintf(file, "\n\tDLL Name: %s\n", dll);
1282 fprintf(file, "\tvma: Ordinal Member-Name\n");
1283
1284 idx = hint_addr + adj;
1285
1286 for (j=0;j<stop;j+=4)
1287 {
1288 int ordinal;
1289 char *member_name;
1290 bfd_vma member = bfd_get_32(abfd, data + idx + j);
1291 if (member == 0)
1292 break;
1293 ordinal = bfd_get_16(abfd,
1294 data + member + adj);
1295 member_name = data + member + adj + 2;
1296 fprintf(file, "\t%04lx\t %4d %s\n",
1297 member, ordinal, member_name);
1298 }
1299
1300 if (hint_addr != first_thunk)
1301 {
1302 int differ = 0;
1303 int idx2;
1304
1305 idx2 = first_thunk + adj;
1306
1307 for (j=0;j<stop;j+=4)
1308 {
1309 int ordinal;
1310 char *member_name;
1311 bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1312 bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1313 if (hint_member != iat_member)
1314 {
1315 if (differ == 0)
1316 {
1317 fprintf(file,
1318 "\tThe Import Address Table (difference found)\n");
1319 fprintf(file, "\tvma: Ordinal Member-Name\n");
1320 differ = 1;
1321 }
1322 if (iat_member == 0)
1323 {
1324 fprintf(file,
1325 "\t>>> Ran out of IAT members!\n");
1326 }
1327 else
1328 {
1329 ordinal = bfd_get_16(abfd,
1330 data + iat_member + adj);
1331 member_name = data + iat_member + adj + 2;
1332 fprintf(file, "\t%04lx\t %4d %s\n",
1333 iat_member, ordinal, member_name);
1334 }
1335 break;
1336 }
1337 if (hint_member == 0)
1338 break;
1339 }
1340 if (differ == 0)
1341 {
1342 fprintf(file,
1343 "\tThe Import Address Table is identical\n");
1344 }
1345 }
1346
1347 fprintf(file, "\n");
1348
1349 }
1350
1351 free (data);
1352
1353 return true;
1354 }
1355
1356 static boolean
1357 pe_print_edata(abfd, vfile)
1358 bfd*abfd;
1359 void *vfile;
1360 {
1361 FILE *file = vfile;
1362 bfd_byte *data = 0;
1363 asection *section = bfd_get_section_by_name (abfd, ".edata");
1364
1365 bfd_size_type datasize = 0;
1366 bfd_size_type i;
1367
1368 int adj;
1369 struct EDT_type
1370 {
1371 long export_flags; /* reserved - should be zero */
1372 long time_stamp;
1373 short major_ver;
1374 short minor_ver;
1375 bfd_vma name; /* rva - relative to image base */
1376 long base; /* ordinal base */
1377 long num_functions; /* Number in the export address table */
1378 long num_names; /* Number in the name pointer table */
1379 bfd_vma eat_addr; /* rva to the export address table */
1380 bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
1381 bfd_vma ot_addr; /* rva to the Ordinal Table */
1382 } edt;
1383
1384 pe_data_type *pe = pe_data (abfd);
1385 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1386
1387 if (section == 0)
1388 return true;
1389
1390 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1391 section));
1392 datasize = bfd_section_size (abfd, section);
1393
1394 if (data == NULL && datasize != 0)
1395 return false;
1396
1397 bfd_get_section_contents (abfd,
1398 section,
1399 (PTR) data, 0,
1400 bfd_section_size (abfd, section));
1401
1402 /* Go get Export Directory Table */
1403 edt.export_flags = bfd_get_32(abfd, data+0);
1404 edt.time_stamp = bfd_get_32(abfd, data+4);
1405 edt.major_ver = bfd_get_16(abfd, data+8);
1406 edt.minor_ver = bfd_get_16(abfd, data+10);
1407 edt.name = bfd_get_32(abfd, data+12);
1408 edt.base = bfd_get_32(abfd, data+16);
1409 edt.num_functions = bfd_get_32(abfd, data+20);
1410 edt.num_names = bfd_get_32(abfd, data+24);
1411 edt.eat_addr = bfd_get_32(abfd, data+28);
1412 edt.npt_addr = bfd_get_32(abfd, data+32);
1413 edt.ot_addr = bfd_get_32(abfd, data+36);
1414
1415 adj = extra->ImageBase - section->vma;
1416
1417
1418 /* Dump the EDT first first */
1419 fprintf(file,
1420 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1421
1422 fprintf(file,
1423 "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1424
1425 fprintf(file,
1426 "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1427
1428 fprintf(file,
1429 "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1430
1431 fprintf (file,
1432 "Name \t\t\t\t");
1433 fprintf_vma (file, edt.name);
1434 fprintf (file,
1435 "%s\n", data + edt.name + adj);
1436
1437 fprintf(file,
1438 "Ordinal Base \t\t\t%ld\n", edt.base);
1439
1440 fprintf(file,
1441 "Number in:\n");
1442
1443 fprintf(file,
1444 "\tExport Address Table \t\t%lx\n",
1445 (unsigned long) edt.num_functions);
1446
1447 fprintf(file,
1448 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1449
1450 fprintf(file,
1451 "Table Addresses\n");
1452
1453 fprintf (file,
1454 "\tExport Address Table \t\t");
1455 fprintf_vma (file, edt.eat_addr);
1456 fprintf (file, "\n");
1457
1458 fprintf (file,
1459 "\tName Pointer Table \t\t");
1460 fprintf_vma (file, edt.npt_addr);
1461 fprintf (file, "\n");
1462
1463 fprintf (file,
1464 "\tOrdinal Table \t\t\t");
1465 fprintf_vma (file, edt.ot_addr);
1466 fprintf (file, "\n");
1467
1468
1469 /* The next table to find si the Export Address Table. It's basically
1470 a list of pointers that either locate a function in this dll, or
1471 forward the call to another dll. Something like:
1472 typedef union
1473 {
1474 long export_rva;
1475 long forwarder_rva;
1476 } export_address_table_entry;
1477 */
1478
1479 fprintf(file,
1480 "\nExport Address Table -- Ordinal Base %ld\n",
1481 edt.base);
1482
1483 for (i = 0; i < edt.num_functions; ++i)
1484 {
1485 bfd_vma eat_member = bfd_get_32(abfd,
1486 data + edt.eat_addr + (i*4) + adj);
1487 bfd_vma eat_actual = extra->ImageBase + eat_member;
1488 bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1489 bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1490
1491
1492 if (eat_member == 0)
1493 continue;
1494
1495 if (edata_start < eat_actual && eat_actual < edata_end)
1496 {
1497 /* this rva is to a name (forwarding function) in our section */
1498 /* Should locate a function descriptor */
1499 fprintf(file,
1500 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1501 (long) i, (long) (i + edt.base), eat_member,
1502 "Forwarder RVA", data + eat_member + adj);
1503 }
1504 else
1505 {
1506 /* Should locate a function descriptor in the reldata section */
1507 fprintf(file,
1508 "\t[%4ld] +base[%4ld] %04lx %s\n",
1509 (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1510 }
1511 }
1512
1513 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1514 /* Dump them in parallel for clarity */
1515 fprintf(file,
1516 "\n[Ordinal/Name Pointer] Table\n");
1517
1518 for (i = 0; i < edt.num_names; ++i)
1519 {
1520 bfd_vma name_ptr = bfd_get_32(abfd,
1521 data +
1522 edt.npt_addr
1523 + (i*4) + adj);
1524
1525 char *name = data + name_ptr + adj;
1526
1527 bfd_vma ord = bfd_get_16(abfd,
1528 data +
1529 edt.ot_addr
1530 + (i*2) + adj);
1531 fprintf(file,
1532 "\t[%4ld] %s\n", (long) ord, name);
1533
1534 }
1535
1536 free (data);
1537
1538 return true;
1539 }
1540
1541 static boolean
1542 pe_print_pdata(abfd, vfile)
1543 bfd*abfd;
1544 void *vfile;
1545 {
1546 FILE *file = vfile;
1547 bfd_byte *data = 0;
1548 asection *section = bfd_get_section_by_name (abfd, ".pdata");
1549 bfd_size_type datasize = 0;
1550 bfd_size_type i;
1551 bfd_size_type start, stop;
1552 int onaline = 20;
1553
1554 if (section == 0)
1555 return true;
1556
1557 stop = bfd_section_size (abfd, section);
1558 if ((stop % onaline) != 0)
1559 fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1560 (long)stop, onaline);
1561
1562 fprintf(file,
1563 "\nThe Function Table (interpreted .pdata section contents)\n");
1564 fprintf(file,
1565 " vma:\t\tBegin End EH EH PrologEnd\n");
1566 fprintf(file,
1567 " \t\tAddress Address Handler Data Address\n");
1568
1569 if (bfd_section_size (abfd, section) == 0)
1570 return true;
1571
1572 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1573 datasize = bfd_section_size (abfd, section);
1574 if (data == NULL && datasize != 0)
1575 return false;
1576
1577 bfd_get_section_contents (abfd,
1578 section,
1579 (PTR) data, 0,
1580 bfd_section_size (abfd, section));
1581
1582 start = 0;
1583
1584 for (i = start; i < stop; i += onaline)
1585 {
1586 bfd_vma begin_addr;
1587 bfd_vma end_addr;
1588 bfd_vma eh_handler;
1589 bfd_vma eh_data;
1590 bfd_vma prolog_end_addr;
1591
1592 if (i+20 > stop)
1593 break;
1594
1595 begin_addr = bfd_get_32(abfd, data+i);
1596 end_addr = bfd_get_32(abfd, data+i+4);
1597 eh_handler = bfd_get_32(abfd, data+i+8);
1598 eh_data = bfd_get_32(abfd, data+i+12);
1599 prolog_end_addr = bfd_get_32(abfd, data+i+16);
1600
1601 if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1602 && eh_data == 0 && prolog_end_addr == 0)
1603 {
1604 /* We are probably into the padding of the
1605 section now */
1606 break;
1607 }
1608
1609 fprintf (file,
1610 " %08lx\t",
1611 (unsigned long int) (i + section->vma));
1612
1613 fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1614 begin_addr,
1615 end_addr,
1616 eh_handler,
1617 eh_data,
1618 prolog_end_addr);
1619
1620 #ifdef POWERPC_LE_PE
1621 if (eh_handler == 0 && eh_data != 0)
1622 {
1623 /* Special bits here, although the meaning may */
1624 /* be a little mysterious. The only one I know */
1625 /* for sure is 0x03. */
1626 /* Code Significance */
1627 /* 0x00 None */
1628 /* 0x01 Register Save Millicode */
1629 /* 0x02 Register Restore Millicode */
1630 /* 0x03 Glue Code Sequence */
1631 switch (eh_data)
1632 {
1633 case 0x01:
1634 fprintf(file, " Register save millicode");
1635 break;
1636 case 0x02:
1637 fprintf(file, " Register restore millicode");
1638 break;
1639 case 0x03:
1640 fprintf(file, " Glue code sequence");
1641 break;
1642 default:
1643 break;
1644 }
1645 }
1646 #endif
1647 fprintf(file, "\n");
1648 }
1649
1650 free (data);
1651
1652 return true;
1653 }
1654
1655 static const char *tbl[6] =
1656 {
1657 "ABSOLUTE",
1658 "HIGH",
1659 "LOW",
1660 "HIGHLOW",
1661 "HIGHADJ",
1662 "unknown"
1663 };
1664
1665 static boolean
1666 pe_print_reloc(abfd, vfile)
1667 bfd*abfd;
1668 void *vfile;
1669 {
1670 FILE *file = vfile;
1671 bfd_byte *data = 0;
1672 asection *section = bfd_get_section_by_name (abfd, ".reloc");
1673 bfd_size_type datasize = 0;
1674 bfd_size_type i;
1675 bfd_size_type start, stop;
1676
1677 if (section == 0)
1678 return true;
1679
1680 if (bfd_section_size (abfd, section) == 0)
1681 return true;
1682
1683 fprintf(file,
1684 "\n\nPE File Base Relocations (interpreted .reloc"
1685 " section contents)\n");
1686
1687 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1688 datasize = bfd_section_size (abfd, section);
1689 if (data == NULL && datasize != 0)
1690 return false;
1691
1692 bfd_get_section_contents (abfd,
1693 section,
1694 (PTR) data, 0,
1695 bfd_section_size (abfd, section));
1696
1697 start = 0;
1698
1699 stop = bfd_section_size (abfd, section);
1700
1701 for (i = start; i < stop;)
1702 {
1703 int j;
1704 bfd_vma virtual_address;
1705 long number, size;
1706
1707 /* The .reloc section is a sequence of blocks, with a header consisting
1708 of two 32 bit quantities, followed by a number of 16 bit entries */
1709
1710 virtual_address = bfd_get_32(abfd, data+i);
1711 size = bfd_get_32(abfd, data+i+4);
1712 number = (size - 8) / 2;
1713
1714 if (size == 0)
1715 {
1716 break;
1717 }
1718
1719 fprintf (file,
1720 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1721 virtual_address, size, size, number);
1722
1723 for (j = 0; j < number; ++j)
1724 {
1725 unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1726 int t = (e & 0xF000) >> 12;
1727 int off = e & 0x0FFF;
1728
1729 if (t > 5)
1730 abort();
1731
1732 fprintf(file,
1733 "\treloc %4d offset %4x [%4lx] %s\n",
1734 j, off, (long) (off + virtual_address), tbl[t]);
1735
1736 }
1737 i += size;
1738 }
1739
1740 free (data);
1741
1742 return true;
1743 }
1744
1745 static boolean
1746 pe_print_private_bfd_data (abfd, vfile)
1747 bfd *abfd;
1748 PTR vfile;
1749 {
1750 FILE *file = (FILE *) vfile;
1751 int j;
1752 pe_data_type *pe = pe_data (abfd);
1753 struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1754
1755 fprintf (file,"\nImageBase\t\t");
1756 fprintf_vma (file, i->ImageBase);
1757 fprintf (file,"\nSectionAlignment\t");
1758 fprintf_vma (file, i->SectionAlignment);
1759 fprintf (file,"\nFileAlignment\t\t");
1760 fprintf_vma (file, i->FileAlignment);
1761 fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1762 fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1763 fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1764 fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1765 fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1766 fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1767 fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1768 fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1769 fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1770 fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1771 fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1772 fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1773 fprintf (file,"SizeOfStackReserve\t");
1774 fprintf_vma (file, i->SizeOfStackReserve);
1775 fprintf (file,"\nSizeOfStackCommit\t");
1776 fprintf_vma (file, i->SizeOfStackCommit);
1777 fprintf (file,"\nSizeOfHeapReserve\t");
1778 fprintf_vma (file, i->SizeOfHeapReserve);
1779 fprintf (file,"\nSizeOfHeapCommit\t");
1780 fprintf_vma (file, i->SizeOfHeapCommit);
1781 fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1782 fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1783
1784 fprintf (file,"\nThe Data Directory\n");
1785 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1786 {
1787 fprintf (file, "Entry %1x ", j);
1788 fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1789 fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1790 fprintf (file, "%s\n", dir_names[j]);
1791 }
1792
1793 pe_print_idata(abfd, vfile);
1794 pe_print_edata(abfd, vfile);
1795 pe_print_pdata(abfd, vfile);
1796 pe_print_reloc(abfd, vfile);
1797
1798 return true;
1799 }
1800
1801 static boolean
1802 pe_mkobject (abfd)
1803 bfd * abfd;
1804 {
1805 pe_data_type *pe;
1806 abfd->tdata.pe_obj_data =
1807 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1808
1809 if (abfd->tdata.pe_obj_data == 0)
1810 return false;
1811
1812 pe = pe_data (abfd);
1813
1814 pe->coff.pe = 1;
1815 pe->in_reloc_p = in_reloc_p;
1816 return true;
1817 }
1818
1819 /* Create the COFF backend specific information. */
1820 static PTR
1821 pe_mkobject_hook (abfd, filehdr, aouthdr)
1822 bfd * abfd;
1823 PTR filehdr;
1824 PTR aouthdr;
1825 {
1826 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1827 pe_data_type *pe;
1828
1829 if (pe_mkobject (abfd) == false)
1830 return NULL;
1831
1832 pe = pe_data (abfd);
1833 pe->coff.sym_filepos = internal_f->f_symptr;
1834 /* These members communicate important constants about the symbol
1835 table to GDB's symbol-reading code. These `constants'
1836 unfortunately vary among coff implementations... */
1837 pe->coff.local_n_btmask = N_BTMASK;
1838 pe->coff.local_n_btshft = N_BTSHFT;
1839 pe->coff.local_n_tmask = N_TMASK;
1840 pe->coff.local_n_tshift = N_TSHIFT;
1841 pe->coff.local_symesz = SYMESZ;
1842 pe->coff.local_auxesz = AUXESZ;
1843 pe->coff.local_linesz = LINESZ;
1844
1845 obj_raw_syment_count (abfd) =
1846 obj_conv_table_size (abfd) =
1847 internal_f->f_nsyms;
1848
1849 pe->real_flags = internal_f->f_flags;
1850
1851 #ifdef COFF_IMAGE_WITH_PE
1852 if (aouthdr)
1853 {
1854 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1855 }
1856 #endif
1857
1858 return (PTR) pe;
1859 }
1860
1861
1862
1863 /* Copy any private info we understand from the input bfd
1864 to the output bfd. */
1865
1866 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1867
1868 static boolean
1869 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1870 bfd *ibfd, *obfd;
1871 {
1872 /* One day we may try to grok other private data. */
1873 if (ibfd->xvec->flavour != bfd_target_coff_flavour
1874 || obfd->xvec->flavour != bfd_target_coff_flavour)
1875 return true;
1876
1877 pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1878
1879 return true;
1880 }
This page took 0.077186 seconds and 4 git commands to generate.