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