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