diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-06-24 14:20:08 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-06-24 14:20:08 +0200 |
commit | 1f8592d1a615bef5bad1f255e761664e85d9e4f0 (patch) | |
tree | 05c01cbab8c8834bc356d3db70b8eeed904c2c9f /dwflpp.cxx | |
parent | 123ed3dad4423edf313f3218b3d63804b7edfc47 (diff) | |
download | systemtap-steved-1f8592d1a615bef5bad1f255e761664e85d9e4f0.tar.gz systemtap-steved-1f8592d1a615bef5bad1f255e761664e85d9e4f0.tar.xz systemtap-steved-1f8592d1a615bef5bad1f255e761664e85d9e4f0.zip |
PR10305 Mark probes fail on prelinked shared library.
Mark probes rely on literal statement addresses, these are based on the
on-disk module address space. Introduce helper function to turn such
addresses into symbol addresses as expected by libdwfl. Also properly
adjust for dw bias when such addresses are used in dw queries.
* dwflpp.h (dwflpp::literal_addr_to_sym_addr): New method.
* dwflpp.cxx (query_cu_containing_address): Don't "globalize" address.
(literal_addr_to_sym_addr): New method.
* tapsets.cxx (query_module_dwarf): Turn literal addresses into symbol
addresses.
(query_dwarf_func): Likewise and adjust for dw module bias.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r-- | dwflpp.cxx | 35 |
1 files changed, 31 insertions, 4 deletions
@@ -174,6 +174,10 @@ dwflpp::focus_on_function(Dwarf_Die * f) } +/* Return the Dwarf_Die for the given address in the current module. + * The address should be in the module address address space (this + * function will take care of any dw bias). + */ Dwarf_Die * dwflpp::query_cu_containing_address(Dwarf_Addr a) { @@ -182,10 +186,6 @@ dwflpp::query_cu_containing_address(Dwarf_Addr a) assert(module); get_module_dwarf(); - // globalize the module-relative address - if (module_name != TOK_KERNEL && dwfl_module_relocations (module) > 0) - a += module_start; - Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias); assert(bias == module_bias); return cudie; @@ -2378,6 +2378,33 @@ dwflpp::relocate_address(Dwarf_Addr dw_addr, return reloc_addr; } +/* Converts a "global" literal address to the module symbol address + * space. If necessary (not for kernel and executables using absolute + * addresses), this adjust the address for the current module symbol + * bias. Literal addresses are provided by the user (or contained on + * the .probes section) based on the "on disk" layout of the module. + */ +Dwarf_Addr +dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr) +{ + // 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. + if (module_name != TOK_KERNEL + && dwfl_module_relocations (module) > 0) + { + Dwarf_Addr symbias = ~0; + if (dwfl_module_getsymtab (module) != -1) + dwfl_module_info (module, NULL, NULL, NULL, NULL, + &symbias, NULL, NULL); + if (symbias == (Dwarf_Addr) ~0) + symbias = module_bias; + + lit_addr += symbias; + } + + return lit_addr; +} int dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes) |