This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[RFC 12/13] translator: Hack to interpret mips64 FDEs as 32bit for unwind
- From: Crestez Dan Leonard <cdleonard at gmail dot com>
- To: systemtap at sourceware dot org
- Date: Thu, 31 Jul 2014 23:21:17 +0300
- Subject: [RFC 12/13] translator: Hack to interpret mips64 FDEs as 32bit for unwind
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1406837921 dot git dot cdleonard at gmail dot com>
- References: <cover dot 1406837921 dot git dot cdleonard at gmail dot com>
Signed-off-by: Crestez Dan Leonard <cdleonard@gmail.com>
---
translate.cxx | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/translate.cxx b/translate.cxx
index 158f76f..93917a5 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -5549,7 +5549,7 @@ static bool need_byte_swap_for_target (const unsigned char e_ident[])
#endif
}
-static void create_debug_frame_hdr (const unsigned char e_ident[],
+static void create_debug_frame_hdr (GElf_Ehdr *ehdr,
Elf_Data *debug_frame,
void **debug_frame_hdr,
size_t *debug_frame_hdr_len,
@@ -5567,11 +5567,20 @@ static void create_debug_frame_hdr (const unsigned char e_ident[],
// In the .debug_frame the FDE encoding is always DW_EH_PE_absptr.
// So there is no need to read the CIEs. And the size is either 4
// or 8, depending on the elf class from e_ident.
+ const unsigned char *e_ident = ehdr->e_ident;
int size = (e_ident[EI_CLASS] == ELFCLASS32) ? 4 : 8;
bool need_byte_swap = need_byte_swap_for_target (e_ident);
#define host_to_target_64(x) (need_byte_swap ? bswap_64((x)) : (x))
#define host_to_target_32(x) (need_byte_swap ? bswap_32((x)) : (x))
+ int fde_addr_size = size;
+ bool mips64_msym32 = false;
+ /* Should also check the CU address_size somehow. */
+ if (ehdr->e_machine == EM_MIPS && size == 8)
+ {
+ fde_addr_size = 4;
+ mips64_msym32 = true;
+ }
int res = 0;
Dwarf_Off off = 0;
Dwarf_CFI_Entry entry;
@@ -5588,10 +5597,16 @@ static void create_debug_frame_hdr (const unsigned char e_ident[],
else
{
Dwarf_Addr addr;
- if (size == 4)
+ if (fde_addr_size == 4)
addr = (*((uint32_t *) entry.fde.start));
else
addr = (*((uint64_t *) entry.fde.start));
+ if (mips64_msym32)
+ {
+ if (session.verbose > 1)
+ clog << "sign-extend FDE initial_address=" << hex << addr << endl;
+ addr = (int32_t)(host_to_target_32((uint32_t)addr));
+ }
fdes.insert(pair<Dwarf_Addr, Dwarf_Off>(addr, off));
}
}
@@ -5744,7 +5759,7 @@ static void get_unwind_data (Dwfl_Module *m,
}
if (*debug_frame != NULL && *debug_len > 0)
- create_debug_frame_hdr (ehdr->e_ident, data,
+ create_debug_frame_hdr (ehdr, data,
debug_frame_hdr, debug_frame_hdr_len,
debug_frame_off, session, m);
}