This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Patch] Improve dump of xdata/pdata for Windows x86
- From: Tristan Gingold <gingold at adacore dot com>
- To: binutils Development <binutils at sourceware dot org>
- Cc: Dave Korn <dave dot korn dot cygwin at gmail dot com>, Kai Tietz <ktietz at redhat dot com>
- Date: Tue, 5 Jun 2012 17:14:23 +0200
- Subject: [Patch] Improve dump of xdata/pdata for Windows x86
Hi,
while working on Windows 64 SEH info, I think it was worth improving the output of 'objdump -p':
* exception handler and chained unwind info are now displayed
* for chained pdata entries, the corresponding unwind info rva is now printed.
I also made the corresponding cleanup changes in include/coff/pe.h after checking by git grep that the fields deleted weren't used.
No regressions while cross-checking on Darwin for x86_64-pc-mingw32.
Ok for trunk ?
Tristan.
bfd/
2012-06-05 Tristan Gingold <gingold@adacore.com>
* pei-x86_64.c (pex64_get_runtime_function): Do not decode chain flag.
(pex64_get_unwind_info): Decode exception handler and chained
unwind info.
(pex64_dump_xdata): Add comment. Display exception handler and
chained unwind info.
(pex64_bfd_print_pdata): Adjust. Display shared unwind entry for chain.
include/coff/
2012-06-05 Tristan Gingold <gingold@adacore.com>
* pe.h (struct pex64_runtime_function): Remove isChained field.
(struct pex64_unwind_info): Remove CountOfScopes, rawScopeEntries,
rva_TerminationHandler, rva_FrameHandler, FrameHandlerArgument,
rva_FunctionEntry fields. Add rva_BeginAddress, rva_EndAddress
and rva_UnwindData.
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c
index fdc6205..25547c0 100644
--- a/bfd/pei-x86_64.c
+++ b/bfd/pei-x86_64.c
@@ -90,8 +90,6 @@ pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
rf->rva_BeginAddress = bfd_get_32 (abfd, ex_rf->rva_BeginAddress);
rf->rva_EndAddress = bfd_get_32 (abfd, ex_rf->rva_EndAddress);
rf->rva_UnwindData = bfd_get_32 (abfd, ex_rf->rva_UnwindData);
- rf->isChained = PEX64_IS_RUNTIME_FUNCTION_CHAINED (rf);
- rf->rva_UnwindData = PEX64_GET_UNWINDDATA_UNIFIED_RVA (rf);
}
static void
@@ -115,7 +113,15 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
switch (ui->Flags)
{
case UNW_FLAG_CHAININFO:
- ui->rva_FunctionEntry = bfd_get_32 (abfd, ex_dta);
+ ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0);
+ ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4);
+ ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8);
+ ui->SizeOfBlock += 12;
+ return;
+ case UNW_FLAG_EHANDLER:
+ case UNW_FLAG_UHANDLER:
+ case UNW_FLAG_FHANDLER:
+ ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
ui->SizeOfBlock += 4;
return;
default:
@@ -303,6 +309,9 @@ pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
return section;
}
+/* Dump xdata at rva ADDR to FILE for ABFD, corresponding to function
+ beginning at PC_ADDR. */
+
static void
pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr,
bfd_vma *endx)
@@ -385,6 +394,27 @@ pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr,
pex64_xdata_print_uwd_codes (file, &ui, pc_addr);
+ 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)
@@ -507,7 +537,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
seen_error = 1;
fprintf (file, " has negative unwind address\n");
}
- if (rf.rva_UnwindData && !rf.isChained)
+ if (rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
}
@@ -552,10 +582,26 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
if (rf.rva_UnwindData != 0)
{
- if (rf.isChained)
+ if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
{
- fprintf (file, "\t shares information with pdata element at 0x");
- fprintf_vma (file, rf.rva_UnwindData);
+ bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
+ bfd_vma pdata_vma = bfd_get_section_vma (abfd, section);
+ struct pex64_runtime_function arf;
+
+ fprintf (file, "\t shares information with ");
+ altent += pe_data (abfd)->pe_opthdr.ImageBase;
+
+ if (altent >= pdata_vma
+ && (altent + PDATA_ROW_SIZE <= pdata_vma
+ + pei_section_data (abfd, section)->virt_size))
+ {
+ pex64_get_runtime_function
+ (abfd, &arf, &data[altent - pdata_vma]);
+ fprintf (file, "pdata element at 0x");
+ fprintf_vma (file, arf.rva_UnwindData);
+ }
+ else
+ fprintf (file, "unknown pdata element");
fprintf (file, ".\n");
}
else
diff --git a/include/coff/pe.h b/include/coff/pe.h
index 601a68e..70feaa9 100644
--- a/include/coff/pe.h
+++ b/include/coff/pe.h
@@ -368,7 +368,6 @@ struct pex64_runtime_function
bfd_vma rva_BeginAddress;
bfd_vma rva_EndAddress;
bfd_vma rva_UnwindData;
- unsigned int isChained : 1;
};
struct external_pex64_runtime_function
@@ -441,14 +440,10 @@ struct pex64_unwind_info
bfd_vma FrameOffset;
bfd_vma sizeofUnwindCodes;
bfd_byte *rawUnwindCodes;
- /* Valid for UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER. */
- bfd_vma CountOfScopes;
- bfd_byte *rawScopeEntries;
- bfd_vma rva_ExceptionHandler; /* UNW_EHANDLER. */
- bfd_vma rva_TerminationHandler; /* UNW_FLAG_UHANDLER. */
- bfd_vma rva_FrameHandler; /* UNW_FLAG_FHANDLER. */
- bfd_vma FrameHandlerArgument; /* UNW_FLAG_FHANDLER. */
- bfd_vma rva_FunctionEntry; /* UNW_FLAG_CHAININFO. */
+ bfd_vma rva_ExceptionHandler; /* UNW_EHANDLER or UNW_FLAG_UHANDLER. */
+ bfd_vma rva_BeginAddress; /* UNW_FLAG_CHAININFO. */
+ bfd_vma rva_EndAddress; /* UNW_FLAG_CHAININFO. */
+ bfd_vma rva_UnwindData; /* UNW_FLAG_CHAININFO. */
};
struct external_pex64_unwind_info