This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
[PATCH] readelf: Adjust initial FDE address if pcrel before printing.
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Fri, 21 Dec 2012 22:18:07 +0100
- Subject: [PATCH] readelf: Adjust initial FDE address if pcrel before printing.
The FDE initial_location is printed as start address with format_dwarf_addr.
Which does the right thing for .debug_frame addresses, but in .eh_frame
this is encoded as DW_EH_PE_pcrel and so needs to be adjusted before
formatting.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 16 +++++++++++++++-
2 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 547605d..7aadcf4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,10 @@
2012-12-21 Mark Wielaard <mjw@redhat.com>
+ * readelf.c (print_debug_frame_section): Adjust FDE start address
+ if pcrel before feeding it to format_dwarf_addr.
+
+2012-12-21 Mark Wielaard <mjw@redhat.com>
+
* addr2line (main): Call dwfl_end.
2012-12-11 Roland McGrath <roland@hack.frob.com>
diff --git a/src/readelf.c b/src/readelf.c
index 7f6f31c..434ec68 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4710,6 +4710,10 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
(void) elf_getshdrstrndx (ebl->elf, &shstrndx);
const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+ /* Needed if we find pc relative addresses. */
+ GElf_Addr bias;
+ dwfl_module_getelf (dwflmod, &bias);
+
Elf_Data *data = elf_rawdata (scn, NULL);
if (unlikely (data == NULL))
@@ -4956,8 +4960,18 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
Dwarf_Word address_range
= read_ubyte_unaligned_inc (ptr_size, dbg, readp);
+ /* pcrel for an FDE address really means data relative. */
+ Dwarf_Addr pc_start = initial_location;
+ if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
+ pc_start += ((uint64_t) shdr->sh_addr
+ + (base - (const unsigned char *) data->d_buf))
+ - bias;
+ pc_start &= (ptr_size == 4
+ ? UINT64_C (0xffffffff)
+ : UINT64_C (0xffffffffffffffff));
+
char *a = format_dwarf_addr (dwflmod, cie->address_size,
- initial_location);
+ pc_start);
printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
" CIE_pointer: %" PRIu64 "\n"
" initial_location: %s",
--
1.7.1