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