summaryrefslogtreecommitdiffstats
path: root/setupdwfl.cxx
diff options
context:
space:
mode:
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;
+}