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