1 /* Support for the generic parts of most COFF variants, for BFD.
2 Copyright 1995, 1996 Free Software Foundation, Inc.
3 Written by Cygnus Support.
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);
538 in->x_scn.x_checksum = bfd_h_get_32 (abfd,
539 (bfd_byte *) ext->x_scn.x_checksum);
540 in->x_scn.x_associated =
541 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);
542 in->x_scn.x_comdat = bfd_h_get_8 (abfd,
543 (bfd_byte *) ext->x_scn.x_comdat);
549 in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
551 in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
554 if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
556 in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
557 in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
561 #if DIMNUM != E_DIMNUM
562 #error we need to cope with truncating or extending DIMNUM
564 in->x_sym.x_fcnary.x_ary.x_dimen[0] =
565 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
566 in->x_sym.x_fcnary.x_ary.x_dimen[1] =
567 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
568 in->x_sym.x_fcnary.x_ary.x_dimen[2] =
569 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
570 in->x_sym.x_fcnary.x_ary.x_dimen[3] =
571 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
575 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
578 in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
579 in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
584 coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
593 union internal_auxent *in = (union internal_auxent *)inp;
594 AUXENT *ext = (AUXENT *)extp;
596 memset((PTR)ext, 0, AUXESZ);
599 if (in->x_file.x_fname[0] == 0) {
600 bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
602 in->x_file.x_n.x_offset,
603 (bfd_byte *) ext->x_file.x_n.x_offset);
606 #if FILNMLEN != E_FILNMLEN
607 -> Error, we need to cope with truncating or extending FILNMLEN!;
609 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
612 return sizeof (AUXENT);
620 if (type == T_NULL) {
621 PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
622 PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
623 PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
624 bfd_h_put_32 (abfd, in->x_scn.x_checksum,
625 (bfd_byte *) ext->x_scn.x_checksum);
626 bfd_h_put_16 (abfd, in->x_scn.x_associated,
627 (bfd_byte *) ext->x_scn.x_associated);
628 bfd_h_put_8 (abfd, in->x_scn.x_comdat,
629 (bfd_byte *) ext->x_scn.x_comdat);
630 return sizeof (AUXENT);
635 bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
637 bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
640 if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
642 PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
643 PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
647 #if DIMNUM != E_DIMNUM
648 #error we need to cope with truncating or extending DIMNUM
650 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
651 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
652 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
653 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
654 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
655 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
656 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
657 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
661 bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
662 (bfd_byte *) ext->x_sym.x_misc.x_fsize);
665 PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
666 PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
669 return sizeof(AUXENT);
674 coff_swap_lineno_in (abfd, ext1, in1)
679 LINENO *ext = (LINENO *)ext1;
680 struct internal_lineno *in = (struct internal_lineno *)in1;
682 in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
683 in->l_lnno = GET_LINENO_LNNO(abfd, ext);
687 coff_swap_lineno_out (abfd, inp, outp)
692 struct internal_lineno *in = (struct internal_lineno *)inp;
693 struct external_lineno *ext = (struct external_lineno *)outp;
694 bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
695 ext->l_addr.l_symndx);
697 PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
698 return sizeof(struct external_lineno);
704 coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
709 struct internal_extra_pe_aouthdr *a;
710 PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
711 AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
712 struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
714 aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
715 aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
717 GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
719 GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
721 GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
723 GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
724 aouthdr_int->text_start =
725 GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
726 aouthdr_int->data_start =
727 GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
729 a = &aouthdr_int->pe;
730 a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase);
731 a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment);
732 a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment);
733 a->MajorOperatingSystemVersion =
734 bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion);
735 a->MinorOperatingSystemVersion =
736 bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion);
737 a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion);
738 a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion);
739 a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion);
740 a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion);
741 a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1);
742 a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage);
743 a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders);
744 a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum);
745 a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem);
746 a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics);
747 a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve);
748 a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit);
749 a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve);
750 a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit);
751 a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags);
752 a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes);
756 for (idx=0; idx < 16; idx++)
758 a->DataDirectory[idx].VirtualAddress =
759 bfd_h_get_32 (abfd, src->DataDirectory[idx][0]);
760 a->DataDirectory[idx].Size =
761 bfd_h_get_32 (abfd, src->DataDirectory[idx][1]);
765 if (aouthdr_int->entry)
766 aouthdr_int->entry += a->ImageBase;
767 if (aouthdr_int->tsize)
768 aouthdr_int->text_start += a->ImageBase;
769 if (aouthdr_int->dsize)
770 aouthdr_int->data_start += a->ImageBase;
774 static void add_data_entry (abfd, aout, idx, name, base)
776 struct internal_extra_pe_aouthdr *aout;
781 asection *sec = bfd_get_section_by_name (abfd, name);
783 /* add import directory information if it exists */
786 aout->DataDirectory[idx].VirtualAddress = sec->vma - base;
787 aout->DataDirectory[idx].Size = sec->_cooked_size;
788 sec->flags |= SEC_DATA;
793 coff_swap_aouthdr_out (abfd, in, out)
798 struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
799 struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
800 PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
802 bfd_vma sa = extra->SectionAlignment;
803 bfd_vma fa = extra->FileAlignment;
804 bfd_vma ib = extra->ImageBase ;
806 if (aouthdr_in->tsize)
807 aouthdr_in->text_start -= ib;
808 if (aouthdr_in->dsize)
809 aouthdr_in->data_start -= ib;
810 if (aouthdr_in->entry)
811 aouthdr_in->entry -= ib;
813 #define FA(x) (((x) + fa -1 ) & (- fa))
814 #define SA(x) (((x) + sa -1 ) & (- sa))
816 /* We like to have the sizes aligned */
818 aouthdr_in->bsize = FA (aouthdr_in->bsize);
821 extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
823 /* first null out all data directory entries .. */
824 memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
826 add_data_entry (abfd, extra, 0, ".edata", ib);
827 add_data_entry (abfd, extra, 1, ".idata", ib);
828 add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
831 /* FIXME: do other PE platforms use this? */
832 add_data_entry (abfd, extra, 3, ".pdata" ,ib);
835 add_data_entry (abfd, extra, 5, ".reloc", ib);
838 /* On the PPC NT system, this field is set up as follows. It is
839 not an "officially" reserved field, so it currently has no title.
840 first_thunk_address is idata$5, and the thunk_size is the size
841 of the idata$5 chunk of the idata section.
843 extra->DataDirectory[12].VirtualAddress = first_thunk_address;
844 extra->DataDirectory[12].Size = thunk_size;
846 /* On the PPC NT system, the size of the directory entry is not the
847 size of the entire section. It's actually offset to the end of
848 the idata$3 component of the idata section. This is the size of
849 the entire import table. (also known as the start of idata$4)
851 extra->DataDirectory[1].Size = import_table_size;
857 bfd_vma isize = SA(abfd->sections->filepos);
860 for (sec = abfd->sections; sec; sec = sec->next)
862 int rounded = FA(sec->_raw_size);
864 if (sec->flags & SEC_DATA)
866 if (sec->flags & SEC_CODE)
868 isize += SA(rounded);
871 aouthdr_in->dsize = dsize;
872 aouthdr_in->tsize = tsize;
873 extra->SizeOfImage = isize;
876 extra->SizeOfHeaders = abfd->sections->filepos;
877 bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
880 /* this little piece of magic sets the "linker version" field to 2.60 */
881 bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
883 /* this little piece of magic sets the "linker version" field to 2.55 */
884 bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
887 PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
888 PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
889 PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
890 PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
891 PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
892 (bfd_byte *) aouthdr_out->standard.text_start);
894 PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
895 (bfd_byte *) aouthdr_out->standard.data_start);
898 bfd_h_put_32 (abfd, extra->ImageBase,
899 (bfd_byte *) aouthdr_out->ImageBase);
900 bfd_h_put_32 (abfd, extra->SectionAlignment,
901 (bfd_byte *) aouthdr_out->SectionAlignment);
902 bfd_h_put_32 (abfd, extra->FileAlignment,
903 (bfd_byte *) aouthdr_out->FileAlignment);
904 bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
905 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
906 bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
907 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
908 bfd_h_put_16 (abfd, extra->MajorImageVersion,
909 (bfd_byte *) aouthdr_out->MajorImageVersion);
910 bfd_h_put_16 (abfd, extra->MinorImageVersion,
911 (bfd_byte *) aouthdr_out->MinorImageVersion);
912 bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
913 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
914 bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
915 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
916 bfd_h_put_32 (abfd, extra->Reserved1,
917 (bfd_byte *) aouthdr_out->Reserved1);
918 bfd_h_put_32 (abfd, extra->SizeOfImage,
919 (bfd_byte *) aouthdr_out->SizeOfImage);
920 bfd_h_put_32 (abfd, extra->SizeOfHeaders,
921 (bfd_byte *) aouthdr_out->SizeOfHeaders);
922 bfd_h_put_32 (abfd, extra->CheckSum,
923 (bfd_byte *) aouthdr_out->CheckSum);
924 bfd_h_put_16 (abfd, extra->Subsystem,
925 (bfd_byte *) aouthdr_out->Subsystem);
926 bfd_h_put_16 (abfd, extra->DllCharacteristics,
927 (bfd_byte *) aouthdr_out->DllCharacteristics);
928 bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
929 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
930 bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
931 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
932 bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
933 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
934 bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
935 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
936 bfd_h_put_32 (abfd, extra->LoaderFlags,
937 (bfd_byte *) aouthdr_out->LoaderFlags);
938 bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
939 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
942 for (idx=0; idx < 16; idx++)
944 bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
945 (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
946 bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
947 (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
951 return sizeof(AOUTHDR);
955 coff_swap_scnhdr_in (abfd, ext, in)
960 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
961 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
963 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
964 scnhdr_int->s_vaddr =
965 GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
966 scnhdr_int->s_paddr =
967 GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
969 GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
970 scnhdr_int->s_scnptr =
971 GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
972 scnhdr_int->s_relptr =
973 GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
974 scnhdr_int->s_lnnoptr =
975 GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
976 scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
978 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
979 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
981 if (scnhdr_int->s_vaddr != 0)
983 scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
985 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
987 scnhdr_int->s_size = scnhdr_int->s_paddr;
988 scnhdr_int->s_paddr = 0;
993 coff_swap_scnhdr_out (abfd, in, out)
998 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
999 SCNHDR *scnhdr_ext = (SCNHDR *)out;
1000 unsigned int ret = sizeof (SCNHDR);
1004 memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
1006 PUT_SCNHDR_VADDR (abfd,
1007 (scnhdr_int->s_vaddr
1008 - pe_data(abfd)->pe_opthdr.ImageBase),
1009 (bfd_byte *) scnhdr_ext->s_vaddr);
1011 /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1012 value except for the BSS section, its s_size should be 0 */
1015 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
1017 ps = scnhdr_int->s_size;
1022 ps = scnhdr_int->s_paddr;
1023 ss = scnhdr_int->s_size;
1026 PUT_SCNHDR_SIZE (abfd, ss,
1027 (bfd_byte *) scnhdr_ext->s_size);
1030 PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
1032 PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
1033 (bfd_byte *) scnhdr_ext->s_scnptr);
1034 PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
1035 (bfd_byte *) scnhdr_ext->s_relptr);
1036 PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
1037 (bfd_byte *) scnhdr_ext->s_lnnoptr);
1039 /* Extra flags must be set when dealing with NT. All sections should also
1040 have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
1041 .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1042 sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1043 (this is especially important when dealing with the .idata section since
1044 the addresses for routines from .dlls must be overwritten). If .reloc
1045 section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1046 (0x02000000). Also, the resource data should also be read and
1049 /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1050 /* FIXME: even worse, I don't see how to get the original alignment field*/
1054 int flags = scnhdr_int->s_flags;
1055 if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
1056 strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
1057 strcmp (scnhdr_int->s_name, ".rsrc") == 0 ||
1058 strcmp (scnhdr_int->s_name, ".bss") == 0)
1059 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1060 else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1061 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1062 else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1063 flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
1064 else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1065 flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
1066 else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1067 || strcmp (scnhdr_int->s_name, ".edata") == 0)
1068 flags = IMAGE_SCN_MEM_READ | SEC_DATA;
1069 /* ppc-nt additions */
1070 else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1071 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1072 IMAGE_SCN_MEM_READ ;
1073 /* Remember this field is a max of 8 chars, so the null is _not_ there
1074 for an 8 character name like ".reldata". (yep. Stupid bug) */
1075 else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
1076 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1077 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1078 else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1079 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1080 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1081 else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1082 flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1083 /* end of ppc-nt additions */
1084 #ifdef POWERPC_LE_PE
1085 else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0)
1087 flags = IMAGE_SCN_LNK_INFO;
1089 else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1091 flags = IMAGE_SCN_LNK_INFO;
1095 bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1098 if (scnhdr_int->s_nlnno <= 0xffff)
1099 bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1102 (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1103 bfd_get_filename (abfd),
1104 scnhdr_int->s_nlnno);
1105 bfd_set_error (bfd_error_file_truncated);
1106 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1109 if (scnhdr_int->s_nreloc <= 0xffff)
1110 bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1113 (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1114 bfd_get_filename (abfd),
1115 scnhdr_int->s_nreloc);
1116 bfd_set_error (bfd_error_file_truncated);
1117 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1123 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1125 "Export Directory [.edata]",
1126 "Import Directory [parts of .idata]",
1127 "Resource Directory [.rsrc]",
1128 "Exception Directory [.pdata]",
1129 "Security Directory",
1130 "Base Relocation Directory [.reloc]",
1132 "Description Directory",
1133 "Special Directory",
1134 "Thread Storage Directory [.tls]",
1135 "Load Configuration Directory",
1136 "Bound Import Directory",
1137 "Import Address Table Directory",
1143 /**********************************************************************/
1145 pe_print_idata(abfd, vfile)
1151 asection *section = bfd_get_section_by_name (abfd, ".idata");
1153 #ifdef POWERPC_LE_PE
1154 asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1157 bfd_size_type datasize = 0;
1159 bfd_size_type start, stop;
1162 pe_data_type *pe = pe_data (abfd);
1163 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1168 #ifdef POWERPC_LE_PE
1169 if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1171 /* The toc address can be found by taking the starting address,
1172 which on the PPC locates a function descriptor. The descriptor
1173 consists of the function code starting address followed by the
1174 address of the toc. The starting address we get from the bfd,
1175 and the descriptor is supposed to be in the .reldata section.
1178 bfd_vma loadable_toc_address;
1179 bfd_vma toc_address;
1180 bfd_vma start_address;
1183 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1185 if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1188 datasize = bfd_section_size (abfd, rel_section);
1190 bfd_get_section_contents (abfd,
1193 bfd_section_size (abfd, rel_section));
1195 offset = abfd->start_address - rel_section->vma;
1197 start_address = bfd_get_32(abfd, data+offset);
1198 loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1199 toc_address = loadable_toc_address - 32768;
1202 "\nFunction descriptor located at the start address: %04lx\n",
1203 (unsigned long int) (abfd->start_address));
1205 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
1206 start_address, loadable_toc_address, toc_address);
1211 "\nThe Import Tables (interpreted .idata section contents)\n");
1213 " vma: Hint Time Forward DLL First\n");
1215 " Table Stamp Chain Name Thunk\n");
1217 if (bfd_section_size (abfd, section) == 0)
1220 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1221 datasize = bfd_section_size (abfd, section);
1222 if (data == NULL && datasize != 0)
1225 bfd_get_section_contents (abfd,
1228 bfd_section_size (abfd, section));
1232 stop = bfd_section_size (abfd, section);
1234 for (i = start; i < stop; i += onaline)
1238 bfd_vma forward_chain;
1240 bfd_vma first_thunk;
1244 int adj = extra->ImageBase - section->vma;
1248 (unsigned long int) (i + section->vma));
1256 hint_addr = bfd_get_32(abfd, data+i);
1257 time_stamp = bfd_get_32(abfd, data+i+4);
1258 forward_chain = bfd_get_32(abfd, data+i+8);
1259 dll_name = bfd_get_32(abfd, data+i+12);
1260 first_thunk = bfd_get_32(abfd, data+i+16);
1262 fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1274 /* the image base is present in the section->vma */
1275 dll = data + dll_name + adj;
1276 fprintf(file, "\n\tDLL Name: %s\n", dll);
1277 fprintf(file, "\tvma: Ordinal Member-Name\n");
1279 idx = hint_addr + adj;
1281 for (j=0;j<stop;j+=4)
1285 bfd_vma member = bfd_get_32(abfd, data + idx + j);
1288 ordinal = bfd_get_16(abfd,
1289 data + member + adj);
1290 member_name = data + member + adj + 2;
1291 fprintf(file, "\t%04lx\t %4d %s\n",
1292 member, ordinal, member_name);
1295 if (hint_addr != first_thunk)
1300 idx2 = first_thunk + adj;
1302 for (j=0;j<stop;j+=4)
1306 bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1307 bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1308 if (hint_member != iat_member)
1313 "\tThe Import Address Table (difference found)\n");
1314 fprintf(file, "\tvma: Ordinal Member-Name\n");
1317 if (iat_member == 0)
1320 "\t>>> Ran out of IAT members!\n");
1324 ordinal = bfd_get_16(abfd,
1325 data + iat_member + adj);
1326 member_name = data + iat_member + adj + 2;
1327 fprintf(file, "\t%04lx\t %4d %s\n",
1328 iat_member, ordinal, member_name);
1332 if (hint_member == 0)
1338 "\tThe Import Address Table is identical\n");
1342 fprintf(file, "\n");
1352 pe_print_edata(abfd, vfile)
1358 asection *section = bfd_get_section_by_name (abfd, ".edata");
1360 bfd_size_type datasize = 0;
1366 long export_flags; /* reserved - should be zero */
1370 bfd_vma name; /* rva - relative to image base */
1371 long base; /* ordinal base */
1372 long num_functions; /* Number in the export address table */
1373 long num_names; /* Number in the name pointer table */
1374 bfd_vma eat_addr; /* rva to the export address table */
1375 bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
1376 bfd_vma ot_addr; /* rva to the Ordinal Table */
1379 pe_data_type *pe = pe_data (abfd);
1380 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1385 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1387 datasize = bfd_section_size (abfd, section);
1389 if (data == NULL && datasize != 0)
1392 bfd_get_section_contents (abfd,
1395 bfd_section_size (abfd, section));
1397 /* Go get Export Directory Table */
1398 edt.export_flags = bfd_get_32(abfd, data+0);
1399 edt.time_stamp = bfd_get_32(abfd, data+4);
1400 edt.major_ver = bfd_get_16(abfd, data+8);
1401 edt.minor_ver = bfd_get_16(abfd, data+10);
1402 edt.name = bfd_get_32(abfd, data+12);
1403 edt.base = bfd_get_32(abfd, data+16);
1404 edt.num_functions = bfd_get_32(abfd, data+20);
1405 edt.num_names = bfd_get_32(abfd, data+24);
1406 edt.eat_addr = bfd_get_32(abfd, data+28);
1407 edt.npt_addr = bfd_get_32(abfd, data+32);
1408 edt.ot_addr = bfd_get_32(abfd, data+36);
1410 adj = extra->ImageBase - section->vma;
1413 /* Dump the EDT first first */
1415 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1418 "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
1421 "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
1424 "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1428 fprintf_vma (file, edt.name);
1430 "%s\n", data + edt.name + adj);
1433 "Ordinal Base \t\t\t%ld\n", edt.base);
1439 "\tExport Address Table \t\t%lx\n",
1440 (unsigned long) edt.num_functions);
1443 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
1446 "Table Addresses\n");
1449 "\tExport Address Table \t\t");
1450 fprintf_vma (file, edt.eat_addr);
1451 fprintf (file, "\n");
1454 "\tName Pointer Table \t\t");
1455 fprintf_vma (file, edt.npt_addr);
1456 fprintf (file, "\n");
1459 "\tOrdinal Table \t\t\t");
1460 fprintf_vma (file, edt.ot_addr);
1461 fprintf (file, "\n");
1464 /* The next table to find si the Export Address Table. It's basically
1465 a list of pointers that either locate a function in this dll, or
1466 forward the call to another dll. Something like:
1471 } export_address_table_entry;
1475 "\nExport Address Table -- Ordinal Base %ld\n",
1478 for (i = 0; i < edt.num_functions; ++i)
1480 bfd_vma eat_member = bfd_get_32(abfd,
1481 data + edt.eat_addr + (i*4) + adj);
1482 bfd_vma eat_actual = extra->ImageBase + eat_member;
1483 bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1484 bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1487 if (eat_member == 0)
1490 if (edata_start < eat_actual && eat_actual < edata_end)
1492 /* this rva is to a name (forwarding function) in our section */
1493 /* Should locate a function descriptor */
1495 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1496 (long) i, (long) (i + edt.base), eat_member,
1497 "Forwarder RVA", data + eat_member + adj);
1501 /* Should locate a function descriptor in the reldata section */
1503 "\t[%4ld] +base[%4ld] %04lx %s\n",
1504 (long) i, (long) (i + edt.base), eat_member, "Export RVA");
1508 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1509 /* Dump them in parallel for clarity */
1511 "\n[Ordinal/Name Pointer] Table\n");
1513 for (i = 0; i < edt.num_names; ++i)
1515 bfd_vma name_ptr = bfd_get_32(abfd,
1520 char *name = data + name_ptr + adj;
1522 bfd_vma ord = bfd_get_16(abfd,
1527 "\t[%4ld] %s\n", (long) ord, name);
1537 pe_print_pdata(abfd, vfile)
1543 asection *section = bfd_get_section_by_name (abfd, ".pdata");
1544 bfd_size_type datasize = 0;
1546 bfd_size_type start, stop;
1552 stop = bfd_section_size (abfd, section);
1553 if ((stop % onaline) != 0)
1554 fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1555 (long)stop, onaline);
1558 "\nThe Function Table (interpreted .pdata section contents)\n");
1560 " vma:\t\tBegin End EH EH PrologEnd\n");
1562 " \t\tAddress Address Handler Data Address\n");
1564 if (bfd_section_size (abfd, section) == 0)
1567 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1568 datasize = bfd_section_size (abfd, section);
1569 if (data == NULL && datasize != 0)
1572 bfd_get_section_contents (abfd,
1575 bfd_section_size (abfd, section));
1579 for (i = start; i < stop; i += onaline)
1585 bfd_vma prolog_end_addr;
1590 begin_addr = bfd_get_32(abfd, data+i);
1591 end_addr = bfd_get_32(abfd, data+i+4);
1592 eh_handler = bfd_get_32(abfd, data+i+8);
1593 eh_data = bfd_get_32(abfd, data+i+12);
1594 prolog_end_addr = bfd_get_32(abfd, data+i+16);
1596 if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1597 && eh_data == 0 && prolog_end_addr == 0)
1599 /* We are probably into the padding of the
1606 (unsigned long int) (i + section->vma));
1608 fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1615 #ifdef POWERPC_LE_PE
1616 if (eh_handler == 0 && eh_data != 0)
1618 /* Special bits here, although the meaning may */
1619 /* be a little mysterious. The only one I know */
1620 /* for sure is 0x03. */
1621 /* Code Significance */
1623 /* 0x01 Register Save Millicode */
1624 /* 0x02 Register Restore Millicode */
1625 /* 0x03 Glue Code Sequence */
1629 fprintf(file, " Register save millicode");
1632 fprintf(file, " Register restore millicode");
1635 fprintf(file, " Glue code sequence");
1642 fprintf(file, "\n");
1650 static const char *tbl[6] =
1661 pe_print_reloc(abfd, vfile)
1667 asection *section = bfd_get_section_by_name (abfd, ".reloc");
1668 bfd_size_type datasize = 0;
1670 bfd_size_type start, stop;
1675 if (bfd_section_size (abfd, section) == 0)
1679 "\n\nPE File Base Relocations (interpreted .reloc"
1680 " section contents)\n");
1682 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1683 datasize = bfd_section_size (abfd, section);
1684 if (data == NULL && datasize != 0)
1687 bfd_get_section_contents (abfd,
1690 bfd_section_size (abfd, section));
1694 stop = bfd_section_size (abfd, section);
1696 for (i = start; i < stop;)
1699 bfd_vma virtual_address;
1702 /* The .reloc section is a sequence of blocks, with a header consisting
1703 of two 32 bit quantities, followed by a number of 16 bit entries */
1705 virtual_address = bfd_get_32(abfd, data+i);
1706 size = bfd_get_32(abfd, data+i+4);
1707 number = (size - 8) / 2;
1715 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
1716 virtual_address, size, size, number);
1718 for (j = 0; j < number; ++j)
1720 unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1721 int t = (e & 0xF000) >> 12;
1722 int off = e & 0x0FFF;
1728 "\treloc %4d offset %4x [%4lx] %s\n",
1729 j, off, (long) (off + virtual_address), tbl[t]);
1741 pe_print_private_bfd_data (abfd, vfile)
1745 FILE *file = (FILE *) vfile;
1747 pe_data_type *pe = pe_data (abfd);
1748 struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1750 fprintf (file,"\nImageBase\t\t");
1751 fprintf_vma (file, i->ImageBase);
1752 fprintf (file,"\nSectionAlignment\t");
1753 fprintf_vma (file, i->SectionAlignment);
1754 fprintf (file,"\nFileAlignment\t\t");
1755 fprintf_vma (file, i->FileAlignment);
1756 fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1757 fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1758 fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1759 fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1760 fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1761 fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1762 fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1763 fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1764 fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1765 fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1766 fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1767 fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1768 fprintf (file,"SizeOfStackReserve\t");
1769 fprintf_vma (file, i->SizeOfStackReserve);
1770 fprintf (file,"\nSizeOfStackCommit\t");
1771 fprintf_vma (file, i->SizeOfStackCommit);
1772 fprintf (file,"\nSizeOfHeapReserve\t");
1773 fprintf_vma (file, i->SizeOfHeapReserve);
1774 fprintf (file,"\nSizeOfHeapCommit\t");
1775 fprintf_vma (file, i->SizeOfHeapCommit);
1776 fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1777 fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1779 fprintf (file,"\nThe Data Directory\n");
1780 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1782 fprintf (file, "Entry %1x ", j);
1783 fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1784 fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1785 fprintf (file, "%s\n", dir_names[j]);
1788 pe_print_idata(abfd, vfile);
1789 pe_print_edata(abfd, vfile);
1790 pe_print_pdata(abfd, vfile);
1791 pe_print_reloc(abfd, vfile);
1801 abfd->tdata.pe_obj_data =
1802 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1804 if (abfd->tdata.pe_obj_data == 0)
1807 pe = pe_data (abfd);
1810 pe->in_reloc_p = in_reloc_p;
1814 /* Create the COFF backend specific information. */
1816 pe_mkobject_hook (abfd, filehdr, aouthdr)
1821 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1824 if (pe_mkobject (abfd) == false)
1827 pe = pe_data (abfd);
1828 pe->coff.sym_filepos = internal_f->f_symptr;
1829 /* These members communicate important constants about the symbol
1830 table to GDB's symbol-reading code. These `constants'
1831 unfortunately vary among coff implementations... */
1832 pe->coff.local_n_btmask = N_BTMASK;
1833 pe->coff.local_n_btshft = N_BTSHFT;
1834 pe->coff.local_n_tmask = N_TMASK;
1835 pe->coff.local_n_tshift = N_TSHIFT;
1836 pe->coff.local_symesz = SYMESZ;
1837 pe->coff.local_auxesz = AUXESZ;
1838 pe->coff.local_linesz = LINESZ;
1840 obj_raw_syment_count (abfd) =
1841 obj_conv_table_size (abfd) =
1842 internal_f->f_nsyms;
1844 pe->real_flags = internal_f->f_flags;
1846 #ifdef COFF_IMAGE_WITH_PE
1849 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1858 /* Copy any private info we understand from the input bfd
1859 to the output bfd. */
1861 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1864 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1867 /* One day we may try to grok other private data. */
1868 if (ibfd->xvec->flavour != bfd_target_coff_flavour
1869 || obfd->xvec->flavour != bfd_target_coff_flavour)
1872 pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;