summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Moore <moore@blackbox.bricoworks.com>2008-06-11 11:08:22 +0200
committerTim Moore <moore@blackbox.bricoworks.com>2008-06-11 11:11:54 +0200
commit86bf665eac22efa78936a3059e7bc90ee10dcf4b (patch)
tree3492e0f5b84f66c25bf5d2d33190dcba479ed8f4
parent335972be354a791757e475417c955efd9a45f03d (diff)
downloadsystemtap-steved-86bf665eac22efa78936a3059e7bc90ee10dcf4b.tar.gz
systemtap-steved-86bf665eac22efa78936a3059e7bc90ee10dcf4b.tar.xz
systemtap-steved-86bf665eac22efa78936a3059e7bc90ee10dcf4b.zip
PR 2608 plus some refactoring in tapsets.cxx
New dwarf_wrappers.h, dwarf_wrappers.cxx for for idiomatic access to libdwarf and refactoring somethings out of the giant classes in tapsets.cxx.
-rw-r--r--ChangeLog17
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in20
-rw-r--r--dwarf_wrappers.cxx40
-rw-r--r--dwarf_wrappers.h87
-rw-r--r--elaborate.h13
-rw-r--r--tapsets.cxx180
7 files changed, 256 insertions, 103 deletions
diff --git a/ChangeLog b/ChangeLog
index a70c2245..a5a6d3c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-06-11 Tim Moore <timoore@redhat.com>
+
+ PR 2608
+ * dwarf_wrappers.h, dwarf_wrappers.cxx: New files.
+ * Makefile.in: Regenerated.
+ * tapsets.cxx (dwarf_assert, dwfl_assert): Move to
+ dwarf_wrappers.h.
+ (iterate_over_srcfile_lines, has_single_line_record,
+ query_srcfile_line): Use dwarf_line_t wrapper.
+ (die_has_pc): Take a reference to a Dwarf_Die instead of a
+ pointer. Clean up use of dwfl_assert.
+ (query_cu): Check that statement raw address matches the beginning
+ of a statement record.
+ * elaborate.h: Include iosfwd instead of iostream.
+ (literal_map_t, resolve_prologue_endings,): New typedef.
+
+
2008-06-10 Jim Keniston <jkenisto@us.ibm.com>
* testsuite/systemtap.context/num_args.tcl: Run twice --
diff --git a/Makefile.am b/Makefile.am
index 6b5ac6fa..82d056c7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@ bin_PROGRAMS = stap staprun
stap_SOURCES = main.cxx \
parse.cxx staptree.cxx elaborate.cxx translate.cxx \
tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \
- cache.cxx util.cxx coveragedb.cxx
+ cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
BUILT_SOURCES =
diff --git a/Makefile.in b/Makefile.in
index af2bea5d..fa14e05b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -97,7 +97,8 @@ am_stap_OBJECTS = stap-main.$(OBJEXT) stap-parse.$(OBJEXT) \
stap-translate.$(OBJEXT) stap-tapsets.$(OBJEXT) \
stap-buildrun.$(OBJEXT) stap-loc2c.$(OBJEXT) \
stap-hash.$(OBJEXT) stap-mdfour.$(OBJEXT) stap-cache.$(OBJEXT) \
- stap-util.$(OBJEXT) stap-coveragedb.$(OBJEXT)
+ stap-util.$(OBJEXT) stap-coveragedb.$(OBJEXT) \
+ stap-dwarf_wrappers.$(OBJEXT)
stap_OBJECTS = $(am_stap_OBJECTS)
stap_LINK = $(CXXLD) $(stap_CXXFLAGS) $(CXXFLAGS) $(stap_LDFLAGS) \
$(LDFLAGS) -o $@
@@ -274,7 +275,7 @@ dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 ma
stap_SOURCES = main.cxx \
parse.cxx staptree.cxx elaborate.cxx translate.cxx \
tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \
- cache.cxx util.cxx coveragedb.cxx
+ cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
@@ -509,6 +510,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-buildrun.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-coveragedb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-dwarf_wrappers.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-elaborate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-hash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-loc2c.Po@am__quote@
@@ -922,6 +924,20 @@ stap-coveragedb.obj: coveragedb.cxx
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='coveragedb.cxx' object='stap-coveragedb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-coveragedb.obj `if test -f 'coveragedb.cxx'; then $(CYGPATH_W) 'coveragedb.cxx'; else $(CYGPATH_W) '$(srcdir)/coveragedb.cxx'; fi`
+
+stap-dwarf_wrappers.o: dwarf_wrappers.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-dwarf_wrappers.o -MD -MP -MF $(DEPDIR)/stap-dwarf_wrappers.Tpo -c -o stap-dwarf_wrappers.o `test -f 'dwarf_wrappers.cxx' || echo '$(srcdir)/'`dwarf_wrappers.cxx
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-dwarf_wrappers.Tpo $(DEPDIR)/stap-dwarf_wrappers.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dwarf_wrappers.cxx' object='stap-dwarf_wrappers.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-dwarf_wrappers.o `test -f 'dwarf_wrappers.cxx' || echo '$(srcdir)/'`dwarf_wrappers.cxx
+
+stap-dwarf_wrappers.obj: dwarf_wrappers.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-dwarf_wrappers.obj -MD -MP -MF $(DEPDIR)/stap-dwarf_wrappers.Tpo -c -o stap-dwarf_wrappers.obj `if test -f 'dwarf_wrappers.cxx'; then $(CYGPATH_W) 'dwarf_wrappers.cxx'; else $(CYGPATH_W) '$(srcdir)/dwarf_wrappers.cxx'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-dwarf_wrappers.Tpo $(DEPDIR)/stap-dwarf_wrappers.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dwarf_wrappers.cxx' object='stap-dwarf_wrappers.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-dwarf_wrappers.obj `if test -f 'dwarf_wrappers.cxx'; then $(CYGPATH_W) 'dwarf_wrappers.cxx'; else $(CYGPATH_W) '$(srcdir)/dwarf_wrappers.cxx'; fi`
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
diff --git a/dwarf_wrappers.cxx b/dwarf_wrappers.cxx
new file mode 100644
index 00000000..ad690d78
--- /dev/null
+++ b/dwarf_wrappers.cxx
@@ -0,0 +1,40 @@
+// -*- C++ -*-
+// Copyright (C) 2008 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+#include "dwarf_wrappers.h"
+#include "staptree.h"
+
+#include <cstring>
+#include <string>
+#include <elfutils/libdwfl.h>
+
+using std::string;
+
+void dwfl_assert(const string& desc, int rc)
+{
+ if (rc == 0)
+ return;
+ string msg = "libdwfl failure (" + desc + "): ";
+ if (rc < 0)
+ msg += dwfl_errmsg (rc);
+ else
+ msg += std::strerror (rc);
+ throw semantic_error (msg);
+}
+
+void dwarf_assert(const string& desc, int rc)
+{
+ if (rc == 0)
+ return;
+ string msg = "libdw failure (" + desc + "): ";
+ if (rc < 0)
+ msg += dwarf_errmsg (rc);
+ else
+ msg += std::strerror (rc);
+ throw semantic_error (msg);
+}
diff --git a/dwarf_wrappers.h b/dwarf_wrappers.h
new file mode 100644
index 00000000..043c2957
--- /dev/null
+++ b/dwarf_wrappers.h
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+// Copyright (C) 2008 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+#ifndef DWARF_WRAPPERS_H
+#define DWARF_WRAPPERS_H 1
+#include <elfutils/libdw.h>
+
+#include <string>
+
+// NB: "rc == 0" means OK in this case
+void dwfl_assert(const std::string& desc, int rc);
+
+template <typename T>
+void dwfl_assert(const std::string& desc, T* ptr)
+{
+ if (!ptr)
+ dwfl_assert(desc, -1);
+}
+
+template <typename T>
+void dwfl_assert(const std::string& desc, const T* ptr)
+{
+ if (!ptr)
+ dwfl_assert(desc, -1);
+}
+
+// NB: "rc == 0" means OK in this case
+void dwarf_assert(const std::string& desc, int rc);
+
+template <typename T>
+void dwarf_assert(const std::string& desc, T* ptr)
+{
+ if (!ptr)
+ dwarf_assert(desc, -1);
+}
+
+
+class dwarf_line_t
+{
+public:
+ const Dwarf_Line* line;
+ dwarf_line_t() : line(0) {}
+ dwarf_line_t(const Dwarf_Line* line_) : line(line_) {}
+
+ dwarf_line_t& operator= (const Dwarf_Line* line_)
+ {
+ line = (line_);
+ return *this;
+ }
+
+ operator bool() const
+ {
+ return line != 0;
+ }
+
+ int lineno() const
+ {
+ int lineval;
+ if (!line)
+ dwarf_assert("dwarf_line_t::lineno", -1);
+ dwarf_lineno(const_cast<Dwarf_Line*>(line), &lineval);
+ return lineval;
+ }
+ Dwarf_Addr addr() const
+ {
+ Dwarf_Addr addrval;
+ if (!line)
+ dwarf_assert("dwarf_line_t::addr", -1);
+ dwarf_lineaddr(const_cast<Dwarf_Line*>(line), &addrval);
+ return addrval;
+ }
+ const char* linesrc(Dwarf_Word* mtime = 0, Dwarf_Word* length = 0)
+ {
+ const char* retval = dwarf_linesrc(const_cast<Dwarf_Line*>(line), mtime,
+ length);
+ dwarf_assert("dwarf_line_t::linesrc", retval);
+ return retval;
+ }
+};
+
+
+#endif
diff --git a/elaborate.h b/elaborate.h
index 30bf5bce..c0e35477 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -13,7 +13,8 @@
#include "parse.h"
#include <string>
#include <vector>
-#include <iostream>
+//#include <iostream>
+#include <iosfwd>
#include <sstream>
#include <map>
@@ -175,21 +176,23 @@ struct derived_probe_group
// ------------------------------------------------------------------------
+typedef std::map<std::string, literal*> literal_map_t;
+
struct derived_probe_builder
{
virtual void build(systemtap_session & sess,
probe* base,
probe_point* location,
- std::map<std::string, literal*> const & parameters,
+ literal_map_t const & parameters,
std::vector<derived_probe*> & finished_results) = 0;
virtual ~derived_probe_builder() {}
virtual void build_no_more (systemtap_session &) {}
- static bool has_null_param (std::map<std::string, literal*> const & parameters,
+ static bool has_null_param (literal_map_t const & parameters,
const std::string& key);
- static bool get_param (std::map<std::string, literal*> const & parameters,
+ static bool get_param (literal_map_t const & parameters,
const std::string& key, std::string& value);
- static bool get_param (std::map<std::string, literal*> const & parameters,
+ static bool get_param (literal_map_t const & parameters,
const std::string& key, int64_t& value);
};
diff --git a/tapsets.cxx b/tapsets.cxx
index 3de2123c..f0809978 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -14,6 +14,7 @@
#include "translate.h"
#include "session.h"
#include "util.h"
+#include "dwarf_wrappers.h"
#include <cstdlib>
#include <algorithm>
@@ -61,7 +62,6 @@ extern "C" {
using namespace std;
using namespace __gnu_cxx;
-
// ------------------------------------------------------------------------
// Generic derived_probe_group: contains an ordinary vector of the
// given type. It provides only the enrollment function.
@@ -120,7 +120,6 @@ public:
void emit_module_exit (systemtap_session& s);
};
-
struct be_builder: public derived_probe_builder
{
be_t type;
@@ -130,7 +129,7 @@ struct be_builder: public derived_probe_builder
virtual void build(systemtap_session &,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t priority;
@@ -434,7 +433,7 @@ struct never_builder: public derived_probe_builder
virtual void build(systemtap_session &,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const &,
+ literal_map_t const &,
vector<derived_probe *> & finished_results)
{
finished_results.push_back(new never_derived_probe(base, location));
@@ -831,29 +830,6 @@ struct dwflpp
}
- // NB: "rc == 0" means OK in this case
- static void dwfl_assert(string desc, int rc, string extra_msg = "")
- {
- string msg = "libdwfl failure (" + desc + "): ";
- if (rc < 0) msg += dwfl_errmsg (rc);
- else if (rc > 0) msg += strerror (rc);
- if (rc != 0)
- {
- if (extra_msg.length() > 0)
- msg += "\n" + extra_msg;
- throw semantic_error (msg);
- }
- }
-
- void dwarf_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
- {
- string msg = "libdw failure (" + desc + "): ";
- if (rc < 0) msg += dwarf_errmsg (rc);
- else if (rc > 0) msg += strerror (rc);
- if (rc != 0)
- throw semantic_error (msg);
- }
-
// static so pathname_caching_callback() can access them
static module_cache_t module_cache;
static bool ignore_vmlinux;
@@ -1162,7 +1138,8 @@ struct dwflpp
int lineno,
bool need_single_match,
bool line_type_relative,
- void (* callback) (Dwarf_Line * line, void * arg),
+ void (* callback) (const dwarf_line_t& line,
+ void * arg),
void *data)
{
Dwarf_Line **srcsp = NULL;
@@ -1265,7 +1242,7 @@ struct dwflpp
{
if (pending_interrupts) return;
if (srcsp [i]) // skip over mismatched lines
- callback (srcsp[i], data);
+ callback (dwarf_line_t(srcsp[i]), data);
}
}
catch (...)
@@ -1346,23 +1323,23 @@ struct dwflpp
if (func->decl_file == 0) func->decl_file = "";
unsigned entrypc_srcline_idx = 0;
- Dwarf_Line* entrypc_srcline = 0;
+ dwarf_line_t entrypc_srcline;
// open-code binary search for exact match
{
unsigned l = 0, h = nlines;
while (l < h)
{
entrypc_srcline_idx = (l + h) / 2;
- Dwarf_Addr addr;
- Dwarf_Line *lr = dwarf_onesrcline(lines, entrypc_srcline_idx);
- dwarf_lineaddr (lr, &addr);
+ const dwarf_line_t lr(dwarf_onesrcline(lines,
+ entrypc_srcline_idx));
+ Dwarf_Addr addr = lr.addr();
if (addr == entrypc) { entrypc_srcline = lr; break; }
else if (l + 1 == h) { break; } // ran off bottom of tree
else if (addr < entrypc) { l = entrypc_srcline_idx; }
else { h = entrypc_srcline_idx; }
}
}
- if (entrypc_srcline == 0)
+ if (!entrypc_srcline)
throw semantic_error ("missing entrypc dwarf line record for function '"
+ func->name + "'");
@@ -1387,13 +1364,10 @@ struct dwflpp
bool ranoff_end = false;
while (postprologue_srcline_idx < nlines)
{
- Dwarf_Addr postprologue_addr;
- Dwarf_Line *lr = dwarf_onesrcline(lines, postprologue_srcline_idx);
- dwarf_lineaddr (lr, &postprologue_addr);
- const char* postprologue_file = dwarf_linesrc (lr, NULL, NULL);
- int postprologue_lineno;
- dwfl_assert ("dwarf_lineno",
- dwarf_lineno (lr, & postprologue_lineno));
+ dwarf_line_t lr(dwarf_onesrcline(lines, postprologue_srcline_idx));
+ Dwarf_Addr postprologue_addr = lr.addr();
+ const char* postprologue_file = lr.linesrc();
+ int postprologue_lineno = lr.lineno();
if (sess.verbose>2)
clog << "checking line record 0x" << hex << postprologue_addr << dec
@@ -1515,9 +1489,9 @@ struct dwflpp
dwarf_decl_line (function, linep);
}
- bool die_has_pc (Dwarf_Die * die, Dwarf_Addr pc)
+ bool die_has_pc (Dwarf_Die & die, Dwarf_Addr pc)
{
- int res = dwarf_haspc (die, pc);
+ int res = dwarf_haspc (&die, pc);
if (res == -1)
dwarf_assert ("dwarf_haspc", res);
return res == 1;
@@ -1554,14 +1528,14 @@ struct dwflpp
// We emit a comment approximating the variable+offset expression that
// relocatable module probing code will need to have.
Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
- dwfl_assert ("dwfl_addrmodule", mod == NULL);
+ dwfl_assert ("dwfl_addrmodule", mod);
int n = dwfl_module_relocations (mod);
- dwfl_assert ("dwfl_module_relocations", n < 0);
+ dwfl_assert ("dwfl_module_relocations", n);
int i = dwfl_module_relocate_address (mod, &address);
- dwfl_assert ("dwfl_module_relocate_address", i < 0);
+ dwfl_assert ("dwfl_module_relocate_address", i);
const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
- dwfl_assert ("dwfl_module_info", modname == NULL);
+ dwfl_assert ("dwfl_module_info", modname);
const char *secname = dwfl_module_relocation_info (mod, i, NULL);
if (n > 0 && !(n == 1 && secname == NULL))
@@ -2282,7 +2256,7 @@ struct base_query
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results);
virtual ~base_query() {}
@@ -2293,13 +2267,13 @@ struct base_query
vector<derived_probe *> & results;
// Parameter extractors.
- static bool has_null_param(map<string, literal *> const & params,
+ static bool has_null_param(literal_map_t const & params,
string const & k);
- static bool get_string_param(map<string, literal *> const & params,
+ static bool get_string_param(literal_map_t const & params,
string const & k, string & v);
- static bool get_number_param(map<string, literal *> const & params,
+ static bool get_number_param(literal_map_t const & params,
string const & k, long & v);
- static bool get_number_param(map<string, literal *> const & params,
+ static bool get_number_param(literal_map_t const & params,
string const & k, Dwarf_Addr & v);
// Extracted parameters.
@@ -2314,7 +2288,7 @@ base_query::base_query(systemtap_session & sess,
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results)
: sess(sess), base_probe(base_probe), base_loc(base_loc), dw(dw),
results(results)
@@ -2331,7 +2305,7 @@ base_query::base_query(systemtap_session & sess,
}
bool
-base_query::has_null_param(map<string, literal *> const & params,
+base_query::has_null_param(literal_map_t const & params,
string const & k)
{
return derived_probe_builder::has_null_param(params, k);
@@ -2339,7 +2313,7 @@ base_query::has_null_param(map<string, literal *> const & params,
bool
-base_query::get_string_param(map<string, literal *> const & params,
+base_query::get_string_param(literal_map_t const & params,
string const & k, string & v)
{
return derived_probe_builder::get_param (params, k, v);
@@ -2347,7 +2321,7 @@ base_query::get_string_param(map<string, literal *> const & params,
bool
-base_query::get_number_param(map<string, literal *> const & params,
+base_query::get_number_param(literal_map_t const & params,
string const & k, long & v)
{
int64_t value;
@@ -2358,7 +2332,7 @@ base_query::get_number_param(map<string, literal *> const & params,
bool
-base_query::get_number_param(map<string, literal *> const & params,
+base_query::get_number_param(literal_map_t const & params,
string const & k, Dwarf_Addr & v)
{
int64_t value;
@@ -2367,6 +2341,8 @@ base_query::get_number_param(map<string, literal *> const & params,
return present;
}
+typedef map<Dwarf_Addr, inline_instance_info> inline_instance_map_t;
+typedef map<Dwarf_Addr, func_info> func_info_map_t;
enum line_t { ABSOLUTE, RELATIVE };
@@ -2376,7 +2352,7 @@ struct dwarf_query : public base_query
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results);
virtual void handle_query_module();
@@ -2443,8 +2419,8 @@ struct dwarf_query : public base_query
set<char const *> filtered_srcfiles;
// Map official entrypc -> func_info object
- map<Dwarf_Addr, inline_instance_info> filtered_inlines;
- map<Dwarf_Addr, func_info> filtered_functions;
+ inline_instance_map_t filtered_inlines;
+ func_info_map_t filtered_functions;
bool choose_next_line;
Dwarf_Addr entrypc_for_next_line;
};
@@ -2484,14 +2460,13 @@ dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int linen
// We also try to filter out lines that leave the selected
// functions (if any).
- Dwarf_Line *line = srcsp[0];
- Dwarf_Addr addr;
- dwarf_lineaddr (line, &addr);
+ dwarf_line_t line(srcsp[0]);
+ Dwarf_Addr addr = line.addr();
- for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
+ for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (q->sess.verbose>4)
clog << "alternative line " << lineno << " accepted: fn=" << i->second.name << endl;
@@ -2499,10 +2474,10 @@ dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int linen
}
}
- for (map<Dwarf_Addr, inline_instance_info>::iterator i = q->filtered_inlines.begin();
+ for (inline_instance_map_t::iterator i = q->filtered_inlines.begin();
i != q->filtered_inlines.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (sess.verbose>4)
clog << "alternative line " << lineno << " accepted: ifn=" << i->second.name << endl;
@@ -2603,7 +2578,7 @@ struct dwarf_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
};
@@ -2612,7 +2587,7 @@ dwarf_query::dwarf_query(systemtap_session & sess,
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results)
: base_query(sess, base_probe, base_loc, dw, params, results)
{
@@ -3053,7 +3028,7 @@ string dwarf_query::get_blacklist_section(Dwarf_Addr addr)
{
Elf_Scn* scn = 0;
size_t shstrndx;
- dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
+ dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
while ((scn = elf_nextscn (elf, scn)) != NULL)
{
GElf_Shdr shdr_mem;
@@ -3305,20 +3280,18 @@ query_func_info (Dwarf_Addr entrypc,
static void
-query_srcfile_line (Dwarf_Line * line, void * arg)
+query_srcfile_line (const dwarf_line_t& line, void * arg)
{
dwarf_query * q = static_cast<dwarf_query *>(arg);
- Dwarf_Addr addr;
- dwarf_lineaddr(line, &addr);
+ Dwarf_Addr addr = line.addr();
- int lineno;
- dwarf_lineno (line, &lineno);
+ int lineno = line.lineno();
- for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
+ for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (q->sess.verbose>3)
clog << "function DIE lands on srcfile\n";
@@ -3331,11 +3304,11 @@ query_srcfile_line (Dwarf_Line * line, void * arg)
}
}
- for (map<Dwarf_Addr, inline_instance_info>::iterator i
+ for (inline_instance_map_t::iterator i
= q->filtered_inlines.begin();
i != q->filtered_inlines.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (q->sess.verbose>3)
clog << "inline instance DIE lands on srcfile\n";
@@ -3427,7 +3400,7 @@ query_dwarf_func (Dwarf_Die * func, void * arg)
Dwarf_Die d;
q->dw.function_die (&d);
- if (q->dw.die_has_pc (&d, query_addr))
+ if (q->dw.die_has_pc (d, query_addr))
record_this_function = true;
}
@@ -3513,7 +3486,24 @@ query_cu (Dwarf_Die * cudie, void * arg)
if (q->filtered_srcfiles.empty())
return DWARF_CB_OK;
}
-
+ // Verify that a raw address matches the beginning of a
+ // statement. This is a somewhat lame check that the address
+ // is at the start of an assembly instruction.
+ if (q->has_statement_num)
+ {
+ Dwarf_Addr queryaddr = q->statement_num_val;
+ dwarf_line_t address_line(dwarf_getsrc_die(cudie, queryaddr));
+ Dwarf_Addr lineaddr = 0;
+ if (address_line)
+ lineaddr = address_line.addr();
+ if (!address_line || lineaddr != queryaddr)
+ {
+ stringstream msg;
+ msg << "address 0x" << hex << queryaddr
+ << "does not match the begining of a statement";
+ throw semantic_error(msg.str());
+ }
+ }
// Pick up [entrypc, name, DIE] tuples for all the functions
// matching the query, and fill in the prologue endings of them
// all in a single pass.
@@ -3539,13 +3529,13 @@ query_cu (Dwarf_Die * cudie, void * arg)
else
{
// Otherwise, simply probe all resolved functions.
- for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
+ for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
query_func_info (i->first, i->second, q);
// And all inline instances (if we're not excluding inlines with ".call")
if (! q->has_call)
- for (map<Dwarf_Addr, inline_instance_info>::iterator i
+ for (inline_instance_map_t::iterator i
= q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
query_inline_instance_info (i->first, i->second, q);
}
@@ -3613,7 +3603,7 @@ validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
GElf_Ehdr ehdr_mem;
GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
- if (em == 0) { q->dw.dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
+ if (em == 0) { dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
int elf_machine = em->e_machine;
const char* debug_filename = "";
const char* main_filename = "";
@@ -4658,7 +4648,7 @@ void
dwarf_builder::build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
// NB: the kernel/user dwlfpp objects are long-lived.
@@ -5328,7 +5318,7 @@ struct utrace_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string path;
@@ -5854,7 +5844,7 @@ struct uprobe_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t process, address;
@@ -6172,7 +6162,7 @@ struct profile_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const &,
+ literal_map_t const &,
vector<derived_probe *> & finished_results)
{
finished_results.push_back(new profile_derived_probe(sess, base, location));
@@ -6689,7 +6679,7 @@ struct procfs_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
};
@@ -6698,7 +6688,7 @@ void
procfs_builder::build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string path;
@@ -7356,7 +7346,7 @@ public:
void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
};
@@ -7365,7 +7355,7 @@ void
mark_builder::build(systemtap_session & sess,
probe * base,
probe_point *loc,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string mark_str_val;
@@ -7655,7 +7645,7 @@ struct timer_builder: public derived_probe_builder
{
virtual void build(systemtap_session & sess,
probe * base, probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
static void register_patterns(match_node *root);
@@ -7665,7 +7655,7 @@ void
timer_builder::build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t period, rand=0;
@@ -7877,7 +7867,7 @@ struct perfmon_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string event;