summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Cohen <wcohen@redhat.com>2009-06-24 09:37:51 -0400
committerWilliam Cohen <wcohen@redhat.com>2009-06-24 09:37:51 -0400
commit9cb00f47af5b4feb20df8d747ba9ecc683c26aa6 (patch)
treef4d834770a06e0e5d887cb8a409f0c774d3e193d
parent174eae80fcdcdc6bfd002e82d919259fe46b1149 (diff)
parentf77540fe71e8237942fe28cc3c2ffd5ad9f10a8d (diff)
downloadsystemtap-steved-9cb00f47af5b4feb20df8d747ba9ecc683c26aa6.tar.gz
systemtap-steved-9cb00f47af5b4feb20df8d747ba9ecc683c26aa6.tar.xz
systemtap-steved-9cb00f47af5b4feb20df8d747ba9ecc683c26aa6.zip
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
-rw-r--r--dwflpp.cxx63
-rw-r--r--dwflpp.h14
-rw-r--r--loc2c-test.c4
-rw-r--r--tapsets.cxx16
-rw-r--r--testsuite/systemtap.exelib/exelib.exp4
-rw-r--r--testsuite/systemtap.exelib/ustack.tcl3
6 files changed, 75 insertions, 29 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 5991d1a1..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;
@@ -193,7 +193,7 @@ dwflpp::query_cu_containing_address(Dwarf_Addr a)
bool
-dwflpp::module_name_matches(string pattern)
+dwflpp::module_name_matches(const string& pattern)
{
bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
if (t && sess.verbose>3)
@@ -205,7 +205,7 @@ dwflpp::module_name_matches(string pattern)
bool
-dwflpp::name_has_wildcard(string pattern)
+dwflpp::name_has_wildcard(const string& pattern)
{
return (pattern.find('*') != string::npos ||
pattern.find('?') != string::npos ||
@@ -214,7 +214,7 @@ dwflpp::name_has_wildcard(string pattern)
bool
-dwflpp::module_name_final_match(string pattern)
+dwflpp::module_name_final_match(const string& pattern)
{
// Assume module_name_matches(). Can there be any more matches?
// Not unless the pattern is a wildcard, since module names are
@@ -224,7 +224,7 @@ dwflpp::module_name_final_match(string pattern)
bool
-dwflpp::function_name_matches_pattern(string name, string pattern)
+dwflpp::function_name_matches_pattern(const string& name, const string& pattern)
{
bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0);
if (t && sess.verbose>3)
@@ -236,7 +236,7 @@ dwflpp::function_name_matches_pattern(string name, string pattern)
bool
-dwflpp::function_name_matches(string pattern)
+dwflpp::function_name_matches(const string& pattern)
{
assert(function);
return function_name_matches_pattern(function_name, pattern);
@@ -244,7 +244,7 @@ dwflpp::function_name_matches(string pattern)
bool
-dwflpp::function_name_final_match(string pattern)
+dwflpp::function_name_final_match(const string& pattern)
{
return module_name_final_match (pattern);
}
@@ -565,26 +565,26 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
clog << "function cache " << key << " size " << v->size() << endl;
}
- string subkey = function;
- if (v->find(subkey) != v->end())
+ cu_function_cache_t::iterator it = v->find(function);
+ if (it != v->end())
{
- Dwarf_Die die = v->find(subkey)->second;
+ Dwarf_Die die = it->second;
if (sess.verbose > 4)
- clog << "function cache " << key << " hit " << subkey << endl;
+ clog << "function cache " << key << " hit " << function << endl;
return (*callback)(& die, q);
}
- else if (name_has_wildcard (subkey))
+ else if (name_has_wildcard (function))
{
- for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++)
+ for (it = v->begin(); it != v->end(); it++)
{
if (pending_interrupts) return DWARF_CB_ABORT;
string func_name = it->first;
Dwarf_Die die = it->second;
- if (function_name_matches_pattern (func_name, subkey))
+ if (function_name_matches_pattern (func_name, function))
{
if (sess.verbose > 4)
clog << "function cache " << key << " match " << func_name << " vs "
- << subkey << endl;
+ << function << endl;
rc = (*callback)(& die, q);
if (rc != DWARF_CB_OK) break;
@@ -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 ec2fc2b9..8b503b33 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -198,13 +198,13 @@ struct dwflpp
Dwarf_Die *query_cu_containing_address(Dwarf_Addr a);
- bool module_name_matches(std::string pattern);
- bool name_has_wildcard(std::string pattern);
- bool module_name_final_match(std::string pattern);
+ bool module_name_matches(const std::string& pattern);
+ bool name_has_wildcard(const std::string& pattern);
+ bool module_name_final_match(const std::string& pattern);
- bool function_name_matches_pattern(std::string name, std::string pattern);
- bool function_name_matches(std::string pattern);
- bool function_name_final_match(std::string pattern);
+ bool function_name_matches_pattern(const std::string& name, const std::string& pattern);
+ bool function_name_matches(const std::string& pattern);
+ bool function_name_final_match(const std::string& pattern);
void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
const char *, Dwarf_Addr,
@@ -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/loc2c-test.c b/loc2c-test.c
index a584c024..01edc805 100644
--- a/loc2c-test.c
+++ b/loc2c-test.c
@@ -255,7 +255,9 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out,
if (typedie == NULL)
error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
typetag = dwarf_tag (typedie);
- if (typetag != DW_TAG_typedef)
+ if (typetag != DW_TAG_typedef &&
+ typetag != DW_TAG_const_type &&
+ typetag != DW_TAG_volatile_type)
break;
if (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem) == NULL)
error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
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;
diff --git a/testsuite/systemtap.exelib/exelib.exp b/testsuite/systemtap.exelib/exelib.exp
index 960ebbfa..51025d56 100644
--- a/testsuite/systemtap.exelib/exelib.exp
+++ b/testsuite/systemtap.exelib/exelib.exp
@@ -31,7 +31,7 @@ set testsrclib "$testpath/uprobes_lib.c"
set testlibdir "."
set arches [list "default"]
-# BUG! non-default arch breaks ustack tests.
+# BUG! non-default arch breaks mark and ustack tests PR10318 and PR10272
#switch -regexp $::tcl_platform(machine) {
# {^(x86_64|ppc64)$} { lappend arches "-m32" }
# {^s390x$} { lappend arches "-m31" }
@@ -45,7 +45,7 @@ foreach arch $arches {
# Adding -O, -O2, -Os and mixing lib/exe is a bit overdone
foreach opt {-O0 -O3} {
- foreach libprelink {no} { # BUG! "yes" breaks uname tests
+ foreach libprelink {no yes} { # BUG! "yes" breaks ustack PR10323
# not done yet, "no" lib debug.
foreach libdebug {yes sep} {
diff --git a/testsuite/systemtap.exelib/ustack.tcl b/testsuite/systemtap.exelib/ustack.tcl
index b70b8334..07dcec10 100644
--- a/testsuite/systemtap.exelib/ustack.tcl
+++ b/testsuite/systemtap.exelib/ustack.tcl
@@ -7,6 +7,9 @@ lib: lib_func=lib_func
lib: lib_func=lib_func
lib: lib_func=lib_func}
+# BUG XXX PR10323 skip all prelink scenarios for now.
+if {[string match "*prelink*" "$testname"]} { return }
+
# Only run on make installcheck
if {! [installtest_p]} { untested "ustack-$testname"; return }
if {! [utrace_p]} { untested "ustack-$testname"; return }