1 /* BFD back-end for Intel 386 PE IMAGE COFF files. 2 Copyright (C) 2006-2016 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. 20 21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */ 22 23 #include "sysdep.h" 24 #include "bfd.h" 25 26 #define TARGET_SYM x86_64_pei_vec 27 #define TARGET_NAME "pei-x86-64" 28 #define COFF_IMAGE_WITH_PE 29 #define COFF_WITH_PE 30 #define COFF_WITH_pex64 31 #define PCRELOFFSET TRUE 32 #if defined (USE_MINGW64_LEADING_UNDERSCORES) 33 #define TARGET_UNDERSCORE '_' 34 #else 35 #define TARGET_UNDERSCORE 0 36 #endif 37 /* Long section names not allowed in executable images, only object files. */ 38 #define COFF_LONG_SECTION_NAMES 0 39 #define COFF_SUPPORT_GNU_LINKONCE 40 #define COFF_LONG_FILENAMES 41 #define PDATA_ROW_SIZE (3 * 4) 42 43 #define COFF_SECTION_ALIGNMENT_ENTRIES \ 44 { COFF_SECTION_NAME_EXACT_MATCH (".bss"), \ 45 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 46 { COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \ 47 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 48 { COFF_SECTION_NAME_PARTIAL_MATCH (".rdata"), \ 49 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 50 { COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \ 51 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 52 { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ 53 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ 54 { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ 55 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ 56 { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ 57 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \ 58 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \ 59 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 } 60 61 /* Note we have to make sure not to include headers twice. 62 Not all headers are wrapped in #ifdef guards, so we define 63 PEI_HEADERS to prevent double including in coff-x86_64.c */ 64 #define PEI_HEADERS 65 #include "sysdep.h" 66 #include "bfd.h" 67 #include "libbfd.h" 68 #include "coff/x86_64.h" 69 #include "coff/internal.h" 70 #include "coff/pe.h" 71 #include "libcoff.h" 72 #include "libpei.h" 73 #include "libiberty.h" 74 75 #undef AOUTSZ 76 #define AOUTSZ PEPAOUTSZ 77 #define PEAOUTHDR PEPAOUTHDR 78 79 /* Name of registers according to SEH conventions. */ 80 81 static const char * const pex_regs[16] = { 82 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", 83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 84 }; 85 86 /* Swap in a runtime function. */ 87 88 static void 89 pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf, 90 const void *data) 91 { 92 const struct external_pex64_runtime_function *ex_rf = 93 (const struct external_pex64_runtime_function *) data; 94 rf->rva_BeginAddress = bfd_get_32 (abfd, ex_rf->rva_BeginAddress); 95 rf->rva_EndAddress = bfd_get_32 (abfd, ex_rf->rva_EndAddress); 96 rf->rva_UnwindData = bfd_get_32 (abfd, ex_rf->rva_UnwindData); 97 } 98 99 /* Swap in unwind info header. */ 100 101 static void 102 pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data) 103 { 104 struct external_pex64_unwind_info *ex_ui = 105 (struct external_pex64_unwind_info *) data; 106 bfd_byte *ex_dta = (bfd_byte *) data; 107 108 memset (ui, 0, sizeof (struct pex64_unwind_info)); 109 ui->Version = PEX64_UWI_VERSION (ex_ui->Version_Flags); 110 ui->Flags = PEX64_UWI_FLAGS (ex_ui->Version_Flags); 111 ui->SizeOfPrologue = (bfd_vma) ex_ui->SizeOfPrologue; 112 ui->CountOfCodes = (bfd_vma) ex_ui->CountOfCodes; 113 ui->FrameRegister = PEX64_UWI_FRAMEREG (ex_ui->FrameRegisterOffset); 114 ui->FrameOffset = PEX64_UWI_FRAMEOFF (ex_ui->FrameRegisterOffset); 115 ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes); 116 ui->SizeOfBlock = ui->sizeofUnwindCodes + 4; 117 ui->rawUnwindCodes = &ex_dta[4]; 118 119 ex_dta += ui->SizeOfBlock; 120 switch (ui->Flags) 121 { 122 case UNW_FLAG_CHAININFO: 123 ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0); 124 ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4); 125 ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8); 126 ui->SizeOfBlock += 12; 127 return; 128 case UNW_FLAG_EHANDLER: 129 case UNW_FLAG_UHANDLER: 130 case UNW_FLAG_FHANDLER: 131 ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta); 132 ui->SizeOfBlock += 4; 133 return; 134 default: 135 return; 136 } 137 } 138 139 /* Display unwind codes. */ 140 141 static void 142 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd, 143 struct pex64_unwind_info *ui, 144 struct pex64_runtime_function *rf) 145 { 146 unsigned int i; 147 unsigned int tmp; /* At least 32 bits. */ 148 int save_allowed; 149 150 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL) 151 return; 152 153 /* According to UNWIND_CODE documentation: 154 If an FP reg is used, the any unwind code taking an offset must only be 155 used after the FP reg is established in the prolog. 156 But there are counter examples of that in system dlls... */ 157 save_allowed = TRUE; 158 159 i = 0; 160 161 if (ui->Version == 2 162 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG) 163 { 164 /* Display epilog opcode (whose docoding is not fully documented). 165 Looks to be designed to speed-up unwinding, as there is no need 166 to decode instruction flow if outside an epilog. */ 167 unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress; 168 169 fprintf (file, "\tv2 epilog (length: %02x) at pc+:", 170 ui->rawUnwindCodes[0]); 171 if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1])) 172 fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]); 173 i++; 174 for (; i < ui->CountOfCodes; i++) 175 { 176 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i; 177 unsigned int off; 178 179 if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG) 180 break; 181 off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8); 182 if (off == 0) 183 fprintf (file, " [pad]"); 184 else 185 fprintf (file, " 0x%x", func_size - off); 186 } 187 fputc ('\n', file); 188 } 189 190 for (; i < ui->CountOfCodes; i++) 191 { 192 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i; 193 unsigned int info = PEX64_UNWCODE_INFO (dta[1]); 194 int unexpected = FALSE; 195 196 fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]); 197 switch (PEX64_UNWCODE_CODE (dta[1])) 198 { 199 case UWOP_PUSH_NONVOL: 200 fprintf (file, "push %s", pex_regs[info]); 201 break; 202 case UWOP_ALLOC_LARGE: 203 if (info == 0) 204 { 205 tmp = bfd_get_16 (abfd, &dta[2]) * 8; 206 i++; 207 } 208 else 209 { 210 tmp = bfd_get_32 (abfd, &dta[2]); 211 i += 2; 212 } 213 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp); 214 break; 215 case UWOP_ALLOC_SMALL: 216 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8); 217 break; 218 case UWOP_SET_FPREG: 219 /* According to the documentation, info field is unused. */ 220 fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)", 221 pex_regs[ui->FrameRegister], 222 (unsigned int) ui->FrameOffset * 16, info); 223 unexpected = ui->FrameRegister == 0; 224 save_allowed = FALSE; 225 break; 226 case UWOP_SAVE_NONVOL: 227 tmp = bfd_get_16 (abfd, &dta[2]) * 8; 228 i++; 229 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp); 230 unexpected = !save_allowed; 231 break; 232 case UWOP_SAVE_NONVOL_FAR: 233 tmp = bfd_get_32 (abfd, &dta[2]); 234 i += 2; 235 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp); 236 unexpected = !save_allowed; 237 break; 238 case UWOP_SAVE_XMM: 239 if (ui->Version == 1) 240 { 241 tmp = bfd_get_16 (abfd, &dta[2]) * 8; 242 i++; 243 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp); 244 unexpected = !save_allowed; 245 } 246 else if (ui->Version == 2) 247 { 248 fprintf (file, "epilog %02x %01x", dta[0], info); 249 unexpected = TRUE; 250 } 251 break; 252 case UWOP_SAVE_XMM_FAR: 253 tmp = bfd_get_32 (abfd, &dta[2]) * 8; 254 i += 2; 255 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp); 256 unexpected = !save_allowed; 257 break; 258 case UWOP_SAVE_XMM128: 259 tmp = bfd_get_16 (abfd, &dta[2]) * 16; 260 i++; 261 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp); 262 unexpected = !save_allowed; 263 break; 264 case UWOP_SAVE_XMM128_FAR: 265 tmp = bfd_get_32 (abfd, &dta[2]) * 16; 266 i += 2; 267 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp); 268 unexpected = !save_allowed; 269 break; 270 case UWOP_PUSH_MACHFRAME: 271 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP"); 272 if (info == 0) 273 fprintf (file, ")"); 274 else if (info == 1) 275 fprintf (file, ",ErrorCode)"); 276 else 277 fprintf (file, ", unknown(%u))", info); 278 break; 279 default: 280 /* PR 17512: file: 2245-7442-0.004. */ 281 fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1])); 282 break; 283 } 284 if (unexpected) 285 fprintf (file, " [Unexpected!]"); 286 fputc ('\n', file); 287 } 288 } 289 290 /* Check wether section SEC_NAME contains the xdata at address ADDR. */ 291 292 static asection * 293 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name) 294 { 295 asection *section = bfd_get_section_by_name (abfd, sec_name); 296 bfd_vma vsize; 297 bfd_size_type datasize = 0; 298 299 if (section == NULL 300 || coff_section_data (abfd, section) == NULL 301 || pei_section_data (abfd, section) == NULL) 302 return NULL; 303 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase; 304 datasize = section->size; 305 if (!datasize || vsize > addr || (vsize + datasize) < addr) 306 return NULL; 307 return section; 308 } 309 310 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION 311 designate the bfd section containing the xdata, XDATA is its content, 312 and ENDX the size if known (or NULL). */ 313 314 static void 315 pex64_dump_xdata (FILE *file, bfd *abfd, 316 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx, 317 struct pex64_runtime_function *rf) 318 { 319 bfd_vma vaddr; 320 bfd_vma end_addr; 321 bfd_vma addr = rf->rva_UnwindData; 322 bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size; 323 struct pex64_unwind_info ui; 324 325 vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase; 326 addr -= vaddr; 327 328 /* PR 17512: file: 2245-7442-0.004. */ 329 if (addr >= sec_size) 330 { 331 fprintf (file, _("warning: xdata section corrupt\n")); 332 return; 333 } 334 335 if (endx) 336 { 337 end_addr = endx[0] - vaddr; 338 /* PR 17512: file: 2245-7442-0.004. */ 339 if (end_addr > sec_size) 340 { 341 fprintf (file, _("warning: xdata section corrupt")); 342 end_addr = sec_size; 343 } 344 } 345 else 346 end_addr = sec_size; 347 348 pex64_get_unwind_info (abfd, &ui, &xdata[addr]); 349 350 if (ui.Version != 1 && ui.Version != 2) 351 { 352 unsigned int i; 353 fprintf (file, "\tVersion %u (unknown).\n", 354 (unsigned int) ui.Version); 355 for (i = 0; addr < end_addr; addr += 1, i++) 356 { 357 if ((i & 15) == 0) 358 fprintf (file, "\t %03x:", i); 359 fprintf (file, " %02x", xdata[addr]); 360 if ((i & 15) == 15) 361 fprintf (file, "\n"); 362 } 363 if ((i & 15) != 0) 364 fprintf (file, "\n"); 365 return; 366 } 367 368 fprintf (file, "\tVersion: %d, Flags: ", ui.Version); 369 switch (ui.Flags) 370 { 371 case UNW_FLAG_NHANDLER: 372 fprintf (file, "none"); 373 break; 374 case UNW_FLAG_EHANDLER: 375 fprintf (file, "UNW_FLAG_EHANDLER"); 376 break; 377 case UNW_FLAG_UHANDLER: 378 fprintf (file, "UNW_FLAG_UHANDLER"); 379 break; 380 case UNW_FLAG_FHANDLER: 381 fprintf 382 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER"); 383 break; 384 case UNW_FLAG_CHAININFO: 385 fprintf (file, "UNW_FLAG_CHAININFO"); 386 break; 387 default: 388 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags); 389 break; 390 } 391 fputc ('\n', file); 392 fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes); 393 fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ", 394 (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset); 395 fprintf (file, "Frame reg: %s\n", 396 ui.FrameRegister == 0 ? "none" 397 : pex_regs[(unsigned int) ui.FrameRegister]); 398 399 /* PR 17512: file: 2245-7442-0.004. */ 400 if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size) 401 fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes); 402 else 403 pex64_xdata_print_uwd_codes (file, abfd, &ui, rf); 404 405 switch (ui.Flags) 406 { 407 case UNW_FLAG_EHANDLER: 408 case UNW_FLAG_UHANDLER: 409 case UNW_FLAG_FHANDLER: 410 fprintf (file, "\tHandler: "); 411 fprintf_vma (file, (ui.rva_ExceptionHandler 412 + pe_data (abfd)->pe_opthdr.ImageBase)); 413 fprintf (file, ".\n"); 414 break; 415 case UNW_FLAG_CHAININFO: 416 fprintf (file, "\tChain: start: "); 417 fprintf_vma (file, ui.rva_BeginAddress); 418 fprintf (file, ", end: "); 419 fprintf_vma (file, ui.rva_EndAddress); 420 fprintf (file, "\n\t unwind data: "); 421 fprintf_vma (file, ui.rva_UnwindData); 422 fprintf (file, ".\n"); 423 break; 424 } 425 426 /* Now we need end of this xdata block. */ 427 addr += ui.SizeOfBlock; 428 if (addr < end_addr) 429 { 430 unsigned int i; 431 fprintf (file,"\tUser data:\n"); 432 for (i = 0; addr < end_addr; addr += 1, i++) 433 { 434 if ((i & 15) == 0) 435 fprintf (file, "\t %03x:", i); 436 fprintf (file, " %02x", xdata[addr]); 437 if ((i & 15) == 15) 438 fprintf (file, "\n"); 439 } 440 if ((i & 15) != 0) 441 fprintf (file, "\n"); 442 } 443 } 444 445 /* Helper function to sort xdata. The entries of xdata are sorted to know 446 the size of each entry. */ 447 448 static int 449 sort_xdata_arr (const void *l, const void *r) 450 { 451 const bfd_vma *lp = (const bfd_vma *) l; 452 const bfd_vma *rp = (const bfd_vma *) r; 453 454 if (*lp == *rp) 455 return 0; 456 return (*lp < *rp ? -1 : 1); 457 } 458 459 /* Display unwind tables for x86-64. */ 460 461 static bfd_boolean 462 pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section) 463 { 464 FILE *file = (FILE *) vfile; 465 bfd_byte *pdata = NULL; 466 bfd_byte *xdata = NULL; 467 asection *xdata_section = NULL; 468 bfd_vma xdata_base; 469 bfd_size_type i; 470 bfd_size_type datasize; 471 bfd_size_type stop; 472 bfd_vma prev_beginaddress = (bfd_vma) -1; 473 bfd_vma prev_unwinddata_rva = (bfd_vma) -1; 474 bfd_vma imagebase; 475 int onaline = PDATA_ROW_SIZE; 476 int seen_error = 0; 477 bfd_vma *xdata_arr = NULL; 478 int xdata_arr_cnt; 479 bfd_boolean virt_size_is_zero = FALSE; 480 481 /* Sanity checks. */ 482 if (pdata_section == NULL 483 || coff_section_data (abfd, pdata_section) == NULL 484 || pei_section_data (abfd, pdata_section) == NULL) 485 return TRUE; 486 487 stop = pei_section_data (abfd, pdata_section)->virt_size; 488 if ((stop % onaline) != 0) 489 fprintf (file, 490 _("Warning: %s section size (%ld) is not a multiple of %d\n"), 491 pdata_section->name, (long) stop, onaline); 492 493 datasize = pdata_section->size; 494 if (datasize == 0) 495 { 496 if (stop) 497 fprintf (file, _("Warning: %s section size is zero\n"), 498 pdata_section->name); 499 return TRUE; 500 } 501 502 /* virt_size might be zero for objects. */ 503 if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0) 504 { 505 stop = (datasize / onaline) * onaline; 506 virt_size_is_zero = TRUE; 507 } 508 else if (datasize < stop) 509 { 510 fprintf (file, 511 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"), 512 pdata_section->name, (unsigned long) datasize, 513 (unsigned long) stop); 514 /* Be sure not to read passed datasize. */ 515 stop = datasize / onaline; 516 } 517 518 /* Display functions table. */ 519 fprintf (file, 520 _("\nThe Function Table (interpreted %s section contents)\n"), 521 pdata_section->name); 522 523 fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n")); 524 525 if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata)) 526 goto done; 527 528 /* Table of xdata entries. */ 529 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1)); 530 xdata_arr_cnt = 0; 531 532 if (strcmp (abfd->xvec->name, "pei-x86-64") == 0) 533 imagebase = pe_data (abfd)->pe_opthdr.ImageBase; 534 else 535 imagebase = 0; 536 537 for (i = 0; i < stop; i += onaline) 538 { 539 struct pex64_runtime_function rf; 540 541 if (i + PDATA_ROW_SIZE > stop) 542 break; 543 544 pex64_get_runtime_function (abfd, &rf, &pdata[i]); 545 546 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0 547 && rf.rva_UnwindData == 0) 548 /* We are probably into the padding of the section now. */ 549 break; 550 fputc (' ', file); 551 fprintf_vma (file, i + pdata_section->vma); 552 fprintf (file, ":\t"); 553 fprintf_vma (file, imagebase + rf.rva_BeginAddress); 554 fprintf (file, " "); 555 fprintf_vma (file, imagebase + rf.rva_EndAddress); 556 fprintf (file, " "); 557 fprintf_vma (file, imagebase + rf.rva_UnwindData); 558 fprintf (file, "\n"); 559 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress) 560 { 561 seen_error = 1; 562 fprintf (file, " has %s begin address as predecessor\n", 563 (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same")); 564 } 565 prev_beginaddress = rf.rva_BeginAddress; 566 /* Now we check for negative addresses. */ 567 if ((prev_beginaddress & 0x80000000) != 0) 568 { 569 seen_error = 1; 570 fprintf (file, " has negative begin address\n"); 571 } 572 if ((rf.rva_EndAddress & 0x80000000) != 0) 573 { 574 seen_error = 1; 575 fprintf (file, " has negative end address\n"); 576 } 577 if ((rf.rva_UnwindData & 0x80000000) != 0) 578 { 579 seen_error = 1; 580 fprintf (file, " has negative unwind address\n"); 581 } 582 else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) 583 || virt_size_is_zero) 584 xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData; 585 } 586 587 if (seen_error) 588 goto done; 589 590 /* Add end of list marker. */ 591 xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0); 592 593 /* Sort start RVAs of xdata. */ 594 if (xdata_arr_cnt > 1) 595 qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma), 596 sort_xdata_arr); 597 598 /* Find the section containing the unwind data (.xdata). */ 599 xdata_base = xdata_arr[0]; 600 /* For sections with long names, first look for the same 601 section name, replacing .pdata by .xdata prefix. */ 602 if (strcmp (pdata_section->name, ".pdata") != 0) 603 { 604 size_t len = strlen (pdata_section->name); 605 char *xdata_name = xmalloc (len + 1); 606 607 xdata_name = memcpy (xdata_name, pdata_section->name, len + 1); 608 /* Transform .pdata prefix into .xdata prefix. */ 609 if (len > 1) 610 xdata_name [1] = 'x'; 611 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, 612 xdata_name); 613 free (xdata_name); 614 } 615 /* Second, try the .xdata section itself. */ 616 if (!xdata_section) 617 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata"); 618 /* Otherwise, if xdata_base is non zero, search also inside 619 other standard sections. */ 620 if (!xdata_section && xdata_base) 621 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata"); 622 if (!xdata_section && xdata_base) 623 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data"); 624 if (!xdata_section && xdata_base) 625 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata"); 626 if (!xdata_section && xdata_base) 627 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text"); 628 /* Transfer xdata section into xdata array. */ 629 if (!xdata_section 630 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata)) 631 goto done; 632 633 /* Avoid "also used "... ouput for single unwind info 634 in object file. */ 635 prev_unwinddata_rva = (bfd_vma) -1; 636 637 /* Do dump of pdata related xdata. */ 638 for (i = 0; i < stop; i += onaline) 639 { 640 struct pex64_runtime_function rf; 641 642 if (i + PDATA_ROW_SIZE > stop) 643 break; 644 645 pex64_get_runtime_function (abfd, &rf, &pdata[i]); 646 647 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0 648 && rf.rva_UnwindData == 0) 649 /* We are probably into the padding of the section now. */ 650 break; 651 if (i == 0) 652 fprintf (file, _("\nDump of %s\n"), xdata_section->name); 653 654 fputc (' ', file); 655 fprintf_vma (file, rf.rva_UnwindData + imagebase); 656 657 if (prev_unwinddata_rva == rf.rva_UnwindData) 658 { 659 /* Do not dump again the xdata for the same entry. */ 660 fprintf (file, " also used for function at "); 661 fprintf_vma (file, rf.rva_BeginAddress + imagebase); 662 fputc ('\n', file); 663 continue; 664 } 665 else 666 prev_unwinddata_rva = rf.rva_UnwindData; 667 668 fprintf (file, " (rva: %08x): ", 669 (unsigned int) rf.rva_UnwindData); 670 fprintf_vma (file, rf.rva_BeginAddress + imagebase); 671 fprintf (file, " - "); 672 fprintf_vma (file, rf.rva_EndAddress + imagebase); 673 fputc ('\n', file); 674 675 if (rf.rva_UnwindData != 0 || virt_size_is_zero) 676 { 677 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) 678 { 679 bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf); 680 bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section); 681 struct pex64_runtime_function arf; 682 683 fprintf (file, "\t shares information with "); 684 altent += imagebase; 685 686 if (altent >= pdata_vma 687 && (altent + PDATA_ROW_SIZE <= pdata_vma 688 + pei_section_data (abfd, pdata_section)->virt_size)) 689 { 690 pex64_get_runtime_function 691 (abfd, &arf, &pdata[altent - pdata_vma]); 692 fprintf (file, "pdata element at 0x"); 693 fprintf_vma (file, arf.rva_UnwindData); 694 } 695 else 696 fprintf (file, "unknown pdata element"); 697 fprintf (file, ".\n"); 698 } 699 else 700 { 701 bfd_vma *p; 702 703 /* Search for the current entry in the sorted array. */ 704 p = (bfd_vma *) 705 bsearch (&rf.rva_UnwindData, xdata_arr, 706 (size_t) xdata_arr_cnt, sizeof (bfd_vma), 707 sort_xdata_arr); 708 709 /* Advance to the next pointer into the xdata section. We may 710 have shared xdata entries, which will result in a string of 711 identical pointers in the array; advance past all of them. */ 712 while (p[0] <= rf.rva_UnwindData) 713 ++p; 714 715 if (p[0] == ~((bfd_vma) 0)) 716 p = NULL; 717 718 pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf); 719 } 720 } 721 } 722 723 done: 724 free (pdata); 725 free (xdata_arr); 726 free (xdata); 727 728 return TRUE; 729 } 730 731 /* Static counter of number of found pdata sections. */ 732 static bfd_boolean pdata_count; 733 734 /* Functionn prototype. */ 735 bfd_boolean pex64_bfd_print_pdata (bfd *, void *); 736 737 /* Helper function for bfd_map_over_section. */ 738 static void 739 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj) 740 { 741 if (CONST_STRNEQ (pdata->name, ".pdata")) 742 { 743 if (pex64_bfd_print_pdata_section (abfd, obj, pdata)) 744 pdata_count++; 745 } 746 } 747 748 bfd_boolean 749 pex64_bfd_print_pdata (bfd *abfd, void *vfile) 750 { 751 asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata"); 752 753 if (pdata_section) 754 return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section); 755 756 pdata_count = 0; 757 bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile); 758 return (pdata_count > 0); 759 } 760 761 #define bfd_pe_print_pdata pex64_bfd_print_pdata 762 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table 763 764 #include "coff-x86_64.c" 765