summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-09-28 15:36:33 +0200
committerMark Wielaard <mjw@redhat.com>2009-09-28 15:36:33 +0200
commit3db9c8433e58812c9ce47df384e23841aca27894 (patch)
tree5af4c562d8bd9775075dcb6bf6ff3b4feb07f355 /dwflpp.cxx
parentd498530cec1fcf4b71b1b27a068206fda18f3188 (diff)
downloadsystemtap-steved-3db9c8433e58812c9ce47df384e23841aca27894.tar.gz
systemtap-steved-3db9c8433e58812c9ce47df384e23841aca27894.tar.xz
systemtap-steved-3db9c8433e58812c9ce47df384e23841aca27894.zip
Factor out duplicated code to setup kernel/module Dwfl from dwflpp/translate.
* setupdwfl.h: New header file. * setupdwfl.cxx: New source file containing shared setup_dwfl_kernel() code. * dwflpp.cxx (dwfl_report_offline_predicate): Removed. (setup_kernel): Call setup_dwfl_kernel(). * translate.cxx (dwfl_report_offline_predicate2): Remove. (emit_symbol_data): Call setup_dwfl_kernel(). * Makefile.am (stap_SOURCES): Add setupdwfl.cxx. * Makefile.in: Regenerated.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r--dwflpp.cxx97
1 files changed, 4 insertions, 93 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 636cd38d..4ef9f76b 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -22,6 +22,7 @@
#include "auto_free.h"
#include "hash.h"
#include "rpm_finder.h"
+#include "setupdwfl.h"
#include <cstdlib>
#include <algorithm>
@@ -293,99 +294,16 @@ dwflpp::function_scope_matches(const vector<string> scopes)
}
-static const char *offline_search_modname = NULL;
-static int offline_search_match_p = 0;
-
-static int dwfl_report_offline_predicate (const char* modname, const char* filename)
-{
- if (pending_interrupts)
- return -1;
-
- assert (offline_search_modname);
-
- // elfutils sends us NULL filenames sometimes if it can't find dwarf
- if (filename == NULL)
- return 0;
-
- if (dwflpp::name_has_wildcard (offline_search_modname)) {
- int match_p = !fnmatch(offline_search_modname, modname, 0);
- // In the wildcard case, we don't short-circuit (return -1) upon
- // offline_search_match_p, analogously to dwflpp::module_name_final_match().
-
- if (match_p)
- offline_search_match_p ++;
-
- return match_p;
- } else { /* non-wildcard mode */
- if (offline_search_match_p)
- return -1;
-
- /* Reject mismatching module names */
- if (strcmp(modname, offline_search_modname))
- return 0;
- else
- {
- offline_search_match_p ++;
- return 1;
- }
- }
-}
-
-
void
dwflpp::setup_kernel(const string& name, bool debuginfo_needed)
{
- // XXX: See also translate.cxx:emit_symbol_data
-
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");
- static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr );
+ unsigned offline_search_matches = 0;
+ dwfl = setup_dwfl_kernel(name, &offline_search_matches, sess);
- static const Dwfl_Callbacks kernel_callbacks =
- {
- dwfl_linux_kernel_find_elf,
- dwfl_standard_find_debuginfo,
- dwfl_offline_section_address,
- (char **) & debuginfo_path
- };
-
- dwfl = dwfl_begin (&kernel_callbacks);
- if (!dwfl)
- throw semantic_error ("cannot open dwfl");
- dwfl_report_begin (dwfl);
-
- // We have a problem with -r REVISION vs -r BUILDDIR here. If
- // we're running against a fedora/rhel style kernel-debuginfo
- // tree, s.kernel_build_tree is not the place where the unstripped
- // vmlinux will be installed. Rather, it's over yonder at
- // /usr/lib/debug/lib/modules/$REVISION/. It seems that there is
- // no way to set the dwfl_callback.debuginfo_path and always
- // passs the plain kernel_release here. So instead we have to
- // hard-code this magic here.
- string elfutils_kernel_path;
- if (sess.kernel_build_tree == string("/lib/modules/" + sess.kernel_release + "/build"))
- elfutils_kernel_path = sess.kernel_release;
- else
- elfutils_kernel_path = sess.kernel_build_tree;
-
- offline_search_modname = name.c_str();
- offline_search_match_p = 0;
- int rc = dwfl_linux_kernel_report_offline (dwfl,
- elfutils_kernel_path.c_str(),
- &dwfl_report_offline_predicate);
- offline_search_modname = NULL;
-
- (void) rc; /* Ignore since the predicate probably returned -1 at some point,
- And libdwfl interprets that as "whole query failed" rather than
- "found it already, stop looking". */
-
- /* But we still need to check whether the module was itself found. One could
- do an iterate_modules() search over the resulting dwfl and count hits. Or
- one could rely on the match_p flag being set just before. */
- if (! offline_search_match_p)
+ if (offline_search_matches < 1)
{
if (debuginfo_needed) {
// Suggest a likely kernel dir to find debuginfo rpm for
@@ -397,13 +315,6 @@ dwflpp::setup_kernel(const string& name, bool debuginfo_needed)
sess.kernel_build_tree + string("'"));
}
- // 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));
-
build_blacklist();
}