1 /* BFD back-end for Intel 386 PE IMAGE COFF files. 2 Copyright (C) 2006-2022 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 bool 102 pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, 103 void *data, void *data_end) 104 { 105 struct external_pex64_unwind_info *ex_ui = 106 (struct external_pex64_unwind_info *) data; 107 bfd_byte *ex_dta = (bfd_byte *) data; 108 bfd_byte *ex_dta_end = (bfd_byte *) data_end; 109 110 memset (ui, 0, sizeof (struct pex64_unwind_info)); 111 112 if (ex_dta_end - ex_dta < 4) 113 return false; 114 115 ui->Version = PEX64_UWI_VERSION (ex_ui->Version_Flags); 116 ui->Flags = PEX64_UWI_FLAGS (ex_ui->Version_Flags); 117 ui->SizeOfPrologue = (bfd_vma) ex_ui->SizeOfPrologue; 118 ui->CountOfCodes = (bfd_vma) ex_ui->CountOfCodes; 119 ui->FrameRegister = PEX64_UWI_FRAMEREG (ex_ui->FrameRegisterOffset); 120 ui->FrameOffset = PEX64_UWI_FRAMEOFF (ex_ui->FrameRegisterOffset); 121 ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes); 122 ui->SizeOfBlock = ui->sizeofUnwindCodes + 4; 123 ui->rawUnwindCodes = ex_dta + 4; 124 ui->rawUnwindCodesEnd = ex_dta_end; 125 126 if ((size_t) (ex_dta_end - ex_dta) < ui->SizeOfBlock) 127 return false; 128 ex_dta += ui->SizeOfBlock; 129 130 switch (ui->Flags) 131 { 132 case UNW_FLAG_CHAININFO: 133 if (ex_dta_end - ex_dta < 12) 134 return false; 135 ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0); 136 ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4); 137 ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8); 138 ui->SizeOfBlock += 12; 139 return true; 140 case UNW_FLAG_EHANDLER: 141 case UNW_FLAG_UHANDLER: 142 case UNW_FLAG_FHANDLER: 143 if (ex_dta_end - ex_dta < 4) 144 return false; 145 ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta); 146 ui->SizeOfBlock += 4; 147 return true; 148 default: 149 return true; 150 } 151 } 152 153 /* Display unwind codes. */ 154 155 static void 156 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd, 157 struct pex64_unwind_info *ui, 158 struct pex64_runtime_function *rf) 159 { 160 unsigned int i; 161 unsigned int tmp; /* At least 32 bits. */ 162 int save_allowed; 163 164 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL) 165 return; 166 167 /* According to UNWIND_CODE documentation: 168 If an FP reg is used, the any unwind code taking an offset must only be 169 used after the FP reg is established in the prolog. 170 But there are counter examples of that in system dlls... */ 171 save_allowed = true; 172 173 i = 0; 174 175 if ((size_t) (ui->rawUnwindCodesEnd - ui->rawUnwindCodes) 176 < ui->CountOfCodes * 2) 177 { 178 fprintf (file, _("warning: corrupt unwind data\n")); 179 return; 180 } 181 182 if (ui->Version == 2 183 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG) 184 { 185 /* Display epilog opcode (whose docoding is not fully documented). 186 Looks to be designed to speed-up unwinding, as there is no need 187 to decode instruction flow if outside an epilog. */ 188 unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress; 189 190 fprintf (file, "\tv2 epilog (length: %02x) at pc+:", 191 ui->rawUnwindCodes[0]); 192 193 if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1])) 194 fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]); 195 196 i++; 197 for (; i < ui->CountOfCodes; i++) 198 { 199 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i; 200 unsigned int off; 201 202 if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG) 203 break; 204 off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8); 205 if (off == 0) 206 fprintf (file, " [pad]"); 207 else 208 fprintf (file, " 0x%x", func_size - off); 209 } 210 fputc ('\n', file); 211 } 212 213 for (; i < ui->CountOfCodes; i++) 214 { 215 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i; 216 unsigned int info = PEX64_UNWCODE_INFO (dta[1]); 217 int unexpected = false; 218 219 fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]); 220 221 switch (PEX64_UNWCODE_CODE (dta[1])) 222 { 223 case UWOP_PUSH_NONVOL: 224 fprintf (file, "push %s", pex_regs[info]); 225 break; 226 227 case UWOP_ALLOC_LARGE: 228 if (info == 0) 229 { 230 if (ui->rawUnwindCodesEnd - dta < 4) 231 { 232 fprintf (file, _("warning: corrupt unwind data\n")); 233 return; 234 } 235 tmp = bfd_get_16 (abfd, dta + 2) * 8; 236 i++; 237 } 238 else 239 { 240 if (ui->rawUnwindCodesEnd - dta < 6) 241 { 242 fprintf (file, _("warning: corrupt unwind data\n")); 243 return; 244 } 245 tmp = bfd_get_32 (abfd, dta + 2); 246 i += 2; 247 } 248 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp); 249 break; 250 251 case UWOP_ALLOC_SMALL: 252 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8); 253 break; 254 255 case UWOP_SET_FPREG: 256 /* According to the documentation, info field is unused. */ 257 fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)", 258 pex_regs[ui->FrameRegister], 259 (unsigned int) ui->FrameOffset * 16, info); 260 unexpected = ui->FrameRegister == 0; 261 save_allowed = false; 262 break; 263 264 case UWOP_SAVE_NONVOL: 265 if (ui->rawUnwindCodesEnd - dta < 4) 266 { 267 fprintf (file, _("warning: corrupt unwind data\n")); 268 return; 269 } 270 tmp = bfd_get_16 (abfd, dta + 2) * 8; 271 i++; 272 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp); 273 unexpected = !save_allowed; 274 break; 275 276 case UWOP_SAVE_NONVOL_FAR: 277 if (ui->rawUnwindCodesEnd - dta < 6) 278 { 279 fprintf (file, _("warning: corrupt unwind data\n")); 280 return; 281 } 282 tmp = bfd_get_32 (abfd, dta + 2); 283 i += 2; 284 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp); 285 unexpected = !save_allowed; 286 break; 287 288 case UWOP_SAVE_XMM: 289 if (ui->Version == 1) 290 { 291 if (ui->rawUnwindCodesEnd - dta < 4) 292 { 293 fprintf (file, _("warning: corrupt unwind data\n")); 294 return; 295 } 296 tmp = bfd_get_16 (abfd, dta + 2) * 8; 297 i++; 298 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp); 299 unexpected = !save_allowed; 300 } 301 else if (ui->Version == 2) 302 { 303 fprintf (file, "epilog %02x %01x", dta[0], info); 304 unexpected = true; 305 } 306 break; 307 308 case UWOP_SAVE_XMM_FAR: 309 if (ui->rawUnwindCodesEnd - dta < 6) 310 { 311 fprintf (file, _("warning: corrupt unwind data\n")); 312 return; 313 } 314 tmp = bfd_get_32 (abfd, dta + 2) * 8; 315 i += 2; 316 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp); 317 unexpected = !save_allowed; 318 break; 319 320 case UWOP_SAVE_XMM128: 321 if (ui->rawUnwindCodesEnd - dta < 4) 322 { 323 fprintf (file, _("warning: corrupt unwind data\n")); 324 return; 325 } 326 tmp = bfd_get_16 (abfd, dta + 2) * 16; 327 i++; 328 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp); 329 unexpected = !save_allowed; 330 break; 331 332 case UWOP_SAVE_XMM128_FAR: 333 if (ui->rawUnwindCodesEnd - dta < 6) 334 { 335 fprintf (file, _("warning: corrupt unwind data\n")); 336 return; 337 } 338 tmp = bfd_get_32 (abfd, dta + 2) * 16; 339 i += 2; 340 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp); 341 unexpected = !save_allowed; 342 break; 343 344 case UWOP_PUSH_MACHFRAME: 345 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP"); 346 if (info == 0) 347 fprintf (file, ")"); 348 else if (info == 1) 349 fprintf (file, ",ErrorCode)"); 350 else 351 fprintf (file, ", unknown(%u))", info); 352 break; 353 354 default: 355 /* PR 17512: file: 2245-7442-0.004. */ 356 fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1])); 357 break; 358 } 359 360 if (unexpected) 361 fprintf (file, " [Unexpected!]"); 362 fputc ('\n', file); 363 } 364 } 365 366 /* Check wether section SEC_NAME contains the xdata at address ADDR. */ 367 368 static asection * 369 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name) 370 { 371 asection *section = bfd_get_section_by_name (abfd, sec_name); 372 bfd_vma vsize; 373 bfd_size_type datasize = 0; 374 375 if (section == NULL 376 || coff_section_data (abfd, section) == NULL 377 || pei_section_data (abfd, section) == NULL) 378 return NULL; 379 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase; 380 datasize = section->size; 381 if (!datasize || vsize > addr || (vsize + datasize) < addr) 382 return NULL; 383 return section; 384 } 385 386 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION 387 designate the bfd section containing the xdata, XDATA is its content, 388 and ENDX the size if known (or NULL). */ 389 390 static void 391 pex64_dump_xdata (FILE *file, bfd *abfd, 392 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx, 393 struct pex64_runtime_function *rf) 394 { 395 bfd_vma vaddr; 396 bfd_vma end_addr; 397 bfd_vma addr = rf->rva_UnwindData; 398 bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size; 399 struct pex64_unwind_info ui; 400 401 vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase; 402 addr -= vaddr; 403 404 /* PR 17512: file: 2245-7442-0.004. */ 405 if (addr >= sec_size) 406 { 407 fprintf (file, _("warning: xdata section corrupt\n")); 408 return; 409 } 410 411 if (endx) 412 { 413 end_addr = endx[0] - vaddr; 414 /* PR 17512: file: 2245-7442-0.004. */ 415 if (end_addr > sec_size) 416 { 417 fprintf (file, _("warning: xdata section corrupt\n")); 418 end_addr = sec_size; 419 } 420 } 421 else 422 end_addr = sec_size; 423 424 if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr)) 425 { 426 fprintf (file, _("warning: xdata section corrupt\n")); 427 return; 428 } 429 430 if (ui.Version != 1 && ui.Version != 2) 431 { 432 unsigned int i; 433 fprintf (file, "\tVersion %u (unknown).\n", 434 (unsigned int) ui.Version); 435 for (i = 0; addr < end_addr; addr += 1, i++) 436 { 437 if ((i & 15) == 0) 438 fprintf (file, "\t %03x:", i); 439 fprintf (file, " %02x", xdata[addr]); 440 if ((i & 15) == 15) 441 fprintf (file, "\n"); 442 } 443 if ((i & 15) != 0) 444 fprintf (file, "\n"); 445 return; 446 } 447 448 fprintf (file, "\tVersion: %d, Flags: ", ui.Version); 449 switch (ui.Flags) 450 { 451 case UNW_FLAG_NHANDLER: 452 fprintf (file, "none"); 453 break; 454 case UNW_FLAG_EHANDLER: 455 fprintf (file, "UNW_FLAG_EHANDLER"); 456 break; 457 case UNW_FLAG_UHANDLER: 458 fprintf (file, "UNW_FLAG_UHANDLER"); 459 break; 460 case UNW_FLAG_FHANDLER: 461 fprintf 462 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER"); 463 break; 464 case UNW_FLAG_CHAININFO: 465 fprintf (file, "UNW_FLAG_CHAININFO"); 466 break; 467 default: 468 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags); 469 break; 470 } 471 fputc ('\n', file); 472 fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes); 473 fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ", 474 (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset); 475 fprintf (file, "Frame reg: %s\n", 476 ui.FrameRegister == 0 ? "none" 477 : pex_regs[(unsigned int) ui.FrameRegister]); 478 479 /* PR 17512: file: 2245-7442-0.004. */ 480 if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size) 481 fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes); 482 else 483 pex64_xdata_print_uwd_codes (file, abfd, &ui, rf); 484 485 switch (ui.Flags) 486 { 487 case UNW_FLAG_EHANDLER: 488 case UNW_FLAG_UHANDLER: 489 case UNW_FLAG_FHANDLER: 490 fprintf (file, "\tHandler: %016" PRIx64 ".\n", 491 ui.rva_ExceptionHandler + pe_data (abfd)->pe_opthdr.ImageBase); 492 break; 493 case UNW_FLAG_CHAININFO: 494 fprintf (file, "\tChain: start: %016" PRIx64 ", end: %016" PRIx64, 495 ui.rva_BeginAddress, ui.rva_EndAddress); 496 fprintf (file, "\n\t unwind data: %016" PRIx64 ".\n", 497 ui.rva_UnwindData); 498 break; 499 } 500 501 /* Now we need end of this xdata block. */ 502 addr += ui.SizeOfBlock; 503 if (addr < end_addr) 504 { 505 unsigned int i; 506 fprintf (file,"\tUser data:\n"); 507 for (i = 0; addr < end_addr; addr += 1, i++) 508 { 509 if ((i & 15) == 0) 510 fprintf (file, "\t %03x:", i); 511 fprintf (file, " %02x", xdata[addr]); 512 if ((i & 15) == 15) 513 fprintf (file, "\n"); 514 } 515 if ((i & 15) != 0) 516 fprintf (file, "\n"); 517 } 518 } 519 520 /* Helper function to sort xdata. The entries of xdata are sorted to know 521 the size of each entry. */ 522 523 static int 524 sort_xdata_arr (const void *l, const void *r) 525 { 526 const bfd_vma *lp = (const bfd_vma *) l; 527 const bfd_vma *rp = (const bfd_vma *) r; 528 529 if (*lp == *rp) 530 return 0; 531 return (*lp < *rp ? -1 : 1); 532 } 533 534 /* Display unwind tables for x86-64. */ 535 536 static bool 537 pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section) 538 { 539 FILE *file = (FILE *) vfile; 540 bfd_byte *pdata = NULL; 541 bfd_byte *xdata = NULL; 542 asection *xdata_section = NULL; 543 bfd_vma xdata_base; 544 bfd_size_type i; 545 bfd_size_type datasize; 546 bfd_size_type stop; 547 bfd_vma prev_beginaddress = (bfd_vma) -1; 548 bfd_vma prev_unwinddata_rva = (bfd_vma) -1; 549 bfd_vma imagebase; 550 int onaline = PDATA_ROW_SIZE; 551 int seen_error = 0; 552 bfd_vma *xdata_arr = NULL; 553 int xdata_arr_cnt; 554 bool virt_size_is_zero = false; 555 556 /* Sanity checks. */ 557 if (pdata_section == NULL 558 || coff_section_data (abfd, pdata_section) == NULL 559 || pei_section_data (abfd, pdata_section) == NULL) 560 return true; 561 562 stop = pei_section_data (abfd, pdata_section)->virt_size; 563 if ((stop % onaline) != 0) 564 fprintf (file, 565 /* xgettext:c-format */ 566 _("Warning: %s section size (%ld) is not a multiple of %d\n"), 567 pdata_section->name, (long) stop, onaline); 568 569 datasize = pdata_section->size; 570 if (datasize == 0) 571 { 572 if (stop) 573 fprintf (file, _("Warning: %s section size is zero\n"), 574 pdata_section->name); 575 return true; 576 } 577 578 /* virt_size might be zero for objects. */ 579 if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0) 580 { 581 stop = datasize; 582 virt_size_is_zero = true; 583 } 584 else if (datasize < stop) 585 { 586 fprintf (file, 587 /* xgettext:c-format */ 588 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"), 589 pdata_section->name, (unsigned long) datasize, 590 (unsigned long) stop); 591 /* Be sure not to read past datasize. */ 592 stop = datasize; 593 } 594 595 /* Display functions table. */ 596 fprintf (file, 597 _("\nThe Function Table (interpreted %s section contents)\n"), 598 pdata_section->name); 599 600 fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n")); 601 602 if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata)) 603 goto done; 604 605 /* Table of xdata entries. */ 606 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1)); 607 xdata_arr_cnt = 0; 608 609 if (strcmp (abfd->xvec->name, "pei-x86-64") == 0) 610 imagebase = pe_data (abfd)->pe_opthdr.ImageBase; 611 else 612 imagebase = 0; 613 614 for (i = 0; i < stop; i += onaline) 615 { 616 struct pex64_runtime_function rf; 617 618 if (i + PDATA_ROW_SIZE > stop) 619 break; 620 621 pex64_get_runtime_function (abfd, &rf, &pdata[i]); 622 623 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0 624 && rf.rva_UnwindData == 0) 625 /* We are probably into the padding of the section now. */ 626 break; 627 fprintf (file, " %016" PRIx64, i + pdata_section->vma); 628 fprintf (file, ":\t%016" PRIx64, imagebase + rf.rva_BeginAddress); 629 fprintf (file, " %016" PRIx64, imagebase + rf.rva_EndAddress); 630 fprintf (file, " %016" PRIx64 "\n", imagebase + rf.rva_UnwindData); 631 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress) 632 { 633 seen_error = 1; 634 fprintf (file, " has %s begin address as predecessor\n", 635 (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same")); 636 } 637 prev_beginaddress = rf.rva_BeginAddress; 638 /* Now we check for negative addresses. */ 639 if ((prev_beginaddress & 0x80000000) != 0) 640 { 641 seen_error = 1; 642 fprintf (file, " has negative begin address\n"); 643 } 644 if ((rf.rva_EndAddress & 0x80000000) != 0) 645 { 646 seen_error = 1; 647 fprintf (file, " has negative end address\n"); 648 } 649 if ((rf.rva_UnwindData & 0x80000000) != 0) 650 { 651 seen_error = 1; 652 fprintf (file, " has negative unwind address\n"); 653 } 654 else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) 655 || virt_size_is_zero) 656 xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData; 657 } 658 659 if (seen_error) 660 goto done; 661 662 /* Add end of list marker. */ 663 xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0); 664 665 /* Sort start RVAs of xdata. */ 666 if (xdata_arr_cnt > 1) 667 qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma), 668 sort_xdata_arr); 669 670 /* Find the section containing the unwind data (.xdata). */ 671 xdata_base = xdata_arr[0]; 672 /* For sections with long names, first look for the same 673 section name, replacing .pdata by .xdata prefix. */ 674 if (strcmp (pdata_section->name, ".pdata") != 0) 675 { 676 size_t len = strlen (pdata_section->name); 677 char *xdata_name = xmalloc (len + 1); 678 679 xdata_name = memcpy (xdata_name, pdata_section->name, len + 1); 680 /* Transform .pdata prefix into .xdata prefix. */ 681 if (len > 1) 682 xdata_name [1] = 'x'; 683 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, 684 xdata_name); 685 free (xdata_name); 686 } 687 /* Second, try the .xdata section itself. */ 688 if (!xdata_section) 689 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata"); 690 /* Otherwise, if xdata_base is non zero, search also inside 691 other standard sections. */ 692 if (!xdata_section && xdata_base) 693 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata"); 694 if (!xdata_section && xdata_base) 695 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data"); 696 if (!xdata_section && xdata_base) 697 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata"); 698 if (!xdata_section && xdata_base) 699 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text"); 700 /* Transfer xdata section into xdata array. */ 701 if (!xdata_section 702 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata)) 703 goto done; 704 705 /* Avoid "also used "... ouput for single unwind info 706 in object file. */ 707 prev_unwinddata_rva = (bfd_vma) -1; 708 709 /* Do dump of pdata related xdata. */ 710 for (i = 0; i < stop; i += onaline) 711 { 712 struct pex64_runtime_function rf; 713 714 if (i + PDATA_ROW_SIZE > stop) 715 break; 716 717 pex64_get_runtime_function (abfd, &rf, &pdata[i]); 718 719 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0 720 && rf.rva_UnwindData == 0) 721 /* We are probably into the padding of the section now. */ 722 break; 723 if (i == 0) 724 fprintf (file, _("\nDump of %s\n"), xdata_section->name); 725 726 fprintf (file, " %016" PRIx64, rf.rva_UnwindData + imagebase); 727 728 if (prev_unwinddata_rva == rf.rva_UnwindData) 729 { 730 /* Do not dump again the xdata for the same entry. */ 731 fprintf (file, " also used for function at %016" PRIx64 "\n", 732 rf.rva_BeginAddress + imagebase); 733 continue; 734 } 735 else 736 prev_unwinddata_rva = rf.rva_UnwindData; 737 738 fprintf (file, " (rva: %08x): %016" PRIx64 " - %016" PRIx64 "\n", 739 (unsigned int) rf.rva_UnwindData, 740 rf.rva_BeginAddress + imagebase, 741 rf.rva_EndAddress + imagebase); 742 743 if (rf.rva_UnwindData != 0 || virt_size_is_zero) 744 { 745 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) 746 { 747 bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf); 748 bfd_vma pdata_vma = bfd_section_vma (pdata_section); 749 struct pex64_runtime_function arf; 750 751 fprintf (file, "\t shares information with "); 752 altent += imagebase; 753 754 if (altent >= pdata_vma 755 && altent - pdata_vma + PDATA_ROW_SIZE <= stop) 756 { 757 pex64_get_runtime_function 758 (abfd, &arf, &pdata[altent - pdata_vma]); 759 fprintf (file, "pdata element at 0x%016" PRIx64, 760 arf.rva_UnwindData); 761 } 762 else 763 fprintf (file, "unknown pdata element"); 764 fprintf (file, ".\n"); 765 } 766 else 767 { 768 bfd_vma *p; 769 770 /* Search for the current entry in the sorted array. */ 771 p = (bfd_vma *) 772 bsearch (&rf.rva_UnwindData, xdata_arr, 773 (size_t) xdata_arr_cnt, sizeof (bfd_vma), 774 sort_xdata_arr); 775 776 /* Advance to the next pointer into the xdata section. We may 777 have shared xdata entries, which will result in a string of 778 identical pointers in the array; advance past all of them. */ 779 while (p[0] <= rf.rva_UnwindData) 780 ++p; 781 782 if (p[0] == ~((bfd_vma) 0)) 783 p = NULL; 784 785 pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf); 786 } 787 } 788 } 789 790 done: 791 free (pdata); 792 free (xdata_arr); 793 free (xdata); 794 795 return true; 796 } 797 798 struct pex64_paps 799 { 800 void *obj; 801 /* Number of found pdata sections. */ 802 unsigned int pdata_count; 803 }; 804 805 /* Functionn prototype. */ 806 bool pex64_bfd_print_pdata (bfd *, void *); 807 808 /* Helper function for bfd_map_over_section. */ 809 static void 810 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *arg) 811 { 812 struct pex64_paps *paps = arg; 813 if (startswith (pdata->name, ".pdata")) 814 { 815 if (pex64_bfd_print_pdata_section (abfd, paps->obj, pdata)) 816 paps->pdata_count++; 817 } 818 } 819 820 bool 821 pex64_bfd_print_pdata (bfd *abfd, void *vfile) 822 { 823 asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata"); 824 struct pex64_paps paps; 825 826 if (pdata_section) 827 return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section); 828 829 paps.obj = vfile; 830 paps.pdata_count = 0; 831 bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, &paps); 832 return paps.pdata_count != 0; 833 } 834 835 #define bfd_pe_print_pdata pex64_bfd_print_pdata 836 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table 837 838 #include "coff-x86_64.c" 839