summaryrefslogtreecommitdiffstats
path: root/setupdwfl.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-09-29 00:12:26 +0200
committerMark Wielaard <mjw@redhat.com>2009-09-29 00:24:06 +0200
commit5f8ca04fbb0682ff8647b4df5de68cd1042e312d (patch)
tree22fea238c8e5175e4040f1b38046b7686c053b8c /setupdwfl.cxx
parentdc3f293b2581a31e78edad07cf41f7c10106ab4b (diff)
downloadsystemtap-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.cxx65
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;
+}