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