summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-06-24 14:20:08 +0200
committerMark Wielaard <mjw@redhat.com>2009-06-24 14:20:08 +0200
commit1f8592d1a615bef5bad1f255e761664e85d9e4f0 (patch)
tree05c01cbab8c8834bc356d3db70b8eeed904c2c9f
parent123ed3dad4423edf313f3218b3d63804b7edfc47 (diff)
downloadsystemtap-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.
-rw-r--r--dwflpp.cxx35
-rw-r--r--dwflpp.h2
-rw-r--r--tapsets.cxx16
3 files changed, 47 insertions, 6 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 2d1e2f54..ee5d2233 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -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)
diff --git a/dwflpp.h b/dwflpp.h
index b31efdf8..8b503b33 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -291,6 +291,8 @@ struct dwflpp
std::string& reloc_section,
std::string& blacklist_section);
+ Dwarf_Addr literal_addr_to_sym_addr(Dwarf_Addr lit_addr);
+
private:
Dwfl * dwfl;
diff --git a/tapsets.cxx b/tapsets.cxx
index 6be7de11..cd6bc28e 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -986,8 +986,9 @@ dwarf_query::query_module_dwarf()
else
addr = statement_num_val;
- // NB: we don't need to add the module base address or bias
- // value here (for reasons that may be coincidental).
+ // Translate to an actual symbol address.
+ addr = dw.literal_addr_to_sym_addr (addr);
+
Dwarf_Die* cudie = dw.query_cu_containing_address(addr);
if (cudie) // address could be wildly out of range
query_cu(cudie, this);
@@ -1546,6 +1547,11 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq)
Dwarf_Die d;
q->dw.function_die (&d);
+ // Translate literal address to symbol address, then
+ // compensate for dw bias.
+ query_addr = q->dw.literal_addr_to_sym_addr(query_addr);
+ query_addr -= q->dw.module_bias;
+
if (q->dw.die_has_pc (d, query_addr))
record_this_function = true;
}
@@ -1576,6 +1582,12 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq)
else if (q->has_statement_num)
{
func.entrypc = q->statement_num_val;
+
+ // Translate literal address to symbol address, then
+ // compensate for dw bias (will be used for query dw funcs).
+ func.entrypc = q->dw.literal_addr_to_sym_addr(func.entrypc);
+ func.entrypc -= q->dw.module_bias;
+
q->filtered_functions.push_back (func);
if (q->dw.function_name_final_match (q->function))
return DWARF_CB_ABORT;