summaryrefslogtreecommitdiffstats
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
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().
-rw-r--r--dwflpp.cxx55
-rw-r--r--setupdwfl.cxx65
-rw-r--r--setupdwfl.h10
-rw-r--r--tapsets.cxx3
-rw-r--r--translate.cxx33
5 files changed, 92 insertions, 74 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index cc882e5d..b8e39b69 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -354,54 +354,17 @@ dwflpp::setup_user(const vector<string>& modules, bool debuginfo_needed)
if (! sess.module_cache)
sess.module_cache = new module_cache ();
- static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build";
- static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
- // NB: kernel_build_tree doesn't enter into this, as it's for
- // kernel-side modules only.
- static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr);
-
- static const Dwfl_Callbacks user_callbacks =
- {
- NULL, /* dwfl_linux_kernel_find_elf, */
- dwfl_standard_find_debuginfo,
- dwfl_offline_section_address,
- (char **) & debuginfo_path
- };
-
- dwfl = dwfl_begin (&user_callbacks);
- if (!dwfl)
- throw semantic_error ("cannot open dwfl");
- dwfl_report_begin (dwfl);
-
- vector<string>::const_iterator it;
- for (it = modules.begin(); it != modules.end(); ++it)
- {
- // XXX: should support buildid-based naming
-
- const string& module_name = *it;
- Dwfl_Module *mod = dwfl_report_offline (dwfl,
- module_name.c_str(),
- module_name.c_str(),
- -1);
-
- if (debuginfo_needed)
- dwfl_assert (string("missing process ") +
- module_name +
- string(" ") +
- sess.architecture +
- string(" debuginfo"),
- mod);
- }
-
- // NB: the result of an _offline call is the assignment of
- // virtualized addresses to relocatable objects such as
- // modules. These have to be converted to real addresses at
- // run time. See the dwarf_derived_probe ctor and its caller.
-
- dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
+ vector<string>::const_iterator it = modules.begin();
+ dwfl = setup_dwfl_user(it, modules.end(), debuginfo_needed);
+ if (debuginfo_needed && it != modules.end())
+ dwfl_assert (string("missing process ") +
+ *it +
+ string(" ") +
+ sess.architecture +
+ string(" debuginfo"),
+ dwfl);
}
-
void
dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
const char *, Dwarf_Addr,
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;
+}
diff --git a/setupdwfl.h b/setupdwfl.h
index 7884e4da..67a66397 100644
--- a/setupdwfl.h
+++ b/setupdwfl.h
@@ -14,6 +14,7 @@
#include <set>
#include <string>
+#include <vector>
extern "C" {
#include <elfutils/libdwfl.h>
@@ -25,4 +26,13 @@ Dwfl *setup_dwfl_kernel(const std::string &name,
Dwfl *setup_dwfl_kernel(const std::set<std::string> &names,
unsigned *found,
systemtap_session &s);
+
+Dwfl* setup_dwfl_user(const std::string &name);
+Dwfl* setup_dwfl_user(std::vector<std::string>::const_iterator &begin,
+ const std::vector<std::string>::const_iterator &end,
+ bool all_needed);
+
+// user-space files must be full paths and not end in .ko
+bool is_user_module(const std::string &m);
+
#endif
diff --git a/tapsets.cxx b/tapsets.cxx
index 4a8432f7..bedb267a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -21,6 +21,7 @@
#include "auto_free.h"
#include "hash.h"
#include "dwflpp.h"
+#include "setupdwfl.h"
#include <cstdlib>
#include <algorithm>
@@ -2606,7 +2607,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
dwflpp* dw;
try
{
- if (module.find('/') == string::npos)
+ if (! is_user_module (module))
{
// kernel or kernel module target
dw = db.get_kern_dw(s, module);
diff --git a/translate.cxx b/translate.cxx
index 1bb6252f..0f53dc78 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4957,8 +4957,9 @@ emit_symbol_data (systemtap_session& s)
it++)
{
string foo = *it;
- if (foo[0] != '/') /* Omit user-space, since we're only using this for
- kernel space offline searches. */
+ if (! is_user_module (foo)) /* Omit user-space, since we're only
+ using this for kernel space
+ offline searches. */
offline_search_modules.insert (foo);
}
Dwfl *dwfl = setup_dwfl_kernel (offline_search_modules, &count, s);
@@ -4978,37 +4979,15 @@ emit_symbol_data (systemtap_session& s)
// ---- step 2: process any user modules (files) listed
- // XXX: see dwflpp::setup_user.
-
- // XXX: copied from tapsets.cxx dwflpp::, sadly
- 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);
-
- static const Dwfl_Callbacks user_callbacks =
- {
- NULL, /* dwfl_linux_kernel_find_elf, */
- dwfl_standard_find_debuginfo,
- NULL, /* ET_REL not supported for user space, only ET_EXEC and ET_DYN.
- dwfl_offline_section_address, */
- (char **) & debuginfo_path
- };
-
for (std::set<std::string>::iterator it = s.unwindsym_modules.begin();
it != s.unwindsym_modules.end();
it++)
{
string modname = *it;
assert (modname.length() != 0);
- if (modname[0] != '/') continue; // user-space files must be full paths
- Dwfl *dwfl = dwfl_begin (&user_callbacks);
- if (!dwfl)
- throw semantic_error ("cannot create dwfl for " + modname);
-
- dwfl_report_begin (dwfl);
- Dwfl_Module* mod = dwfl_report_offline (dwfl, modname.c_str(), modname.c_str(), -1);
- dwfl_report_end (dwfl, NULL, NULL);
- if (mod != 0) // tolerate missing data; will warn below
+ if (! is_user_module (modname)) continue;
+ Dwfl *dwfl = setup_dwfl_user (modname);
+ if (dwfl != NULL) // tolerate missing data; will warn below
{
ptrdiff_t off = 0;
do