4e937cfba63e06669de752a6094535e0fc00f291
[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 = sec->_cooked_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 /* ppc-nt additions */
1069 else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1070 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1071 IMAGE_SCN_MEM_READ ;
1072 /* Remember this field is a max of 8 chars, so the null is _not_ there
1073 for an 8 character name like ".reldata". (yep. Stupid bug) */
1074 else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
1075 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1076 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1077 else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1078 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1079 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1080 else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1081 flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1082 /* end of ppc-nt additions */
1083 #ifdef POWERPC_LE_PE
1084 else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0)
1085 {
1086 flags = IMAGE_SCN_LNK_INFO;
1087 }
1088 else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1089 {
1090 flags = IMAGE_SCN_LNK_INFO;
1091 }
1092 #endif
1093
1094 bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1095 }
1096
1097 if (scnhdr_int->s_nlnno <= 0xffff)
1098 bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1099 else
1100 {
1101 (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1102 bfd_get_filename (abfd),
1103 scnhdr_int->s_nlnno);
1104 bfd_set_error (bfd_error_file_truncated);
1105 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1106 ret = 0;
1107 }
1108 if (scnhdr_int->s_nreloc <= 0xffff)
1109 bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1110 else
1111 {
1112 (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1113 bfd_get_filename (abfd),
1114 scnhdr_int->s_nreloc);
1115 bfd_set_error (bfd_error_file_truncated);
1116 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1117 ret = 0;
1118 }
1119 return ret;
1120 }
1121
1122 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1123 {
1124 "Export Directory [.edata]",
1125 "Import Directory [parts of .idata]",
1126 "Resource Directory [.rsrc]",
1127 "Exception Directory [.pdata]",
1128 "Security Directory",
1129 "Base Relocation Directory [.reloc]",
1130 "Debug Directory",
1131 "Description Directory",
1132 "Special Directory",
1133 "Thread Storage Directory [.tls]",
1134 "Load Configuration Directory",
1135 "Bound Import Directory",
1136 "Import Address Table Directory",
1137 "Reserved",
1138 "Reserved",
1139 "Reserved"
1140 };
1141
1142 /**********************************************************************/
1143 static boolean
1144 pe_print_idata(abfd, vfile)
1145 bfd*abfd;
1146 void *vfile;
1147 {
1148 FILE *file = vfile;
1149 bfd_byte *data = 0;
1150 asection *section = bfd_get_section_by_name (abfd, ".idata");
1151
1152 #ifdef POWERPC_LE_PE
1153 asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1154 #endif
1155
1156 bfd_size_type datasize = 0;
1157 bfd_size_type i;
1158 bfd_size_type start, stop;
1159 int onaline = 20;
1160
1161 pe_data_type *pe = pe_data (abfd);
1162 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1163
1164 if (section == 0)
1165 return true;
1166
1167 #ifdef POWERPC_LE_PE
1168 if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1169 {
1170 /* The toc address can be found by taking the starting address,
1171 which on the PPC locates a function descriptor. The descriptor
1172 consists of the function code starting address followed by the
1173 address of the toc. The starting address we get from the bfd,
1174 and the descriptor is supposed to be in the .reldata section.
1175 */
1176
1177 bfd_vma loadable_toc_address;
1178 bfd_vma toc_address;
1179 bfd_vma start_address;
1180 bfd_byte *data = 0;
1181 int offset;
1182 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1183 rel_section));
1184 if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1185 return false;
1186
1187 datasize = bfd_section_size (abfd, rel_section);
1188
1189 bfd_get_section_contents (abfd,
1190 rel_section,
1191 (PTR) data, 0,
1192 bfd_section_size (abfd, rel_section));
1193
1194 offset = abfd->start_address - rel_section->vma;
1195
1196 start_address = bfd_get_32(abfd, data+offset);
1197 loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1198 toc_address = loadable_toc_address - 32768;
1199
1200 fprintf(file,
1201 "\nFunction descriptor located at the start address: %04lx\n",
1202 (unsigned long int) (abfd->start_address));
1203 fprintf (file,
1204 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
1205 start_address, loadable_toc_address, toc_address);
1206 }
1207 #endif
1208
1209 fprintf(file,
1210 "\nThe Import Tables (interpreted .idata section contents)\n");
1211 fprintf(file,
1212 " vma: Hint Time Forward DLL First\n");
1213 fprintf(file,
1214 " Table Stamp Chain Name Thunk\n");
1215
1216 if (bfd_section_size (abfd, section) == 0)
1217 return true;
1218
1219 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1220 datasize = bfd_section_size (abfd, section);
1221 if (data == NULL && datasize != 0)
1222 return false;
1223
1224 bfd_get_section_contents (abfd,
1225 section,
1226 (PTR) data, 0,
1227 bfd_section_size (abfd, section));
1228
1229 start = 0;
1230
1231 stop = bfd_section_size (abfd, section);
1232
1233 for (i = start; i < stop; i += onaline)
1234 {
1235 bfd_vma hint_addr;
1236 bfd_vma time_stamp;
1237 bfd_vma forward_chain;
1238 bfd_vma dll_name;
1239 bfd_vma first_thunk;
1240 int idx;
1241 int j;
1242 char *dll;
1243 int adj = extra->ImageBase - section->vma;
1244
1245 fprintf (file,
1246 " %04lx\t",
1247 (unsigned long int) (i + section->vma));
1248
1249 if (i+20 > stop)
1250 {
1251 /* check stuff */
1252 ;
1253 }
1254
1255 hint_addr = bfd_get_32(abfd, data+i);
1256 time_stamp = bfd_get_32(abfd, data+i+4);
1257 forward_chain = bfd_get_32(abfd, data+i+8);
1258 dll_name = bfd_get_32(abfd, data+i+12);
1259 first_thunk = bfd_get_32(abfd, data+i+16);
1260
1261 fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1262 hint_addr,
1263 time_stamp,
1264 forward_chain,
1265 dll_name,
1266 first_thunk);
1267
1268 if (hint_addr ==0)
1269 {
1270 break;
1271 }
1272
1273 /* the image base is present in the section->vma */
1274 dll = (char *) data + dll_name + adj;
1275 fprintf(file, "\n\tDLL Name: %s\n", dll);
1276 fprintf(file, "\tvma: Ordinal Member-Name\n");
1277
1278 idx = hint_addr + adj;
1279
1280 for (j=0;j<stop;j+=4)
1281 {
1282 int ordinal;
1283 char *member_name;
1284 bfd_vma member = bfd_get_32(abfd, data + idx + j);
1285 if (member == 0)
1286 break;
1287 ordinal = bfd_get_16(abfd,
1288 data + member + adj);
1289 member_name = (char *) data + member + adj + 2;
1290 fprintf(file, "\t%04lx\t %4d %s\n",
1291 member, ordinal, member_name);
1292 }
1293
1294 if (hint_addr != first_thunk)
1295 {
1296 int differ = 0;
1297 int idx2;
1298
1299 idx2 = first_thunk + adj;
1300
1301 for (j=0;j<stop;j+=4)
1302 {
1303 int ordinal;
1304 char *member_name;
1305 bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1306 bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1307 if (hint_member != iat_member)
1308 {
1309 if (differ == 0)
1310 {
1311 fprintf(file,
1312 "\tThe Import Address Table (difference found)\n");
1313 fprintf(file, "\tvma: Ordinal Member-Name\n");
1314 differ = 1;
1315 }
1316 if (iat_member == 0)
1317 {
1318 fprintf(file,
1319 "\t>>> Ran out of IAT members!\n");
1320 }
1321 else
1322 {
1323 ordinal = bfd_get_16(abfd,
1324 data + iat_member + adj);
1325 member_name = (char *) data + iat_member + adj + 2;
1326 fprintf(file, "\t%04lx\t %4d %s\n",
1327 iat_member, ordinal, member_name);
1328 }
1329 break;
1330 }
1331 if (hint_member == 0)
1332 break;
1333 }
1334 if (differ == 0)
1335 {
1336 fprintf(file,
1337 "\tThe Import Address Table is identical\n");
1338 }
1339 }
1340
1341 fprintf(file, "\n");
1342
1343 }
1344
1345 free (data);
1346
1347 return true;
1348 }
1349
1350 static boolean
1351 pe_print_edata(abfd, vfile)
1352 bfd*abfd;
1353 void *vfile;
1354 {
1355 FILE *file = vfile;
1356 bfd_byte *data = 0;
1357 asection *section = bfd_get_section_by_name (abfd, ".edata");
1358
1359 bfd_size_type datasize = 0;
1360 bfd_size_type i;
1361
1362 int adj;
1363 struct EDT_type
1364 {
1365 long export_flags; /* reserved - should be zero */
1366 long time_stamp;
1367 short major_ver;
1368 short minor_ver;
1369 bfd_vma name; /* rva - relative to image base */
1370 long base; /* ordinal base */
1371 long num_functions; /* Number in the export address table */
1372 long num_names; /* Number in the name pointer table */
1373 bfd_vma eat_addr; /* rva to the export address table */
1374 bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
1375 bfd_vma ot_addr; /* rva to the Ordinal Table */
1376 } edt;
1377
1378 pe_data_type *pe = pe_data (abfd);
1379 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1380
1381 if (section == 0)
1382 return true;
1383
1384 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1385 section));
1386 datasize = bfd_section_size (abfd, section);
1387
1388 if (data == NULL && datasize != 0)
1389 return false;
1390
1391 bfd_get_section_contents (abfd,
1392 section,
1393 (PTR) data, 0,
1394 bfd_section_size (abfd, section));
1395
1396 /* Go get Export Directory Table */
1397 edt.export_flags = bfd_get_32(abfd, data+0);
1398 edt.time_stamp = bfd_get_32(abfd, data+4);
1399 edt.major_ver = bfd_get_16(abfd, data+8);
1400 edt.minor_ver = bfd_get_16(abfd, data+10);
1401 edt.name = bfd_get_32(abfd, data+12);
1402 edt.base = bfd_get_32(abfd, data+16);
1403 edt.num_functions = bfd_get_32(abfd, data+20);
1404 edt.num_names = bfd_get_32(abfd, data+24);
1405 edt.eat_addr = bfd_get_32(abfd, data+28);
1406 edt.npt_addr = bfd_get_32(abfd, data+32);
1407 edt.ot_addr = bfd_get_32(abfd, data+36);
1408
1409 adj = extra->ImageBase - section->vma;
1410
1411
1412 /* Dump the EDT first first */
1413 fprintf(file,
1414 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1415
1416 fprintf(file,
1417 "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1418
1419 fprintf(file,
1420 "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1421
1422 fprintf(file,
1423 "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1424
1425 fprintf (file,
1426 "Name \t\t\t\t");
1427 fprintf_vma (file, edt.name);
1428 fprintf (file,
1429 "%s\n", data + edt.name + adj);
1430
1431 fprintf(file,
1432 "Ordinal Base \t\t\t%ld\n", edt.base);
1433
1434 fprintf(file,
1435 "Number in:\n");
1436
1437 fprintf(file,
1438 "\tExport Address Table \t\t%lx\n",
1439 (unsigned long) edt.num_functions);
1440
1441 fprintf(file,
1442 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1443
1444 fprintf(file,
1445 "Table Addresses\n");
1446
1447 fprintf (file,
1448 "\tExport Address Table \t\t");
1449 fprintf_vma (file, edt.eat_addr);
1450 fprintf (file, "\n");
1451
1452 fprintf (file,
1453 "\tName Pointer Table \t\t");
1454 fprintf_vma (file, edt.npt_addr);
1455 fprintf (file, "\n");
1456
1457 fprintf (file,
1458 "\tOrdinal Table \t\t\t");
1459 fprintf_vma (file, edt.ot_addr);
1460 fprintf (file, "\n");
1461
1462
1463 /* The next table to find si the Export Address Table. It's basically
1464 a list of pointers that either locate a function in this dll, or
1465 forward the call to another dll. Something like:
1466 typedef union
1467 {
1468 long export_rva;
1469 long forwarder_rva;
1470 } export_address_table_entry;
1471 */
1472
1473 fprintf(file,
1474 "\nExport Address Table -- Ordinal Base %ld\n",
1475 edt.base);
1476
1477 for (i = 0; i < edt.num_functions; ++i)
1478 {
1479 bfd_vma eat_member = bfd_get_32(abfd,
1480 data + edt.eat_addr + (i*4) + adj);
1481 bfd_vma eat_actual = extra->ImageBase + eat_member;
1482 bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1483 bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1484
1485
1486 if (eat_member == 0)
1487 continue;
1488
1489 if (edata_start < eat_actual && eat_actual < edata_end)
1490 {
1491 /* this rva is to a name (forwarding function) in our section */
1492 /* Should locate a function descriptor */
1493 fprintf(file,
1494 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1495 (long) i, (long) (i + edt.base), eat_member,
1496 "Forwarder RVA", data + eat_member + adj);
1497 }
1498 else
1499 {
1500 /* Should locate a function descriptor in the reldata section */
1501 fprintf(file,
1502 "\t[%4ld] +base[%4ld] %04lx %s\n",
1503 (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1504 }
1505 }
1506
1507 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1508 /* Dump them in parallel for clarity */
1509 fprintf(file,
1510 "\n[Ordinal/Name Pointer] Table\n");
1511
1512 for (i = 0; i < edt.num_names; ++i)
1513 {
1514 bfd_vma name_ptr = bfd_get_32(abfd,
1515 data +
1516 edt.npt_addr
1517 + (i*4) + adj);
1518
1519 char *name = (char *) data + name_ptr + adj;
1520
1521 bfd_vma ord = bfd_get_16(abfd,
1522 data +
1523 edt.ot_addr
1524 + (i*2) + adj);
1525 fprintf(file,
1526 "\t[%4ld] %s\n", (long) ord, name);
1527
1528 }
1529
1530 free (data);
1531
1532 return true;
1533 }
1534
1535 static boolean
1536 pe_print_pdata(abfd, vfile)
1537 bfd*abfd;
1538 void *vfile;
1539 {
1540 FILE *file = vfile;
1541 bfd_byte *data = 0;
1542 asection *section = bfd_get_section_by_name (abfd, ".pdata");
1543 bfd_size_type datasize = 0;
1544 bfd_size_type i;
1545 bfd_size_type start, stop;
1546 int onaline = 20;
1547
1548 if (section == 0)
1549 return true;
1550
1551 stop = bfd_section_size (abfd, section);
1552 if ((stop % onaline) != 0)
1553 fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1554 (long)stop, onaline);
1555
1556 fprintf(file,
1557 "\nThe Function Table (interpreted .pdata section contents)\n");
1558 fprintf(file,
1559 " vma:\t\tBegin End EH EH PrologEnd\n");
1560 fprintf(file,
1561 " \t\tAddress Address Handler Data Address\n");
1562
1563 if (bfd_section_size (abfd, section) == 0)
1564 return true;
1565
1566 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1567 datasize = bfd_section_size (abfd, section);
1568 if (data == NULL && datasize != 0)
1569 return false;
1570
1571 bfd_get_section_contents (abfd,
1572 section,
1573 (PTR) data, 0,
1574 bfd_section_size (abfd, section));
1575
1576 start = 0;
1577
1578 for (i = start; i < stop; i += onaline)
1579 {
1580 bfd_vma begin_addr;
1581 bfd_vma end_addr;
1582 bfd_vma eh_handler;
1583 bfd_vma eh_data;
1584 bfd_vma prolog_end_addr;
1585
1586 if (i+20 > stop)
1587 break;
1588
1589 begin_addr = bfd_get_32(abfd, data+i);
1590 end_addr = bfd_get_32(abfd, data+i+4);
1591 eh_handler = bfd_get_32(abfd, data+i+8);
1592 eh_data = bfd_get_32(abfd, data+i+12);
1593 prolog_end_addr = bfd_get_32(abfd, data+i+16);
1594
1595 if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1596 && eh_data == 0 && prolog_end_addr == 0)
1597 {
1598 /* We are probably into the padding of the
1599 section now */
1600 break;
1601 }
1602
1603 fprintf (file,
1604 " %08lx\t",
1605 (unsigned long int) (i + section->vma));
1606
1607 fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1608 begin_addr,
1609 end_addr,
1610 eh_handler,
1611 eh_data,
1612 prolog_end_addr);
1613
1614 #ifdef POWERPC_LE_PE
1615 if (eh_handler == 0 && eh_data != 0)
1616 {
1617 /* Special bits here, although the meaning may */
1618 /* be a little mysterious. The only one I know */
1619 /* for sure is 0x03. */
1620 /* Code Significance */
1621 /* 0x00 None */
1622 /* 0x01 Register Save Millicode */
1623 /* 0x02 Register Restore Millicode */
1624 /* 0x03 Glue Code Sequence */
1625 switch (eh_data)
1626 {
1627 case 0x01:
1628 fprintf(file, " Register save millicode");
1629 break;
1630 case 0x02:
1631 fprintf(file, " Register restore millicode");
1632 break;
1633 case 0x03:
1634 fprintf(file, " Glue code sequence");
1635 break;
1636 default:
1637 break;
1638 }
1639 }
1640 #endif
1641 fprintf(file, "\n");
1642 }
1643
1644 free (data);
1645
1646 return true;
1647 }
1648
1649 static const char *tbl[6] =
1650 {
1651 "ABSOLUTE",
1652 "HIGH",
1653 "LOW",
1654 "HIGHLOW",
1655 "HIGHADJ",
1656 "unknown"
1657 };
1658
1659 static boolean
1660 pe_print_reloc(abfd, vfile)
1661 bfd*abfd;
1662 void *vfile;
1663 {
1664 FILE *file = vfile;
1665 bfd_byte *data = 0;
1666 asection *section = bfd_get_section_by_name (abfd, ".reloc");
1667 bfd_size_type datasize = 0;
1668 bfd_size_type i;
1669 bfd_size_type start, stop;
1670
1671 if (section == 0)
1672 return true;
1673
1674 if (bfd_section_size (abfd, section) == 0)
1675 return true;
1676
1677 fprintf(file,
1678 "\n\nPE File Base Relocations (interpreted .reloc section contents)\n");
1679
1680 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1681 datasize = bfd_section_size (abfd, section);
1682 if (data == NULL && datasize != 0)
1683 return false;
1684
1685 bfd_get_section_contents (abfd,
1686 section,
1687 (PTR) data, 0,
1688 bfd_section_size (abfd, section));
1689
1690 start = 0;
1691
1692 stop = bfd_section_size (abfd, section);
1693
1694 for (i = start; i < stop;)
1695 {
1696 int j;
1697 bfd_vma virtual_address;
1698 long number, size;
1699
1700 /* The .reloc section is a sequence of blocks, with a header consisting
1701 of two 32 bit quantities, followed by a number of 16 bit entries */
1702
1703 virtual_address = bfd_get_32(abfd, data+i);
1704 size = bfd_get_32(abfd, data+i+4);
1705 number = (size - 8) / 2;
1706
1707 if (size == 0)
1708 {
1709 break;
1710 }
1711
1712 fprintf (file,
1713 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1714 virtual_address, size, size, number);
1715
1716 for (j = 0; j < number; ++j)
1717 {
1718 unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1719 int t = (e & 0xF000) >> 12;
1720 int off = e & 0x0FFF;
1721
1722 if (t > 5)
1723 abort();
1724
1725 fprintf(file,
1726 "\treloc %4d offset %4x [%4lx] %s\n",
1727 j, off, (long) (off + virtual_address), tbl[t]);
1728
1729 }
1730 i += size;
1731 }
1732
1733 free (data);
1734
1735 return true;
1736 }
1737
1738 static boolean
1739 pe_print_private_bfd_data (abfd, vfile)
1740 bfd *abfd;
1741 PTR vfile;
1742 {
1743 FILE *file = (FILE *) vfile;
1744 int j;
1745 pe_data_type *pe = pe_data (abfd);
1746 struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1747
1748 fprintf (file,"\nImageBase\t\t");
1749 fprintf_vma (file, i->ImageBase);
1750 fprintf (file,"\nSectionAlignment\t");
1751 fprintf_vma (file, i->SectionAlignment);
1752 fprintf (file,"\nFileAlignment\t\t");
1753 fprintf_vma (file, i->FileAlignment);
1754 fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1755 fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1756 fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1757 fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1758 fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1759 fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1760 fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1761 fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1762 fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1763 fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1764 fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1765 fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1766 fprintf (file,"SizeOfStackReserve\t");
1767 fprintf_vma (file, i->SizeOfStackReserve);
1768 fprintf (file,"\nSizeOfStackCommit\t");
1769 fprintf_vma (file, i->SizeOfStackCommit);
1770 fprintf (file,"\nSizeOfHeapReserve\t");
1771 fprintf_vma (file, i->SizeOfHeapReserve);
1772 fprintf (file,"\nSizeOfHeapCommit\t");
1773 fprintf_vma (file, i->SizeOfHeapCommit);
1774 fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1775 fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1776
1777 fprintf (file,"\nThe Data Directory\n");
1778 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1779 {
1780 fprintf (file, "Entry %1x ", j);
1781 fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1782 fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1783 fprintf (file, "%s\n", dir_names[j]);
1784 }
1785
1786 pe_print_idata(abfd, vfile);
1787 pe_print_edata(abfd, vfile);
1788 pe_print_pdata(abfd, vfile);
1789 pe_print_reloc(abfd, vfile);
1790
1791 return true;
1792 }
1793
1794 static boolean
1795 pe_mkobject (abfd)
1796 bfd * abfd;
1797 {
1798 pe_data_type *pe;
1799 abfd->tdata.pe_obj_data =
1800 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1801
1802 if (abfd->tdata.pe_obj_data == 0)
1803 return false;
1804
1805 pe = pe_data (abfd);
1806
1807 pe->coff.pe = 1;
1808 pe->in_reloc_p = in_reloc_p;
1809 return true;
1810 }
1811
1812 /* Create the COFF backend specific information. */
1813 static PTR
1814 pe_mkobject_hook (abfd, filehdr, aouthdr)
1815 bfd * abfd;
1816 PTR filehdr;
1817 PTR aouthdr;
1818 {
1819 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1820 pe_data_type *pe;
1821
1822 if (pe_mkobject (abfd) == false)
1823 return NULL;
1824
1825 pe = pe_data (abfd);
1826 pe->coff.sym_filepos = internal_f->f_symptr;
1827 /* These members communicate important constants about the symbol
1828 table to GDB's symbol-reading code. These `constants'
1829 unfortunately vary among coff implementations... */
1830 pe->coff.local_n_btmask = N_BTMASK;
1831 pe->coff.local_n_btshft = N_BTSHFT;
1832 pe->coff.local_n_tmask = N_TMASK;
1833 pe->coff.local_n_tshift = N_TSHIFT;
1834 pe->coff.local_symesz = SYMESZ;
1835 pe->coff.local_auxesz = AUXESZ;
1836 pe->coff.local_linesz = LINESZ;
1837
1838 obj_raw_syment_count (abfd) =
1839 obj_conv_table_size (abfd) =
1840 internal_f->f_nsyms;
1841
1842 pe->real_flags = internal_f->f_flags;
1843
1844 #ifdef COFF_IMAGE_WITH_PE
1845 if (aouthdr)
1846 {
1847 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1848 }
1849 #endif
1850
1851 return (PTR) pe;
1852 }
1853
1854
1855
1856 /* Copy any private info we understand from the input bfd
1857 to the output bfd. */
1858
1859 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1860
1861 static boolean
1862 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1863 bfd *ibfd, *obfd;
1864 {
1865 /* One day we may try to grok other private data. */
1866 if (ibfd->xvec->flavour != bfd_target_coff_flavour
1867 || obfd->xvec->flavour != bfd_target_coff_flavour)
1868 return true;
1869
1870 pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1871
1872 return true;
1873 }
1874
1875 #ifdef COFF_IMAGE_WITH_PE
1876
1877 /* Copy private section data. */
1878
1879 #define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
1880
1881 static boolean pe_bfd_copy_private_section_data
1882 PARAMS ((bfd *, asection *, bfd *, asection *));
1883
1884 static boolean
1885 pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
1886 bfd *ibfd;
1887 asection *isec;
1888 bfd *obfd;
1889 asection *osec;
1890 {
1891 if (coff_section_data (ibfd, isec) != NULL
1892 && pei_section_data (ibfd, isec) != NULL)
1893 {
1894 if (coff_section_data (obfd, osec) == NULL)
1895 {
1896 osec->used_by_bfd =
1897 (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
1898 if (osec->used_by_bfd == NULL)
1899 return false;
1900 }
1901 if (pei_section_data (obfd, osec) == NULL)
1902 {
1903 coff_section_data (obfd, osec)->tdata =
1904 (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
1905 if (coff_section_data (obfd, osec)->tdata == NULL)
1906 return false;
1907 }
1908 pei_section_data (obfd, osec)->virt_size =
1909 pei_section_data (ibfd, isec)->virt_size;
1910 }
1911
1912 return true;
1913 }
1914
1915 #endif