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