1 /* Support for the generic parts of most COFF variants, for BFD.
2 Copyright 1995 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
22 Most of this hacked by Steve Chamberlain,
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
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)
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)
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)
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)
49 #define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
52 #define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
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)
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)
60 #ifndef GET_SCN_SCNLEN
61 #define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
63 #ifndef GET_SCN_NRELOC
64 #define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
66 #ifndef GET_SCN_NLINNO
67 #define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
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)
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)
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)
78 #ifndef GET_LINENO_LNNO
79 #define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
81 #ifndef PUT_LINENO_LNNO
82 #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
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
89 #ifndef PUT_FILEHDR_SYMPTR
90 #define PUT_FILEHDR_SYMPTR bfd_h_put_32
93 /* Some fields in the aouthdr are sometimes 64 bits. */
94 #ifndef GET_AOUTHDR_TSIZE
95 #define GET_AOUTHDR_TSIZE bfd_h_get_32
97 #ifndef PUT_AOUTHDR_TSIZE
98 #define PUT_AOUTHDR_TSIZE bfd_h_put_32
100 #ifndef GET_AOUTHDR_DSIZE
101 #define GET_AOUTHDR_DSIZE bfd_h_get_32
103 #ifndef PUT_AOUTHDR_DSIZE
104 #define PUT_AOUTHDR_DSIZE bfd_h_put_32
106 #ifndef GET_AOUTHDR_BSIZE
107 #define GET_AOUTHDR_BSIZE bfd_h_get_32
109 #ifndef PUT_AOUTHDR_BSIZE
110 #define PUT_AOUTHDR_BSIZE bfd_h_put_32
112 #ifndef GET_AOUTHDR_ENTRY
113 #define GET_AOUTHDR_ENTRY bfd_h_get_32
115 #ifndef PUT_AOUTHDR_ENTRY
116 #define PUT_AOUTHDR_ENTRY bfd_h_put_32
118 #ifndef GET_AOUTHDR_TEXT_START
119 #define GET_AOUTHDR_TEXT_START bfd_h_get_32
121 #ifndef PUT_AOUTHDR_TEXT_START
122 #define PUT_AOUTHDR_TEXT_START bfd_h_put_32
124 #ifndef GET_AOUTHDR_DATA_START
125 #define GET_AOUTHDR_DATA_START bfd_h_get_32
127 #ifndef PUT_AOUTHDR_DATA_START
128 #define PUT_AOUTHDR_DATA_START bfd_h_put_32
131 /* Some fields in the scnhdr are sometimes 64 bits. */
132 #ifndef GET_SCNHDR_PADDR
133 #define GET_SCNHDR_PADDR bfd_h_get_32
135 #ifndef PUT_SCNHDR_PADDR
136 #define PUT_SCNHDR_PADDR bfd_h_put_32
138 #ifndef GET_SCNHDR_VADDR
139 #define GET_SCNHDR_VADDR bfd_h_get_32
141 #ifndef PUT_SCNHDR_VADDR
142 #define PUT_SCNHDR_VADDR bfd_h_put_32
144 #ifndef GET_SCNHDR_SIZE
145 #define GET_SCNHDR_SIZE bfd_h_get_32
147 #ifndef PUT_SCNHDR_SIZE
148 #define PUT_SCNHDR_SIZE bfd_h_put_32
150 #ifndef GET_SCNHDR_SCNPTR
151 #define GET_SCNHDR_SCNPTR bfd_h_get_32
153 #ifndef PUT_SCNHDR_SCNPTR
154 #define PUT_SCNHDR_SCNPTR bfd_h_put_32
156 #ifndef GET_SCNHDR_RELPTR
157 #define GET_SCNHDR_RELPTR bfd_h_get_32
159 #ifndef PUT_SCNHDR_RELPTR
160 #define PUT_SCNHDR_RELPTR bfd_h_put_32
162 #ifndef GET_SCNHDR_LNNOPTR
163 #define GET_SCNHDR_LNNOPTR bfd_h_get_32
165 #ifndef PUT_SCNHDR_LNNOPTR
166 #define PUT_SCNHDR_LNNOPTR bfd_h_put_32
171 /**********************************************************************/
174 coff_swap_reloc_in (abfd, src, dst)
179 RELOC *reloc_src = (RELOC *) src;
180 struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
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);
185 reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
187 #ifdef SWAP_IN_RELOC_OFFSET
188 reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
189 (bfd_byte *) reloc_src->r_offset);
195 coff_swap_reloc_out (abfd, src, dst)
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);
205 bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
208 #ifdef SWAP_OUT_RELOC_OFFSET
209 SWAP_OUT_RELOC_OFFSET(abfd,
211 (bfd_byte *) reloc_dst->r_offset);
213 #ifdef SWAP_OUT_RELOC_EXTRA
214 SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
216 return sizeof(struct external_reloc);
221 coff_swap_filehdr_in (abfd, src, dst)
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);
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);
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)
240 filehdr_dst->f_flags |= HAS_SYMS;
244 filehdr_dst->f_symptr = 0;
245 filehdr_dst->f_nsyms = 0;
246 filehdr_dst->f_flags &= ~HAS_SYMS;
249 filehdr_dst->f_opthdr = bfd_h_get_16(abfd,
250 (bfd_byte *)filehdr_src-> f_opthdr);
253 #ifdef COFF_IMAGE_WITH_PE
256 coff_swap_filehdr_out (abfd, in, out)
262 struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
263 FILHDR *filehdr_out = (FILHDR *)out;
265 if (pe_data (abfd)->has_reloc_section)
266 filehdr_in->f_flags &= ~F_RELFLG;
268 if (pe_data (abfd)->dll)
269 filehdr_in->f_flags |= F_DLL;
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;
286 for (idx=0; idx < 4; idx++)
287 filehdr_in->pe.e_res[idx] = 0x0;
289 filehdr_in->pe.e_oemid = 0x0;
290 filehdr_in->pe.e_oeminfo = 0x0;
292 for (idx=0; idx < 10; idx++)
293 filehdr_in->pe.e_res2[idx] = 0x0;
295 filehdr_in->pe.e_lfanew = 0x80;
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;
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);
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);
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
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);
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]);
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);
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]);
364 bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
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]);
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);
380 return sizeof(FILHDR);
385 coff_swap_filehdr_out (abfd, in, out)
390 struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
391 FILHDR *filehdr_out = (FILHDR *)out;
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);
402 return sizeof(FILHDR);
409 coff_swap_sym_in (abfd, ext1, in1)
414 SYMENT *ext = (SYMENT *)ext1;
415 struct internal_syment *in = (struct internal_syment *)in1;
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);
422 #if SYMNMLEN != E_SYMNMLEN
423 -> Error, we need to cope with truncating or extending SYMNMLEN!;
425 memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
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);
435 in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
437 in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
438 in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
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) {
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; */
456 /* in->n_scnum = 2; */
459 #ifdef coff_swap_sym_in_hook
460 coff_swap_sym_in_hook(abfd, ext1, in1);
465 coff_swap_sym_out (abfd, inp, extp)
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);
477 #if SYMNMLEN != E_SYMNMLEN
478 -> Error, we need to cope with truncating or extending SYMNMLEN!;
480 memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
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)
488 bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
492 bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type);
494 bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
495 bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
497 return sizeof(SYMENT);
501 coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
510 AUXENT *ext = (AUXENT *)ext1;
511 union internal_auxent *in = (union internal_auxent *)in1;
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);
520 #if FILNMLEN != E_FILNMLEN
521 -> Error, we need to cope with truncating or extending FILNMLEN!;
523 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
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);
543 in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
545 in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
548 if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
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);
555 #if DIMNUM != E_DIMNUM
556 #error we need to cope with truncating or extending DIMNUM
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]);
569 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
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);
578 coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
587 union internal_auxent *in = (union internal_auxent *)inp;
588 AUXENT *ext = (AUXENT *)extp;
590 memset((PTR)ext, 0, AUXESZ);
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);
596 in->x_file.x_n.x_offset,
597 (bfd_byte *) ext->x_file.x_n.x_offset);
600 #if FILNMLEN != E_FILNMLEN
601 -> Error, we need to cope with truncating or extending FILNMLEN!;
603 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
606 return sizeof (AUXENT);
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);
623 bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
625 bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
628 if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
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);
635 #if DIMNUM != E_DIMNUM
636 #error we need to cope with truncating or extending DIMNUM
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]);
649 bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
650 (bfd_byte *) ext->x_sym.x_misc.x_fsize);
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);
657 return sizeof(AUXENT);
662 coff_swap_lineno_in (abfd, ext1, in1)
667 LINENO *ext = (LINENO *)ext1;
668 struct internal_lineno *in = (struct internal_lineno *)in1;
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);
675 coff_swap_lineno_out (abfd, inp, outp)
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);
685 PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
686 return sizeof(struct external_lineno);
692 coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
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;
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);
705 GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
707 GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
709 GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
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);
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);
744 for (idx=0; idx < 16; idx++)
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]);
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;
762 static void add_data_entry (abfd, aout, idx, name, base)
764 struct internal_extra_pe_aouthdr *aout;
769 asection *sec = bfd_get_section_by_name (abfd, name);
771 /* add import directory information if it exists */
774 aout->DataDirectory[idx].VirtualAddress = sec->vma - base;
775 aout->DataDirectory[idx].Size = sec->_cooked_size;
776 sec->flags |= SEC_DATA;
781 coff_swap_aouthdr_out (abfd, in, out)
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;
790 bfd_vma sa = extra->SectionAlignment;
791 bfd_vma fa = extra->FileAlignment;
792 bfd_vma ib = extra->ImageBase ;
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;
801 #define FA(x) (((x) + fa -1 ) & (- fa))
802 #define SA(x) (((x) + sa -1 ) & (- sa))
804 /* We like to have the sizes aligned */
806 aouthdr_in->bsize = FA (aouthdr_in->bsize);
809 extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
811 /* first null out all data directory entries .. */
812 memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
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);
819 /* FIXME: do other PE platforms use this? */
820 add_data_entry (abfd, extra, 3, ".pdata" ,ib);
823 add_data_entry (abfd, extra, 5, ".reloc", ib);
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.
831 extra->DataDirectory[12].VirtualAddress = first_thunk_address;
832 extra->DataDirectory[12].Size = thunk_size;
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)
839 extra->DataDirectory[1].Size = import_table_size;
845 bfd_vma isize = SA(abfd->sections->filepos);
848 for (sec = abfd->sections; sec; sec = sec->next)
850 int rounded = FA(sec->_raw_size);
852 if (strcmp(sec->name,".junk") == 0)
857 if (sec->flags & SEC_DATA)
859 if (sec->flags & SEC_CODE)
861 isize += SA(rounded);
864 aouthdr_in->dsize = dsize;
865 aouthdr_in->tsize = tsize;
866 extra->SizeOfImage = isize;
869 extra->SizeOfHeaders = abfd->sections->filepos;
870 bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
873 /* this little piece of magic sets the "linker version" field to 2.60 */
874 bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
876 /* this little piece of magic sets the "linker version" field to 2.55 */
877 bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
880 PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
881 PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
882 PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
883 PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
884 PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
885 (bfd_byte *) aouthdr_out->standard.text_start);
887 PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
888 (bfd_byte *) aouthdr_out->standard.data_start);
891 bfd_h_put_32 (abfd, extra->ImageBase,
892 (bfd_byte *) aouthdr_out->ImageBase);
893 bfd_h_put_32 (abfd, extra->SectionAlignment,
894 (bfd_byte *) aouthdr_out->SectionAlignment);
895 bfd_h_put_32 (abfd, extra->FileAlignment,
896 (bfd_byte *) aouthdr_out->FileAlignment);
897 bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
898 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
899 bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
900 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
901 bfd_h_put_16 (abfd, extra->MajorImageVersion,
902 (bfd_byte *) aouthdr_out->MajorImageVersion);
903 bfd_h_put_16 (abfd, extra->MinorImageVersion,
904 (bfd_byte *) aouthdr_out->MinorImageVersion);
905 bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
906 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
907 bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
908 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
909 bfd_h_put_32 (abfd, extra->Reserved1,
910 (bfd_byte *) aouthdr_out->Reserved1);
911 bfd_h_put_32 (abfd, extra->SizeOfImage,
912 (bfd_byte *) aouthdr_out->SizeOfImage);
913 bfd_h_put_32 (abfd, extra->SizeOfHeaders,
914 (bfd_byte *) aouthdr_out->SizeOfHeaders);
915 bfd_h_put_32 (abfd, extra->CheckSum,
916 (bfd_byte *) aouthdr_out->CheckSum);
917 bfd_h_put_16 (abfd, extra->Subsystem,
918 (bfd_byte *) aouthdr_out->Subsystem);
919 bfd_h_put_16 (abfd, extra->DllCharacteristics,
920 (bfd_byte *) aouthdr_out->DllCharacteristics);
921 bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
922 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
923 bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
924 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
925 bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
926 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
927 bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
928 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
929 bfd_h_put_32 (abfd, extra->LoaderFlags,
930 (bfd_byte *) aouthdr_out->LoaderFlags);
931 bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
932 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
935 for (idx=0; idx < 16; idx++)
937 bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
938 (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
939 bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
940 (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
944 return sizeof(AOUTHDR);
948 coff_swap_scnhdr_in (abfd, ext, in)
953 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
954 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
956 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
957 scnhdr_int->s_vaddr =
958 GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
959 scnhdr_int->s_paddr =
960 GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
962 GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
963 scnhdr_int->s_scnptr =
964 GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
965 scnhdr_int->s_relptr =
966 GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
967 scnhdr_int->s_lnnoptr =
968 GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
969 scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
971 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
972 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
974 if (scnhdr_int->s_vaddr != 0)
976 scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
978 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
980 scnhdr_int->s_size = scnhdr_int->s_paddr;
981 scnhdr_int->s_paddr = 0;
986 coff_swap_scnhdr_out (abfd, in, out)
991 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
992 SCNHDR *scnhdr_ext = (SCNHDR *)out;
993 unsigned int ret = sizeof (SCNHDR);
997 memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
999 PUT_SCNHDR_VADDR (abfd,
1000 (scnhdr_int->s_vaddr
1001 - pe_data(abfd)->pe_opthdr.ImageBase),
1002 (bfd_byte *) scnhdr_ext->s_vaddr);
1004 /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1005 value except for the BSS section, its s_size should be 0 */
1008 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
1010 ps = scnhdr_int->s_size;
1015 ps = scnhdr_int->s_paddr;
1016 ss = scnhdr_int->s_size;
1019 PUT_SCNHDR_SIZE (abfd, ss,
1020 (bfd_byte *) scnhdr_ext->s_size);
1023 PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
1025 PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
1026 (bfd_byte *) scnhdr_ext->s_scnptr);
1027 PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
1028 (bfd_byte *) scnhdr_ext->s_relptr);
1029 PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
1030 (bfd_byte *) scnhdr_ext->s_lnnoptr);
1032 /* Extra flags must be set when dealing with NT. All sections should also
1033 have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
1034 .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1035 sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1036 (this is especially important when dealing with the .idata section since
1037 the addresses for routines from .dlls must be overwritten). If .reloc
1038 section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1039 (0x02000000). Also, the resource data should also be read and
1042 /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1043 /* FIXME: even worse, I don't see how to get the original alignment field*/
1047 int flags = scnhdr_int->s_flags;
1048 if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
1049 strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
1050 strcmp (scnhdr_int->s_name, ".rsrc") == 0 ||
1051 strcmp (scnhdr_int->s_name, ".bss") == 0)
1052 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1053 else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1054 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1055 else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1056 flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
1057 else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1058 flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
1059 else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1060 || strcmp (scnhdr_int->s_name, ".edata") == 0)
1061 flags = IMAGE_SCN_MEM_READ | SEC_DATA;
1062 /* ppc-nt additions */
1063 else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1064 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1065 IMAGE_SCN_MEM_READ ;
1066 /* Remember this field is a max of 8 chars, so the null is _not_ there
1067 for an 8 character name like ".reldata". (yep. Stupid bug) */
1068 else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
1069 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1070 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1071 else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1072 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1073 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1074 else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1075 flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1076 /* end of ppc-nt additions */
1077 #ifdef POWERPC_LE_PE
1078 else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0)
1080 flags = IMAGE_SCN_LNK_INFO;
1082 else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1084 flags = IMAGE_SCN_LNK_INFO;
1088 bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1091 if (scnhdr_int->s_nlnno <= 0xffff)
1092 bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1095 (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1096 bfd_get_filename (abfd),
1097 scnhdr_int->s_nlnno);
1098 bfd_set_error (bfd_error_file_truncated);
1099 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1102 if (scnhdr_int->s_nreloc <= 0xffff)
1103 bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1106 (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1107 bfd_get_filename (abfd),
1108 scnhdr_int->s_nreloc);
1109 bfd_set_error (bfd_error_file_truncated);
1110 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1116 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1118 "Export Directory [.edata]",
1119 "Import Directory [parts of .idata]",
1120 "Resource Directory [.rsrc]",
1121 "Exception Directory [.pdata]",
1122 "Security Directory",
1123 "Base Relocation Directory [.reloc]",
1125 "Description Directory",
1126 "Special Directory",
1127 "Thread Storage Directory [.tls]",
1128 "Load Configuration Directory",
1129 "Bound Import Directory",
1130 "Import Address Table Directory",
1136 /**********************************************************************/
1138 pe_print_idata(abfd, vfile)
1144 asection *section = bfd_get_section_by_name (abfd, ".idata");
1146 #ifdef POWERPC_LE_PE
1147 asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1150 bfd_size_type datasize = 0;
1152 bfd_size_type start, stop;
1155 pe_data_type *pe = pe_data (abfd);
1156 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1161 #ifdef POWERPC_LE_PE
1162 if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1164 /* The toc address can be found by taking the starting address,
1165 which on the PPC locates a function descriptor. The descriptor
1166 consists of the function code starting address followed by the
1167 address of the toc. The starting address we get from the bfd,
1168 and the descriptor is supposed to be in the .reldata section.
1171 bfd_vma loadable_toc_address;
1172 bfd_vma toc_address;
1173 bfd_vma start_address;
1176 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1178 if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1181 datasize = bfd_section_size (abfd, rel_section);
1183 bfd_get_section_contents (abfd,
1186 bfd_section_size (abfd, rel_section));
1188 offset = abfd->start_address - rel_section->vma;
1190 start_address = bfd_get_32(abfd, data+offset);
1191 loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1192 toc_address = loadable_toc_address - 32768;
1195 "\nFunction descriptor located at the start address: %04lx\n",
1196 (unsigned long int) (abfd->start_address));
1198 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
1199 start_address, loadable_toc_address, toc_address);
1204 "\nThe Import Tables (interpreted .idata section contents)\n");
1206 " vma: Hint Time Forward DLL First\n");
1208 " Table Stamp Chain Name Thunk\n");
1210 if (bfd_section_size (abfd, section) == 0)
1213 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1214 datasize = bfd_section_size (abfd, section);
1215 if (data == NULL && datasize != 0)
1218 bfd_get_section_contents (abfd,
1221 bfd_section_size (abfd, section));
1225 stop = bfd_section_size (abfd, section);
1227 for (i = start; i < stop; i += onaline)
1231 bfd_vma forward_chain;
1233 bfd_vma first_thunk;
1237 int adj = extra->ImageBase - section->vma;
1241 (unsigned long int) (i + section->vma));
1249 hint_addr = bfd_get_32(abfd, data+i);
1250 time_stamp = bfd_get_32(abfd, data+i+4);
1251 forward_chain = bfd_get_32(abfd, data+i+8);
1252 dll_name = bfd_get_32(abfd, data+i+12);
1253 first_thunk = bfd_get_32(abfd, data+i+16);
1255 fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1267 /* the image base is present in the section->vma */
1268 dll = data + dll_name + adj;
1269 fprintf(file, "\n\tDLL Name: %s\n", dll);
1270 fprintf(file, "\tvma: Ordinal Member-Name\n");
1272 idx = hint_addr + adj;
1274 for (j=0;j<stop;j+=4)
1278 bfd_vma member = bfd_get_32(abfd, data + idx + j);
1281 ordinal = bfd_get_16(abfd,
1282 data + member + adj);
1283 member_name = data + member + adj + 2;
1284 fprintf(file, "\t%04lx\t %4d %s\n",
1285 member, ordinal, member_name);
1288 if (hint_addr != first_thunk)
1293 idx2 = first_thunk + adj;
1295 for (j=0;j<stop;j+=4)
1299 bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1300 bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1301 if (hint_member != iat_member)
1306 "\tThe Import Address Table (difference found)\n");
1307 fprintf(file, "\tvma: Ordinal Member-Name\n");
1310 if (iat_member == 0)
1313 "\t>>> Ran out of IAT members!\n");
1317 ordinal = bfd_get_16(abfd,
1318 data + iat_member + adj);
1319 member_name = data + iat_member + adj + 2;
1320 fprintf(file, "\t%04lx\t %4d %s\n",
1321 iat_member, ordinal, member_name);
1325 if (hint_member == 0)
1331 "\tThe Import Address Table is identical\n");
1335 fprintf(file, "\n");
1345 pe_print_edata(abfd, vfile)
1351 asection *section = bfd_get_section_by_name (abfd, ".edata");
1353 bfd_size_type datasize = 0;
1359 long export_flags; /* reserved - should be zero */
1363 bfd_vma name; /* rva - relative to image base */
1364 long base; /* ordinal base */
1365 long num_functions; /* Number in the export address table */
1366 long num_names; /* Number in the name pointer table */
1367 bfd_vma eat_addr; /* rva to the export address table */
1368 bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
1369 bfd_vma ot_addr; /* rva to the Ordinal Table */
1372 pe_data_type *pe = pe_data (abfd);
1373 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1378 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1380 datasize = bfd_section_size (abfd, section);
1382 if (data == NULL && datasize != 0)
1385 bfd_get_section_contents (abfd,
1388 bfd_section_size (abfd, section));
1390 /* Go get Export Directory Table */
1391 edt.export_flags = bfd_get_32(abfd, data+0);
1392 edt.time_stamp = bfd_get_32(abfd, data+4);
1393 edt.major_ver = bfd_get_16(abfd, data+8);
1394 edt.minor_ver = bfd_get_16(abfd, data+10);
1395 edt.name = bfd_get_32(abfd, data+12);
1396 edt.base = bfd_get_32(abfd, data+16);
1397 edt.num_functions = bfd_get_32(abfd, data+20);
1398 edt.num_names = bfd_get_32(abfd, data+24);
1399 edt.eat_addr = bfd_get_32(abfd, data+28);
1400 edt.npt_addr = bfd_get_32(abfd, data+32);
1401 edt.ot_addr = bfd_get_32(abfd, data+36);
1403 adj = extra->ImageBase - section->vma;
1406 /* Dump the EDT first first */
1408 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1411 "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1414 "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1417 "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1421 fprintf_vma (file, edt.name);
1423 "%s\n", data + edt.name + adj);
1426 "Ordinal Base \t\t\t%ld\n", edt.base);
1432 "\tExport Address Table \t\t%lx\n",
1433 (unsigned long) edt.num_functions);
1436 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1439 "Table Addresses\n");
1442 "\tExport Address Table \t\t");
1443 fprintf_vma (file, edt.eat_addr);
1444 fprintf (file, "\n");
1447 "\tName Pointer Table \t\t");
1448 fprintf_vma (file, edt.npt_addr);
1449 fprintf (file, "\n");
1452 "\tOrdinal Table \t\t\t");
1453 fprintf_vma (file, edt.ot_addr);
1454 fprintf (file, "\n");
1457 /* The next table to find si the Export Address Table. It's basically
1458 a list of pointers that either locate a function in this dll, or
1459 forward the call to another dll. Something like:
1464 } export_address_table_entry;
1468 "\nExport Address Table -- Ordinal Base %ld\n",
1471 for (i = 0; i < edt.num_functions; ++i)
1473 bfd_vma eat_member = bfd_get_32(abfd,
1474 data + edt.eat_addr + (i*4) + adj);
1475 bfd_vma eat_actual = extra->ImageBase + eat_member;
1476 bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1477 bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1480 if (eat_member == 0)
1483 if (edata_start < eat_actual && eat_actual < edata_end)
1485 /* this rva is to a name (forwarding function) in our section */
1486 /* Should locate a function descriptor */
1488 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1489 (long) i, (long) (i + edt.base), eat_member,
1490 "Forwarder RVA", data + eat_member + adj);
1494 /* Should locate a function descriptor in the reldata section */
1496 "\t[%4ld] +base[%4ld] %04lx %s\n",
1497 (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1501 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1502 /* Dump them in parallel for clarity */
1504 "\n[Ordinal/Name Pointer] Table\n");
1506 for (i = 0; i < edt.num_names; ++i)
1508 bfd_vma name_ptr = bfd_get_32(abfd,
1513 char *name = data + name_ptr + adj;
1515 bfd_vma ord = bfd_get_16(abfd,
1520 "\t[%4ld] %s\n", (long) ord, name);
1530 pe_print_pdata(abfd, vfile)
1536 asection *section = bfd_get_section_by_name (abfd, ".pdata");
1537 bfd_size_type datasize = 0;
1539 bfd_size_type start, stop;
1545 stop = bfd_section_size (abfd, section);
1546 if ((stop % onaline) != 0)
1547 fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1548 (long)stop, onaline);
1551 "\nThe Function Table (interpreted .pdata section contents)\n");
1553 " vma:\t\tBegin End EH EH PrologEnd\n");
1555 " \t\tAddress Address Handler Data Address\n");
1557 if (bfd_section_size (abfd, section) == 0)
1560 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1561 datasize = bfd_section_size (abfd, section);
1562 if (data == NULL && datasize != 0)
1565 bfd_get_section_contents (abfd,
1568 bfd_section_size (abfd, section));
1572 for (i = start; i < stop; i += onaline)
1578 bfd_vma prolog_end_addr;
1583 begin_addr = bfd_get_32(abfd, data+i);
1584 end_addr = bfd_get_32(abfd, data+i+4);
1585 eh_handler = bfd_get_32(abfd, data+i+8);
1586 eh_data = bfd_get_32(abfd, data+i+12);
1587 prolog_end_addr = bfd_get_32(abfd, data+i+16);
1589 if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1590 && eh_data == 0 && prolog_end_addr == 0)
1592 /* We are probably into the padding of the
1599 (unsigned long int) (i + section->vma));
1601 fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1608 #ifdef POWERPC_LE_PE
1609 if (eh_handler == 0 && eh_data != 0)
1611 /* Special bits here, although the meaning may */
1612 /* be a little mysterious. The only one I know */
1613 /* for sure is 0x03. */
1614 /* Code Significance */
1616 /* 0x01 Register Save Millicode */
1617 /* 0x02 Register Restore Millicode */
1618 /* 0x03 Glue Code Sequence */
1622 fprintf(file, " Register save millicode");
1625 fprintf(file, " Register restore millicode");
1628 fprintf(file, " Glue code sequence");
1635 fprintf(file, "\n");
1643 static const char *tbl[6] =
1654 pe_print_reloc(abfd, vfile)
1660 asection *section = bfd_get_section_by_name (abfd, ".reloc");
1661 bfd_size_type datasize = 0;
1663 bfd_size_type start, stop;
1668 if (bfd_section_size (abfd, section) == 0)
1672 "\n\nPE File Base Relocations (interpreted .reloc"
1673 " section contents)\n");
1675 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1676 datasize = bfd_section_size (abfd, section);
1677 if (data == NULL && datasize != 0)
1680 bfd_get_section_contents (abfd,
1683 bfd_section_size (abfd, section));
1687 stop = bfd_section_size (abfd, section);
1689 for (i = start; i < stop;)
1692 bfd_vma virtual_address;
1695 /* The .reloc section is a sequence of blocks, with a header consisting
1696 of two 32 bit quantities, followed by a number of 16 bit entries */
1698 virtual_address = bfd_get_32(abfd, data+i);
1699 size = bfd_get_32(abfd, data+i+4);
1700 number = (size - 8) / 2;
1708 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1709 virtual_address, size, size, number);
1711 for (j = 0; j < number; ++j)
1713 unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1714 int t = (e & 0xF000) >> 12;
1715 int off = e & 0x0FFF;
1721 "\treloc %4d offset %4x [%4lx] %s\n",
1722 j, off, (long) (off + virtual_address), tbl[t]);
1734 pe_print_private_bfd_data (abfd, vfile)
1738 FILE *file = (FILE *) vfile;
1740 pe_data_type *pe = pe_data (abfd);
1741 struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1743 fprintf (file,"\nImageBase\t\t");
1744 fprintf_vma (file, i->ImageBase);
1745 fprintf (file,"\nSectionAlignment\t");
1746 fprintf_vma (file, i->SectionAlignment);
1747 fprintf (file,"\nFileAlignment\t\t");
1748 fprintf_vma (file, i->FileAlignment);
1749 fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1750 fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1751 fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1752 fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1753 fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1754 fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1755 fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1756 fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1757 fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1758 fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1759 fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1760 fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1761 fprintf (file,"SizeOfStackReserve\t");
1762 fprintf_vma (file, i->SizeOfStackReserve);
1763 fprintf (file,"\nSizeOfStackCommit\t");
1764 fprintf_vma (file, i->SizeOfStackCommit);
1765 fprintf (file,"\nSizeOfHeapReserve\t");
1766 fprintf_vma (file, i->SizeOfHeapReserve);
1767 fprintf (file,"\nSizeOfHeapCommit\t");
1768 fprintf_vma (file, i->SizeOfHeapCommit);
1769 fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1770 fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1772 fprintf (file,"\nThe Data Directory\n");
1773 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1775 fprintf (file, "Entry %1x ", j);
1776 fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1777 fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1778 fprintf (file, "%s\n", dir_names[j]);
1781 pe_print_idata(abfd, vfile);
1782 pe_print_edata(abfd, vfile);
1783 pe_print_pdata(abfd, vfile);
1784 pe_print_reloc(abfd, vfile);
1794 abfd->tdata.pe_obj_data =
1795 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1797 if (abfd->tdata.pe_obj_data == 0)
1800 pe = pe_data (abfd);
1803 pe->in_reloc_p = in_reloc_p;
1807 /* Create the COFF backend specific information. */
1809 pe_mkobject_hook (abfd, filehdr, aouthdr)
1814 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1817 if (pe_mkobject (abfd) == false)
1820 pe = pe_data (abfd);
1821 pe->coff.sym_filepos = internal_f->f_symptr;
1822 /* These members communicate important constants about the symbol
1823 table to GDB's symbol-reading code. These `constants'
1824 unfortunately vary among coff implementations... */
1825 pe->coff.local_n_btmask = N_BTMASK;
1826 pe->coff.local_n_btshft = N_BTSHFT;
1827 pe->coff.local_n_tmask = N_TMASK;
1828 pe->coff.local_n_tshift = N_TSHIFT;
1829 pe->coff.local_symesz = SYMESZ;
1830 pe->coff.local_auxesz = AUXESZ;
1831 pe->coff.local_linesz = LINESZ;
1833 obj_raw_syment_count (abfd) =
1834 obj_conv_table_size (abfd) =
1835 internal_f->f_nsyms;
1837 pe->real_flags = internal_f->f_flags;
1839 #ifdef COFF_IMAGE_WITH_PE
1842 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1851 /* Copy any private info we understand from the input bfd
1852 to the output bfd. */
1854 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1857 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1860 /* One day we may try to grok other private data. */
1861 if (ibfd->xvec->flavour != bfd_target_coff_flavour
1862 || obfd->xvec->flavour != bfd_target_coff_flavour)
1865 pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;