summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwflpp.cxx313
-rw-r--r--dwflpp.h26
-rw-r--r--tapsets.cxx324
3 files changed, 341 insertions, 322 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index f3429118..3af26053 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -66,7 +66,8 @@ static string TOK_KERNEL("kernel");
dwflpp::dwflpp(systemtap_session & session, const string& user_module):
sess(session), module(NULL), module_bias(0), mod_info(NULL),
module_start(0), module_end(0), cu(NULL), dwfl(NULL),
- module_dwarf(NULL), function(NULL)
+ module_dwarf(NULL), function(NULL), blacklist_enabled(false),
+ pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL)
{
if (user_module.empty())
setup_kernel();
@@ -77,6 +78,7 @@ dwflpp::dwflpp(systemtap_session & session, const string& user_module):
dwflpp::~dwflpp()
{
+ free(cached_scopes);
if (dwfl)
dwfl_end(dwfl);
}
@@ -165,6 +167,9 @@ dwflpp::focus_on_cu(Dwarf_Die * c)
// Reset existing pointers and names
function_name.clear();
function = NULL;
+
+ free(cached_scopes);
+ cached_scopes = NULL;
}
@@ -328,6 +333,8 @@ dwflpp::setup_kernel(bool debuginfo_needed)
// run time. See the dwarf_derived_probe ctor and its caller.
dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
+
+ build_blacklist();
}
@@ -1345,7 +1352,7 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die,
assert (cu);
- nscopes = dwarf_getscopes (cu, pc, &scopes);
+ nscopes = dwarf_getscopes_cached (pc, &scopes);
int sidx;
// if pc and scope_die are disjoint then we need dwarf_getscopes_die
for (sidx = 0; sidx < nscopes; sidx++)
@@ -2100,4 +2107,306 @@ dwflpp::literal_stmt_for_pointer (Dwarf_Die *type_die,
}
+static bool
+in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
+{
+ if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
+ {
+ // If the probe point address is anywhere in the __kprobes
+ // address range, we can't use this probe point.
+ if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
+ return true;
+ }
+ return false;
+}
+
+
+bool
+dwflpp::blacklisted_p(const string& funcname,
+ const string& filename,
+ int,
+ const string& module,
+ const string& section,
+ Dwarf_Addr addr,
+ bool has_return)
+{
+ if (!blacklist_enabled)
+ return false; // no blacklist for userspace
+
+ if (section.substr(0, 6) == string(".init.") ||
+ section.substr(0, 6) == string(".exit.") ||
+ section.substr(0, 9) == string(".devinit.") ||
+ section.substr(0, 9) == string(".devexit.") ||
+ section.substr(0, 9) == string(".cpuinit.") ||
+ section.substr(0, 9) == string(".cpuexit.") ||
+ section.substr(0, 9) == string(".meminit.") ||
+ section.substr(0, 9) == string(".memexit."))
+ {
+ // NB: module .exit. routines could be probed in theory:
+ // if the exit handler in "struct module" is diverted,
+ // first inserting the kprobes
+ // then allowing the exit code to run
+ // then removing these kprobes
+ if (sess.verbose>1)
+ clog << " skipping - init/exit";
+ return true;
+ }
+
+ // Check for function marked '__kprobes'.
+ if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
+ {
+ if (sess.verbose>1)
+ clog << " skipping - __kprobes";
+ return true;
+ }
+
+ // Check probe point against blacklist.
+ int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
+ if (has_return)
+ goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
+ int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
+
+ if (! (goodfn && goodfile))
+ {
+ if (sess.guru_mode)
+ {
+ if (sess.verbose>1)
+ clog << " guru mode enabled - ignoring blacklist";
+ }
+ else
+ {
+ if (sess.verbose>1)
+ clog << " skipping - blacklisted";
+ return true;
+ }
+ }
+
+ // This probe point is not blacklisted.
+ return false;
+}
+
+
+void
+dwflpp::build_blacklist()
+{
+ // We build up the regexps in these strings
+
+ // Add ^ anchors at the front; $ will be added just before regcomp.
+
+ string blfn = "^(";
+ string blfn_ret = "^(";
+ string blfile = "^(";
+
+ blfile += "kernel/kprobes.c"; // first alternative, no "|"
+ blfile += "|arch/.*/kernel/kprobes.c";
+ // Older kernels need ...
+ blfile += "|include/asm/io.h";
+ blfile += "|include/asm/bitops.h";
+ // While newer ones need ...
+ blfile += "|arch/.*/include/asm/io.h";
+ blfile += "|arch/.*/include/asm/bitops.h";
+ blfile += "|drivers/ide/ide-iops.c";
+
+ // XXX: it would be nice if these blacklisted functions were pulled
+ // in dynamically, instead of being statically defined here.
+ // Perhaps it could be populated from script files. A "noprobe
+ // kernel.function("...")" construct might do the trick.
+
+ // Most of these are marked __kprobes in newer kernels. We list
+ // them here (anyway) so the translator can block them on older
+ // kernels that don't have the __kprobes function decorator. This
+ // also allows detection of problems at translate- rather than
+ // run-time.
+
+ blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
+ blfn += "|default_do_nmi";
+ blfn += "|__die";
+ blfn += "|die_nmi";
+ blfn += "|do_debug";
+ blfn += "|do_general_protection";
+ blfn += "|do_int3";
+ blfn += "|do_IRQ";
+ blfn += "|do_page_fault";
+ blfn += "|do_sparc64_fault";
+ blfn += "|do_trap";
+ blfn += "|dummy_nmi_callback";
+ blfn += "|flush_icache_range";
+ blfn += "|ia64_bad_break";
+ blfn += "|ia64_do_page_fault";
+ blfn += "|ia64_fault";
+ blfn += "|io_check_error";
+ blfn += "|mem_parity_error";
+ blfn += "|nmi_watchdog_tick";
+ blfn += "|notifier_call_chain";
+ blfn += "|oops_begin";
+ blfn += "|oops_end";
+ blfn += "|program_check_exception";
+ blfn += "|single_step_exception";
+ blfn += "|sync_regs";
+ blfn += "|unhandled_fault";
+ blfn += "|unknown_nmi_error";
+
+ // Lots of locks
+ blfn += "|.*raw_.*lock.*";
+ blfn += "|.*read_.*lock.*";
+ blfn += "|.*write_.*lock.*";
+ blfn += "|.*spin_.*lock.*";
+ blfn += "|.*rwlock_.*lock.*";
+ blfn += "|.*rwsem_.*lock.*";
+ blfn += "|.*mutex_.*lock.*";
+ blfn += "|raw_.*";
+ blfn += "|.*seq_.*lock.*";
+
+ // atomic functions
+ blfn += "|atomic_.*";
+ blfn += "|atomic64_.*";
+
+ // few other problematic cases
+ blfn += "|get_bh";
+ blfn += "|put_bh";
+
+ // Experimental
+ blfn += "|.*apic.*|.*APIC.*";
+ blfn += "|.*softirq.*";
+ blfn += "|.*IRQ.*";
+ blfn += "|.*_intr.*";
+ blfn += "|__delay";
+ blfn += "|.*kernel_text.*";
+ blfn += "|get_current";
+ blfn += "|current_.*";
+ blfn += "|.*exception_tables.*";
+ blfn += "|.*setup_rt_frame.*";
+
+ // PR 5759, CONFIG_PREEMPT kernels
+ blfn += "|.*preempt_count.*";
+ blfn += "|preempt_schedule";
+
+ // These functions don't return, so return probes would never be recovered
+ blfn_ret += "do_exit"; // no "|"
+ blfn_ret += "|sys_exit";
+ blfn_ret += "|sys_exit_group";
+
+ // __switch_to changes "current" on x86_64 and i686, so return probes
+ // would cause kernel panic, and it is marked as "__kprobes" on x86_64
+ if (sess.architecture == "x86_64")
+ blfn += "|__switch_to";
+ if (sess.architecture == "i686")
+ blfn_ret += "|__switch_to";
+
+ blfn += ")$";
+ blfn_ret += ")$";
+ blfile += ")$";
+
+ if (sess.verbose > 2)
+ {
+ clog << "blacklist regexps:" << endl;
+ clog << "blfn: " << blfn << endl;
+ clog << "blfn_ret: " << blfn_ret << endl;
+ clog << "blfile: " << blfile << endl;
+ }
+
+ int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
+ if (rc) throw semantic_error ("blacklist_func regcomp failed");
+ rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
+ if (rc) throw semantic_error ("blacklist_func_ret regcomp failed");
+ rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
+ if (rc) throw semantic_error ("blacklist_file regcomp failed");
+
+ blacklist_enabled = true;
+}
+
+
+string
+dwflpp::get_blacklist_section(Dwarf_Addr addr)
+{
+ string blacklist_section;
+ Dwarf_Addr bias;
+ // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
+ // because dwfl_module_getelf can force costly section relocations
+ // we don't really need, while either will do for this purpose.
+ Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (module, &bias))
+ ?: dwfl_module_getelf (module, &bias));
+
+ Dwarf_Addr offset = addr - bias;
+ if (elf)
+ {
+ Elf_Scn* scn = 0;
+ size_t shstrndx;
+ dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (! shdr)
+ continue; // XXX error?
+
+ if (!(shdr->sh_flags & SHF_ALLOC))
+ continue;
+
+ GElf_Addr start = shdr->sh_addr;
+ GElf_Addr end = start + shdr->sh_size;
+ if (! (offset >= start && offset < end))
+ continue;
+
+ blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name);
+ break;
+ }
+ }
+ return blacklist_section;
+}
+
+
+Dwarf_Addr
+dwflpp::relocate_address(Dwarf_Addr addr,
+ string& reloc_section,
+ string& blacklist_section)
+{
+ Dwarf_Addr reloc_addr = addr;
+ if (!module)
+ {
+ assert(module_name == TOK_KERNEL);
+ reloc_section = "";
+ blacklist_section = "";
+ }
+ else if (dwfl_module_relocations (module) > 0)
+ {
+ // This is a relocatable module; libdwfl already knows its
+ // sections, so we can relativize addr.
+ int idx = dwfl_module_relocate_address (module, &reloc_addr);
+ const char* r_s = dwfl_module_relocation_info (module, idx, NULL);
+ if (r_s)
+ reloc_section = r_s;
+ blacklist_section = reloc_section;
+
+ if (reloc_section == "" && dwfl_module_relocations (module) == 1)
+ {
+ blacklist_section = get_blacklist_section(addr);
+ reloc_section = ".dynamic";
+ reloc_addr = addr;
+ }
+ }
+ else
+ {
+ blacklist_section = get_blacklist_section(addr);
+ reloc_section = ".absolute";
+ }
+ return reloc_addr;
+}
+
+
+int
+dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes)
+{
+ if (!cached_scopes || pc != pc_cached_scopes)
+ {
+ free(cached_scopes);
+ cached_scopes = NULL;
+ pc_cached_scopes = pc;
+ num_cached_scopes = dwarf_getscopes(cu, pc, &cached_scopes);
+ }
+ *scopes = cached_scopes;
+ return num_cached_scopes;
+}
+
+
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
diff --git a/dwflpp.h b/dwflpp.h
index 042b37a9..314e7583 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -25,6 +25,7 @@
extern "C" {
#include <elfutils/libdwfl.h>
+#include <regex.h>
}
@@ -268,6 +269,19 @@ struct dwflpp
bool lvalue,
exp_type & ty);
+ bool blacklisted_p(const std::string& funcname,
+ const std::string& filename,
+ int line,
+ const std::string& module,
+ const std::string& section,
+ Dwarf_Addr addr,
+ bool has_return);
+
+ Dwarf_Addr relocate_address(Dwarf_Addr addr,
+ std::string& reloc_section,
+ std::string& blacklist_section);
+
+
private:
Dwfl * dwfl;
@@ -361,6 +375,18 @@ private:
std::string express_as_string (std::string prelude,
std::string postlude,
struct location *head);
+
+ regex_t blacklist_func; // function/statement probes
+ regex_t blacklist_func_ret; // only for .return probes
+ regex_t blacklist_file; // file name
+ bool blacklist_enabled;
+ void build_blacklist();
+ std::string get_blacklist_section(Dwarf_Addr addr);
+
+ Dwarf_Addr pc_cached_scopes;
+ int num_cached_scopes;
+ Dwarf_Die *cached_scopes;
+ int dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes);
};
#endif // DWFLPP_H
diff --git a/tapsets.cxx b/tapsets.cxx
index e88928dc..f83924ab 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -43,7 +43,6 @@ extern "C" {
#include <dwarf.h>
#include <elf.h>
#include <obstack.h>
-#include <regex.h>
#include <glob.h>
#include <fnmatch.h>
#include <stdio.h>
@@ -550,19 +549,6 @@ struct dwarf_query : public base_query
int line,
Dwarf_Die *scope_die,
Dwarf_Addr addr);
- string get_blacklist_section(Dwarf_Addr addr);
-
- regex_t blacklist_func; // function/statement probes
- regex_t blacklist_func_ret; // only for .return probes
- regex_t blacklist_file; // file name
- void build_blacklist();
-
- bool blacklisted_p(const string& funcname,
- const string& filename,
- int line,
- const string& module,
- const string& section,
- Dwarf_Addr addr);
// Extracted parameters.
string function_val;
@@ -705,7 +691,6 @@ dwarf_query::dwarf_query(systemtap_session & sess,
else if (has_statement_str)
spec_type = parse_function_spec(statement_str_val);
- build_blacklist(); // XXX: why not reuse amongst dwarf_query instances?
dbinfo_reqt = assess_dbinfo_reqt();
query_done = false;
}
@@ -872,138 +857,6 @@ dwarf_query::handle_query_module()
}
-void
-dwarf_query::build_blacklist()
-{
- // No blacklist for userspace.
- if (has_process)
- return;
-
- // We build up the regexps in these strings
-
- // Add ^ anchors at the front; $ will be added just before regcomp.
-
- string blfn = "^(";
- string blfn_ret = "^(";
- string blfile = "^(";
-
- blfile += "kernel/kprobes.c"; // first alternative, no "|"
- blfile += "|arch/.*/kernel/kprobes.c";
- // Older kernels need ...
- blfile += "|include/asm/io.h";
- blfile += "|include/asm/bitops.h";
- // While newer ones need ...
- blfile += "|arch/.*/include/asm/io.h";
- blfile += "|arch/.*/include/asm/bitops.h";
- blfile += "|drivers/ide/ide-iops.c";
-
- // XXX: it would be nice if these blacklisted functions were pulled
- // in dynamically, instead of being statically defined here.
- // Perhaps it could be populated from script files. A "noprobe
- // kernel.function("...")" construct might do the trick.
-
- // Most of these are marked __kprobes in newer kernels. We list
- // them here (anyway) so the translator can block them on older
- // kernels that don't have the __kprobes function decorator. This
- // also allows detection of problems at translate- rather than
- // run-time.
-
- blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
- blfn += "|default_do_nmi";
- blfn += "|__die";
- blfn += "|die_nmi";
- blfn += "|do_debug";
- blfn += "|do_general_protection";
- blfn += "|do_int3";
- blfn += "|do_IRQ";
- blfn += "|do_page_fault";
- blfn += "|do_sparc64_fault";
- blfn += "|do_trap";
- blfn += "|dummy_nmi_callback";
- blfn += "|flush_icache_range";
- blfn += "|ia64_bad_break";
- blfn += "|ia64_do_page_fault";
- blfn += "|ia64_fault";
- blfn += "|io_check_error";
- blfn += "|mem_parity_error";
- blfn += "|nmi_watchdog_tick";
- blfn += "|notifier_call_chain";
- blfn += "|oops_begin";
- blfn += "|oops_end";
- blfn += "|program_check_exception";
- blfn += "|single_step_exception";
- blfn += "|sync_regs";
- blfn += "|unhandled_fault";
- blfn += "|unknown_nmi_error";
-
- // Lots of locks
- blfn += "|.*raw_.*lock.*";
- blfn += "|.*read_.*lock.*";
- blfn += "|.*write_.*lock.*";
- blfn += "|.*spin_.*lock.*";
- blfn += "|.*rwlock_.*lock.*";
- blfn += "|.*rwsem_.*lock.*";
- blfn += "|.*mutex_.*lock.*";
- blfn += "|raw_.*";
- blfn += "|.*seq_.*lock.*";
-
- // atomic functions
- blfn += "|atomic_.*";
- blfn += "|atomic64_.*";
-
- // few other problematic cases
- blfn += "|get_bh";
- blfn += "|put_bh";
-
- // Experimental
- blfn += "|.*apic.*|.*APIC.*";
- blfn += "|.*softirq.*";
- blfn += "|.*IRQ.*";
- blfn += "|.*_intr.*";
- blfn += "|__delay";
- blfn += "|.*kernel_text.*";
- blfn += "|get_current";
- blfn += "|current_.*";
- blfn += "|.*exception_tables.*";
- blfn += "|.*setup_rt_frame.*";
-
- // PR 5759, CONFIG_PREEMPT kernels
- blfn += "|.*preempt_count.*";
- blfn += "|preempt_schedule";
-
- // These functions don't return, so return probes would never be recovered
- blfn_ret += "do_exit"; // no "|"
- blfn_ret += "|sys_exit";
- blfn_ret += "|sys_exit_group";
-
- // __switch_to changes "current" on x86_64 and i686, so return probes
- // would cause kernel panic, and it is marked as "__kprobes" on x86_64
- if (sess.architecture == "x86_64")
- blfn += "|__switch_to";
- if (sess.architecture == "i686")
- blfn_ret += "|__switch_to";
-
- blfn += ")$";
- blfn_ret += ")$";
- blfile += ")$";
-
- if (sess.verbose > 2)
- {
- clog << "blacklist regexps:" << endl;
- clog << "blfn: " << blfn << endl;
- clog << "blfn_ret: " << blfn_ret << endl;
- clog << "blfile: " << blfile << endl;
- }
-
- int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
- if (rc) throw semantic_error ("blacklist_func regcomp failed");
- rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
- if (rc) throw semantic_error ("blacklist_func_ret regcomp failed");
- rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
- if (rc) throw semantic_error ("blacklist_file regcomp failed");
-}
-
-
function_spec_type
dwarf_query::parse_function_spec(string & spec)
{
@@ -1094,129 +947,6 @@ dwarf_query::parse_function_spec(string & spec)
}
-#if 0
-// Forward declaration.
-static int query_kernel_module (Dwfl_Module *, void **, const char *,
- Dwarf_Addr, void *);
-#endif
-
-
-// XXX: pull this into dwflpp
-static bool
-in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
-{
- if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
- {
- // If the probe point address is anywhere in the __kprobes
- // address range, we can't use this probe point.
- if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
- return true;
- }
- return false;
-}
-
-
-bool
-dwarf_query::blacklisted_p(const string& funcname,
- const string& filename,
- int,
- const string& module,
- const string& section,
- Dwarf_Addr addr)
-{
- if (has_process)
- return false; // no blacklist for userspace
-
- if (section.substr(0, 6) == string(".init.") ||
- section.substr(0, 6) == string(".exit.") ||
- section.substr(0, 9) == string(".devinit.") ||
- section.substr(0, 9) == string(".devexit.") ||
- section.substr(0, 9) == string(".cpuinit.") ||
- section.substr(0, 9) == string(".cpuexit.") ||
- section.substr(0, 9) == string(".meminit.") ||
- section.substr(0, 9) == string(".memexit."))
- {
- // NB: module .exit. routines could be probed in theory:
- // if the exit handler in "struct module" is diverted,
- // first inserting the kprobes
- // then allowing the exit code to run
- // then removing these kprobes
- if (sess.verbose>1)
- clog << " skipping - init/exit";
- return true;
- }
-
- // Check for function marked '__kprobes'.
- if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
- {
- if (sess.verbose>1)
- clog << " skipping - __kprobes";
- return true;
- }
-
- // Check probe point against blacklist.
- int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
- if (has_return)
- goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
- int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
-
- if (! (goodfn && goodfile))
- {
- if (sess.guru_mode)
- {
- if (sess.verbose>1)
- clog << " guru mode enabled - ignoring blacklist";
- }
- else
- {
- if (sess.verbose>1)
- clog << " skipping - blacklisted";
- return true;
- }
- }
-
- // This probe point is not blacklisted.
- return false;
-}
-
-string dwarf_query::get_blacklist_section(Dwarf_Addr addr)
-{
- string blacklist_section;
- Dwarf_Addr bias;
- // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
- // because dwfl_module_getelf can force costly section relocations
- // we don't really need, while either will do for this purpose.
- Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (dw.module, &bias))
- ?: dwfl_module_getelf (dw.module, &bias));
-
- Dwarf_Addr offset = addr - bias;
- if (elf)
- {
- Elf_Scn* scn = 0;
- size_t shstrndx;
- dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
- while ((scn = elf_nextscn (elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (! shdr) continue; // XXX error?
-
- if (!(shdr->sh_flags & SHF_ALLOC))
- continue;
-
- GElf_Addr start = shdr->sh_addr;
- GElf_Addr end = start + shdr->sh_size;
- if (! (offset >= start && offset < end))
- continue;
-
- blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name);
- break;
- }
- }
- return blacklist_section;
-}
-
-
void
dwarf_query::add_probe_point(const string& funcname,
const char* filename,
@@ -1225,40 +955,13 @@ dwarf_query::add_probe_point(const string& funcname,
Dwarf_Addr addr)
{
string reloc_section; // base section for relocation purposes
- Dwarf_Addr reloc_addr = addr; // relocated
+ Dwarf_Addr reloc_addr; // relocated
string blacklist_section; // linking section for blacklist purposes
const string& module = dw.module_name; // "kernel" or other
assert (! has_absolute); // already handled in dwarf_builder::build()
- if (!dw.module)
- {
- assert(module == TOK_KERNEL);
- reloc_section = "";
- blacklist_section = "";
- }
- else if (dwfl_module_relocations (dw.module) > 0)
- {
- // This is a relocatable module; libdwfl already knows its
- // sections, so we can relativize addr.
- int idx = dwfl_module_relocate_address (dw.module, &reloc_addr);
- const char* r_s = dwfl_module_relocation_info (dw.module, idx, NULL);
- if (r_s)
- reloc_section = r_s;
- blacklist_section = reloc_section;
-
- if(reloc_section == "" && dwfl_module_relocations (dw.module) == 1)
- {
- blacklist_section = this->get_blacklist_section(addr);
- reloc_section = ".dynamic";
- reloc_addr = addr;
- }
- }
- else
- {
- blacklist_section = this->get_blacklist_section(addr);
- reloc_section = ".absolute";
- }
+ reloc_addr = dw.relocate_address(addr, reloc_section, blacklist_section);
if (sess.verbose > 1)
{
@@ -1274,7 +977,8 @@ dwarf_query::add_probe_point(const string& funcname,
clog << " pc=0x" << hex << addr << dec;
}
- bool bad = blacklisted_p (funcname, filename, line, module, blacklist_section, addr);
+ bool bad = dw.blacklisted_p (funcname, filename, line, module,
+ blacklist_section, addr, has_return);
if (sess.verbose > 1)
clog << endl;
@@ -1777,26 +1481,6 @@ query_cu (Dwarf_Die * cudie, void * arg)
}
-#if 0
-static int
-query_kernel_module (Dwfl_Module *mod,
- void **,
- const char *name,
- Dwarf_Addr,
- void *arg)
-{
- if (TOK_KERNEL == name)
- {
- Dwfl_Module **m = (Dwfl_Module **)arg;
-
- *m = mod;
- return DWARF_CB_ABORT;
- }
- return DWARF_CB_OK;
-}
-#endif
-
-
static void
validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
{