static void pex64_dump_xdata (FILE *file, bfd *abfd, asection *xdata_section, bfd_byte *xdata, bfd_vma *endx, struct pex64_runtime_function *rf) { bfd_vma vaddr; bfd_vma end_addr; bfd_vma addr = rf->rva_UnwindData; bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size; struct pex64_unwind_info ui; vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase; addr -= vaddr; /* PR 17512: file: 2245-7442-0.004. */ if (addr >= sec_size) { fprintf (file, _("warning: xdata section corrupt\n")); return; } if (endx) { end_addr = endx[0] - vaddr; /* PR 17512: file: 2245-7442-0.004. */ if (end_addr > sec_size) { fprintf (file, _("warning: xdata section corrupt")); end_addr = sec_size; } } else end_addr = sec_size; pex64_get_unwind_info (abfd, &ui, &xdata[addr]); if (ui.Version != 1 && ui.Version != 2) { unsigned int i; fprintf (file, "\tVersion %u (unknown).\n", (unsigned int) ui.Version); for (i = 0; addr < end_addr; addr += 1, i++) { if ((i & 15) == 0) fprintf (file, "\t %03x:", i); fprintf (file, " %02x", xdata[addr]); if ((i & 15) == 15) fprintf (file, "\n"); } if ((i & 15) != 0) fprintf (file, "\n"); return; } fprintf (file, "\tVersion: %d, Flags: ", ui.Version); switch (ui.Flags) { case UNW_FLAG_NHANDLER: fprintf (file, "none"); break; case UNW_FLAG_EHANDLER: fprintf (file, "UNW_FLAG_EHANDLER"); break; case UNW_FLAG_UHANDLER: fprintf (file, "UNW_FLAG_UHANDLER"); break; case UNW_FLAG_FHANDLER: fprintf (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER"); break; case UNW_FLAG_CHAININFO: fprintf (file, "UNW_FLAG_CHAININFO"); break; default: fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags); break; } fputc ('\n', file); fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes); fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ", (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset); fprintf (file, "Frame reg: %s\n", ui.FrameRegister == 0 ? "none" : pex_regs[(unsigned int) ui.FrameRegister]); /* PR 17512: file: 2245-7442-0.004. */ if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size) fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes); else pex64_xdata_print_uwd_codes (file, abfd, &ui, rf); switch (ui.Flags) { case UNW_FLAG_EHANDLER: case UNW_FLAG_UHANDLER: case UNW_FLAG_FHANDLER: fprintf (file, "\tHandler: "); fprintf_vma (file, (ui.rva_ExceptionHandler + pe_data (abfd)->pe_opthdr.ImageBase)); fprintf (file, ".\n"); break; case UNW_FLAG_CHAININFO: fprintf (file, "\tChain: start: "); fprintf_vma (file, ui.rva_BeginAddress); fprintf (file, ", end: "); fprintf_vma (file, ui.rva_EndAddress); fprintf (file, "\n\t unwind data: "); fprintf_vma (file, ui.rva_UnwindData); fprintf (file, ".\n"); break; } /* Now we need end of this xdata block. */ addr += ui.SizeOfBlock; if (addr < end_addr) { unsigned int i; fprintf (file,"\tUser data:\n"); for (i = 0; addr < end_addr; addr += 1, i++) { if ((i & 15) == 0) fprintf (file, "\t %03x:", i); fprintf (file, " %02x", xdata[addr]); if ((i & 15) == 15) fprintf (file, "\n"); } if ((i & 15) != 0) fprintf (file, "\n"); } }
static void pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr) { asection *section = pex64_get_section_by_rva (abfd, addr, ".rdata"); bfd_vma vsize; bfd_byte *data = NULL; bfd_vma i; if (!section) section = pex64_get_section_by_rva (abfd, addr, ".data"); if (!section) section = pex64_get_section_by_rva (abfd, addr, ".xdata"); if (!section) { section = pex64_get_section_by_rva (abfd, addr, ".pdata"); if (section) { fprintf (file, "\t Shares information with pdata element at 0x"); fprintf_vma (file, addr + pe_data (abfd)->pe_opthdr.ImageBase); fprintf (file, ".\n"); } } if (!section) return; vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase; addr -= vsize; if (bfd_malloc_and_get_section (abfd, section, &data)) { struct pex64_unwind_info ui; if (!data) return; pex64_get_unwind_info (abfd, &ui, &data[addr]); if (ui.Version != 1) { fprintf (file, "\tVersion %u (unknown).\n", (unsigned int) ui.Version); return; } fprintf (file, "\tFlags: "); switch (ui.Flags) { case UNW_FLAG_NHANDLER: fprintf (file, "UNW_FLAG_NHANDLER"); break; case UNW_FLAG_EHANDLER: fprintf (file, "UNW_FLAG_EHANDLER"); break; case UNW_FLAG_UHANDLER: fprintf (file, "UNW_FLAG_UHANDLER"); break; case UNW_FLAG_FHANDLER: fprintf (file, "UNW_FLAG_FHANDLER = (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)"); break; case UNW_FLAG_CHAININFO: fprintf (file, "UNW_FLAG_CHAININFO"); break; default: fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags); break; } fprintf (file, ".\n"); if (ui.CountOfCodes != 0) fprintf (file, "\tEntry has %u codes.", (unsigned int) ui.CountOfCodes); fprintf (file, "\tPrologue size: %u, Frame offset = 0x%x.\n", (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset); fprintf (file, "\tFrame register is %s.\n", ui.FrameRegister == 0 ? "CFA" : pex_regs[(unsigned int) ui.FrameRegister]); pex64_xdata_print_uwd_codes (file, &ui, pc_addr); switch (ui.Flags) { case UNW_FLAG_NHANDLER: return; case UNW_FLAG_EHANDLER: fprintf (file, "\texception_handler at 0x%x.\n", (unsigned int) ui.rva_ExceptionHandler); break; case UNW_FLAG_UHANDLER: fprintf (file, "\ttermination_handler at 0x%x.\n", (unsigned int) ui.rva_TerminationHandler); case UNW_FLAG_FHANDLER: fprintf (file, "\tframe_handler at 0x%x.\n", (unsigned int) ui.rva_FrameHandler); fprintf (file, "\t Argument for FrameHandler: 0x%x.\n", (unsigned int) ui.FrameHandlerArgument); return; case UNW_FLAG_CHAININFO: fprintf (file, "\t Function Entry: 0x%x\n", (unsigned int) ui.rva_FunctionEntry); return; default: fprintf (file, "\t Unknown flag value of 0x%x\n", (unsigned int) ui.Flags); return; } fprintf (file, "\t 0x%x # of scope(s)\n", (unsigned int) ui.CountOfScopes); for (i = 0; i < ui.CountOfScopes; i++) { struct pex64_scope_entry se; pex64_get_scope_entry (abfd, &se, i, ui.rawScopeEntries); fprintf (file, "\t scope #%u: BeginAddress: 0x%x, EndAddress: 0x%x," "\n\t\tHandlerAddress:0x%x, JumpTarget:0x%x\n", (unsigned int) (i + 1), (unsigned int) se.rva_BeginAddress, (unsigned int) se.rva_EndAddress, (unsigned int) se.rva_HandlerAddress, (unsigned int) se.rva_JumpAddress); } } if (data != NULL) free (data); }