diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-09-29 00:12:26 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-09-29 00:24:06 +0200 |
commit | 5f8ca04fbb0682ff8647b4df5de68cd1042e312d (patch) | |
tree | 22fea238c8e5175e4040f1b38046b7686c053b8c /setupdwfl.cxx | |
parent | dc3f293b2581a31e78edad07cf41f7c10106ab4b (diff) | |
download | systemtap-steved-5f8ca04fbb0682ff8647b4df5de68cd1042e312d.tar.gz systemtap-steved-5f8ca04fbb0682ff8647b4df5de68cd1042e312d.tar.xz systemtap-steved-5f8ca04fbb0682ff8647b4df5de68cd1042e312d.zip |
Factor out duplicated code to setup user/module Dwfl from dwflpp/translate.
* setupdwfl.h: Add setup_dwfl_user() and is_user_module().
* setupdwfl.cxx: Likewise.
* dwflpp.cxx (setup_user): Use setup_dwfl_user().
* translate.cxx (emit_symbol_data): Likewise and is_user_module().
* tapsets.cxx (dwarf_cast_expanding_visitor::visit_cast_op):
Use is_user_module().
Diffstat (limited to 'setupdwfl.cxx')
-rw-r--r-- | setupdwfl.cxx | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/setupdwfl.cxx b/setupdwfl.cxx index 49667152..33d481ef 100644 --- a/setupdwfl.cxx +++ b/setupdwfl.cxx @@ -25,6 +25,12 @@ static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr); +// NB: kernel_build_tree doesn't enter into this, as it's for +// kernel-side modules only. +static const char *debuginfo_usr_path_arr = "+:.debug:/usr/lib/debug"; +static const char *debuginfo_usr_path = (debuginfo_env_arr + ?: debuginfo_usr_path_arr); + static const Dwfl_Callbacks kernel_callbacks = { dwfl_linux_kernel_find_elf, @@ -33,6 +39,15 @@ static const Dwfl_Callbacks kernel_callbacks = (char **) & debuginfo_path }; +static const Dwfl_Callbacks user_callbacks = + { + NULL, + dwfl_standard_find_debuginfo, + NULL, /* ET_REL not supported for user space, only ET_EXEC and ET_DYN. + dwfl_offline_section_address, */ + (char **) & debuginfo_usr_path + }; + using namespace std; // Setup in setup_dwfl_kernel(), for use in setup_dwfl_report_kernel_p(). @@ -191,3 +206,53 @@ setup_dwfl_kernel(const std::set<std::string> &names, offline_search_names = names; return setup_dwfl_kernel(found, s); } + +Dwfl* +setup_dwfl_user(const std::string &name) +{ + Dwfl *dwfl = dwfl_begin (&user_callbacks); + dwfl_assert("dwfl_begin", dwfl); + dwfl_report_begin (dwfl); + + // XXX: should support buildid-based naming + const char *cname = name.c_str(); + Dwfl_Module *mod = dwfl_report_offline (dwfl, cname, cname, -1); + dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL)); + if (! mod) + { + dwfl_end(dwfl); + dwfl = NULL; + } + return dwfl; +} + +Dwfl* +setup_dwfl_user(std::vector<std::string>::const_iterator &begin, + const std::vector<std::string>::const_iterator &end, + bool all_needed) +{ + Dwfl *dwfl = dwfl_begin (&user_callbacks); + dwfl_assert("dwfl_begin", dwfl); + dwfl_report_begin (dwfl); + + // XXX: should support buildid-based naming + while (begin != end && dwfl != NULL) + { + const char *cname = (*begin).c_str(); + Dwfl_Module *mod = dwfl_report_offline (dwfl, cname, cname, -1); + if (! mod && all_needed) + { + dwfl_end(dwfl); + dwfl = NULL; + } + begin++; + } + if (dwfl) + dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL)); + return dwfl; +} + +bool is_user_module(const std::string &m) +{ + return m[0] == '/' && m.rfind(".ko", m.length() - 1) != m.length() - 3; +} |