diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-07-16 23:32:12 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-07-16 23:32:12 +0200 |
commit | 88eaee9fc6d629529e47820525080f26775a9ba6 (patch) | |
tree | 01fdcff671d760463f83002edc3e93afe89ffa3f /dwflpp.cxx | |
parent | a6726c856737ff8451836939d56ca31311b54b6e (diff) | |
download | systemtap-steved-88eaee9fc6d629529e47820525080f26775a9ba6.tar.gz systemtap-steved-88eaee9fc6d629529e47820525080f26775a9ba6.tar.xz systemtap-steved-88eaee9fc6d629529e47820525080f26775a9ba6.zip |
PR10398 DW_OP_call_frame CFA support doesn't work for prelink shared libs.
* dwflpp.cxx (translate_location): Call get_cfa_ops with relative pc plus
module bias.
(literal_addr_to_sym_addr): Add verbose logging.
(get_cfa_ops): Adjust pc for returned bias. Add verbose logging.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r-- | dwflpp.cxx | 43 |
1 files changed, 40 insertions, 3 deletions
@@ -1500,7 +1500,9 @@ dwflpp::translate_location(struct obstack *pool, e->tok); } - Dwarf_Op *cfa_ops = get_cfa_ops (pc); + // get_cfa_ops works on the dw address space, pc is relative to current + // module, so add do need to add module_bias. + Dwarf_Op *cfa_ops = get_cfa_ops (pc + module_bias); return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, @@ -2475,6 +2477,9 @@ dwflpp::relocate_address(Dwarf_Addr dw_addr, Dwarf_Addr dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr) { + if (sess.verbose > 2) + clog << "literal_addr_to_sym_addr 0x" << hex << lit_addr << dec << endl; + // Assume the address came from the symbol list. // If we cannot get the symbol bias fall back on the dw bias. // The kernel (and other absolute executable modules) is special though. @@ -2485,12 +2490,20 @@ dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr) if (dwfl_module_getsymtab (module) != -1) dwfl_module_info (module, NULL, NULL, NULL, NULL, &symbias, NULL, NULL); + + if (sess.verbose > 3) + clog << "symbias 0x" << hex << symbias << dec + << ", dwbias 0x" << hex << module_bias << dec << endl; + if (symbias == (Dwarf_Addr) ~0) symbias = module_bias; lit_addr += symbias; } + if (sess.verbose > 2) + clog << "literal_addr_to_sym_addr ret 0x" << hex << lit_addr << dec << endl; + return lit_addr; } @@ -2508,11 +2521,18 @@ dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes) return num_cached_scopes; } +/* Returns the call frame address operations for the given program counter + * in the libdw address space. + */ Dwarf_Op * dwflpp::get_cfa_ops (Dwarf_Addr pc) { Dwarf_Op *cfa_ops = NULL; + if (sess.verbose > 2) + clog << "get_cfa_ops @0x" << hex << pc << dec + << ", module_start @0x" << hex << module_start << dec << endl; + #ifdef _ELFUTILS_PREREQ #if _ELFUTILS_PREREQ(0,142) // Try debug_frame first, then fall back on eh_frame. @@ -2520,23 +2540,40 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); if (cfi != NULL) { + if (sess.verbose > 3) + clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl; Dwarf_Frame *frame = NULL; - if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) + if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) dwarf_frame_cfa (frame, &cfa_ops); + else if (sess.verbose > 3) + clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; } + else if (sess.verbose > 3) + clog << "dwfl_module_dwarf_cfi failed: " << dwfl_errmsg(-1) << endl; + if (cfa_ops == NULL) { cfi = dwfl_module_eh_cfi (module, &bias); if (cfi != NULL) { + if (sess.verbose > 3) + clog << "got eh cfi bias: 0x" << hex << bias << dec << endl; Dwarf_Frame *frame = NULL; - if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) + if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) dwarf_frame_cfa (frame, &cfa_ops); + else if (sess.verbose > 3) + clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; } + else if (sess.verbose > 3) + clog << "dwfl_module_eh_cfi failed: " << dwfl_errmsg(-1) << endl; + } #endif #endif + if (sess.verbose > 2) + clog << (cfa_ops == NULL ? "not " : " ") << "found cfa" << endl; + return cfa_ops; } |