diff options
author | William Cohen <wcohen@redhat.com> | 2009-06-24 09:37:51 -0400 |
---|---|---|
committer | William Cohen <wcohen@redhat.com> | 2009-06-24 09:37:51 -0400 |
commit | 9cb00f47af5b4feb20df8d747ba9ecc683c26aa6 (patch) | |
tree | f4d834770a06e0e5d887cb8a409f0c774d3e193d | |
parent | 174eae80fcdcdc6bfd002e82d919259fe46b1149 (diff) | |
parent | f77540fe71e8237942fe28cc3c2ffd5ad9f10a8d (diff) | |
download | systemtap-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.cxx | 63 | ||||
-rw-r--r-- | dwflpp.h | 14 | ||||
-rw-r--r-- | loc2c-test.c | 4 | ||||
-rw-r--r-- | tapsets.cxx | 16 | ||||
-rw-r--r-- | testsuite/systemtap.exelib/exelib.exp | 4 | ||||
-rw-r--r-- | testsuite/systemtap.exelib/ustack.tcl | 3 |
6 files changed, 75 insertions, 29 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; @@ -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) @@ -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 } |