diff options
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r-- | dwflpp.cxx | 39 |
1 files changed, 37 insertions, 2 deletions
@@ -41,6 +41,9 @@ extern "C" { #include <fcntl.h> #include <elfutils/libdwfl.h> #include <elfutils/libdw.h> +#ifdef HAVE_ELFUTILS_VERSION_H +#include <elfutils/version.h> +#endif #include <dwarf.h> #include <elf.h> #include <obstack.h> @@ -1497,10 +1500,11 @@ dwflpp::translate_location(struct obstack *pool, e->tok); } + Dwarf_Op *cfa_ops = get_cfa_ops (pc); return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, - pc, expr, len, tail, fb_attr); + pc, expr, len, tail, fb_attr, cfa_ops); } @@ -2085,7 +2089,7 @@ dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die, &loc2c_emit_address, 1, 0 /* PR9768 */, pc, locops, nlocops, - &tail, NULL); + &tail, NULL, NULL); /* Translate the ->bar->baz[NN] parts. */ @@ -2489,5 +2493,36 @@ dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes) return num_cached_scopes; } +Dwarf_Op * +dwflpp::get_cfa_ops (Dwarf_Addr pc) +{ + Dwarf_Op *cfa_ops = NULL; + +#ifdef _ELFUTILS_PREREQ +#if _ELFUTILS_PREREQ(0,142) + // Try debug_frame first, then fall back on eh_frame. + Dwarf_Addr bias; + Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); + if (cfi != NULL) + { + Dwarf_Frame *frame = NULL; + if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) + dwarf_frame_cfa (frame, &cfa_ops); + } + if (cfa_ops == NULL) + { + cfi = dwfl_module_eh_cfi (module, &bias); + if (cfi != NULL) + { + Dwarf_Frame *frame = NULL; + if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) + dwarf_frame_cfa (frame, &cfa_ops); + } + } +#endif +#endif + + return cfa_ops; +} /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ |