summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-05-07 15:15:29 -0700
committerJosh Stone <jistone@redhat.com>2009-05-07 15:16:27 -0700
commitdd0e4fa70fd7589ff80618305bd3d24e98a5d73b (patch)
treead838bedde6211cfc00bc3e080d6e31af0e57ce8
parent01c2eefe76e5a0eb8dd5a9504b522cdcb11f2665 (diff)
downloadsystemtap-steved-dd0e4fa70fd7589ff80618305bd3d24e98a5d73b.tar.gz
systemtap-steved-dd0e4fa70fd7589ff80618305bd3d24e98a5d73b.tar.xz
systemtap-steved-dd0e4fa70fd7589ff80618305bd3d24e98a5d73b.zip
Separate the kernel.mark tapset
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in20
-rw-r--r--tapset-mark.cxx712
-rw-r--r--tapsets.cxx709
-rw-r--r--tapsets.h1
5 files changed, 733 insertions, 711 deletions
diff --git a/Makefile.am b/Makefile.am
index dc8f060d..e65d1535 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,7 +39,7 @@ stap_SOURCES = main.cxx \
tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \
cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx \
tapset-been.cxx tapset-procfs.cxx tapset-timers.cxx \
- tapset-perfmon.cxx
+ tapset-perfmon.cxx tapset-mark.cxx
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
BUILT_SOURCES =
diff --git a/Makefile.in b/Makefile.in
index eded2636..0e0aee9a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -123,7 +123,8 @@ am_stap_OBJECTS = stap-main.$(OBJEXT) stap-parse.$(OBJEXT) \
stap-util.$(OBJEXT) stap-coveragedb.$(OBJEXT) \
stap-dwarf_wrappers.$(OBJEXT) stap-tapset-been.$(OBJEXT) \
stap-tapset-procfs.$(OBJEXT) stap-tapset-timers.$(OBJEXT) \
- stap-tapset-perfmon.$(OBJEXT) $(am__objects_1)
+ stap-tapset-perfmon.$(OBJEXT) stap-tapset-mark.$(OBJEXT) \
+ $(am__objects_1)
stap_OBJECTS = $(am_stap_OBJECTS)
stap_LINK = $(CXXLD) $(stap_CXXFLAGS) $(CXXFLAGS) $(stap_LDFLAGS) \
$(LDFLAGS) -o $@
@@ -330,7 +331,7 @@ 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 dwarf_wrappers.cxx \
tapset-been.cxx tapset-procfs.cxx tapset-timers.cxx \
- tapset-perfmon.cxx $(am__append_4)
+ tapset-perfmon.cxx tapset-mark.cxx $(am__append_4)
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ $(am__append_6)
# Arrange for git_version.h to be regenerated at every "make".
@@ -605,6 +606,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-parse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-staptree.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-been.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-mark.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-perfmon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-procfs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-timers.Po@am__quote@
@@ -1144,6 +1146,20 @@ stap-tapset-perfmon.obj: tapset-perfmon.cxx
@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-tapset-perfmon.obj `if test -f 'tapset-perfmon.cxx'; then $(CYGPATH_W) 'tapset-perfmon.cxx'; else $(CYGPATH_W) '$(srcdir)/tapset-perfmon.cxx'; fi`
+stap-tapset-mark.o: tapset-mark.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-tapset-mark.o -MD -MP -MF $(DEPDIR)/stap-tapset-mark.Tpo -c -o stap-tapset-mark.o `test -f 'tapset-mark.cxx' || echo '$(srcdir)/'`tapset-mark.cxx
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-tapset-mark.Tpo $(DEPDIR)/stap-tapset-mark.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tapset-mark.cxx' object='stap-tapset-mark.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-tapset-mark.o `test -f 'tapset-mark.cxx' || echo '$(srcdir)/'`tapset-mark.cxx
+
+stap-tapset-mark.obj: tapset-mark.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-tapset-mark.obj -MD -MP -MF $(DEPDIR)/stap-tapset-mark.Tpo -c -o stap-tapset-mark.obj `if test -f 'tapset-mark.cxx'; then $(CYGPATH_W) 'tapset-mark.cxx'; else $(CYGPATH_W) '$(srcdir)/tapset-mark.cxx'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-tapset-mark.Tpo $(DEPDIR)/stap-tapset-mark.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tapset-mark.cxx' object='stap-tapset-mark.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-tapset-mark.obj `if test -f 'tapset-mark.cxx'; then $(CYGPATH_W) 'tapset-mark.cxx'; else $(CYGPATH_W) '$(srcdir)/tapset-mark.cxx'; fi`
+
stap-modsign.o: modsign.cxx
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-modsign.o -MD -MP -MF $(DEPDIR)/stap-modsign.Tpo -c -o stap-modsign.o `test -f 'modsign.cxx' || echo '$(srcdir)/'`modsign.cxx
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-modsign.Tpo $(DEPDIR)/stap-modsign.Po
diff --git a/tapset-mark.cxx b/tapset-mark.cxx
new file mode 100644
index 00000000..1f0ef2ce
--- /dev/null
+++ b/tapset-mark.cxx
@@ -0,0 +1,712 @@
+// tapset for kernel static markers
+// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2007 Intel Corporation.
+// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
+//
+// 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 "session.h"
+#include "tapsets.h"
+#include "translate.h"
+#include "util.h"
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+extern "C" {
+#include <fnmatch.h>
+}
+
+
+using namespace std;
+using namespace __gnu_cxx;
+
+
+static string TOK_KERNEL("kernel");
+static string TOK_MARK("mark");
+static string TOK_FORMAT("format");
+
+
+// ------------------------------------------------------------------------
+// statically inserted macro-based derived probes
+// ------------------------------------------------------------------------
+
+struct mark_arg
+{
+ bool str;
+ string c_type;
+ exp_type stp_type;
+};
+
+struct mark_derived_probe: public derived_probe
+{
+ mark_derived_probe (systemtap_session &s,
+ const string& probe_name, const string& probe_format,
+ probe* base_probe, probe_point* location);
+
+ systemtap_session& sess;
+ string probe_name, probe_format;
+ vector <struct mark_arg *> mark_args;
+ bool target_symbol_seen;
+
+ void join_group (systemtap_session& s);
+ void print_dupe_stamp (ostream& o);
+ void emit_probe_context_vars (translator_output* o);
+ void initialize_probe_context_vars (translator_output* o);
+ void printargs (std::ostream &o) const;
+
+ void parse_probe_format ();
+};
+
+
+struct mark_derived_probe_group: public generic_dpg<mark_derived_probe>
+{
+public:
+ void emit_module_decls (systemtap_session& s);
+ void emit_module_init (systemtap_session& s);
+ void emit_module_exit (systemtap_session& s);
+};
+
+
+struct mark_var_expanding_visitor: public var_expanding_visitor
+{
+ mark_var_expanding_visitor(systemtap_session& s, const string& pn,
+ vector <struct mark_arg *> &mark_args):
+ sess (s), probe_name (pn), mark_args (mark_args),
+ target_symbol_seen (false) {}
+ systemtap_session& sess;
+ string probe_name;
+ vector <struct mark_arg *> &mark_args;
+ bool target_symbol_seen;
+
+ void visit_target_symbol (target_symbol* e);
+ void visit_target_symbol_arg (target_symbol* e);
+ void visit_target_symbol_context (target_symbol* e);
+};
+
+
+void
+mark_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
+{
+ string argnum_s = e->base_name.substr(4,e->base_name.length()-4);
+ int argnum = atoi (argnum_s.c_str());
+
+ if (argnum < 1 || argnum > (int)mark_args.size())
+ throw semantic_error ("invalid marker argument number", e->tok);
+
+ if (is_active_lvalue (e))
+ throw semantic_error("write to marker parameter not permitted", e->tok);
+
+ if (e->components.size() > 0)
+ {
+ switch (e->components[0].first)
+ {
+ case target_symbol::comp_literal_array_index:
+ throw semantic_error("marker argument may not be used as array",
+ e->tok);
+ break;
+ case target_symbol::comp_struct_member:
+ throw semantic_error("marker argument may not be used as a structure",
+ e->tok);
+ break;
+ default:
+ throw semantic_error ("invalid marker argument use", e->tok);
+ break;
+ }
+ }
+
+ // Remember that we've seen a target variable.
+ target_symbol_seen = true;
+
+ e->probe_context_var = "__mark_arg" + lex_cast<string>(argnum);
+ e->type = mark_args[argnum-1]->stp_type;
+ provide (e);
+}
+
+
+void
+mark_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
+{
+ string sname = e->base_name;
+
+ if (is_active_lvalue (e))
+ throw semantic_error("write to marker '" + sname + "' not permitted", e->tok);
+
+ if (e->components.size() > 0)
+ {
+ switch (e->components[0].first)
+ {
+ case target_symbol::comp_literal_array_index:
+ throw semantic_error("marker '" + sname + "' may not be used as array",
+ e->tok);
+ break;
+ case target_symbol::comp_struct_member:
+ throw semantic_error("marker '" + sname + "' may not be used as a structure",
+ e->tok);
+ break;
+ default:
+ throw semantic_error ("invalid marker '" + sname + "' use", e->tok);
+ break;
+ }
+ }
+
+ string fname;
+ if (e->base_name == "$format") {
+ fname = string("_mark_format_get");
+ } else {
+ fname = string("_mark_name_get");
+ }
+
+ // Synthesize a functioncall.
+ functioncall* n = new functioncall;
+ n->tok = e->tok;
+ n->function = fname;
+ n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
+ provide (n);
+}
+
+void
+mark_var_expanding_visitor::visit_target_symbol (target_symbol* e)
+{
+ assert(e->base_name.size() > 0 && e->base_name[0] == '$');
+
+ if (e->base_name.substr(0,4) == "$arg")
+ visit_target_symbol_arg (e);
+ else if (e->base_name == "$format" || e->base_name == "$name")
+ visit_target_symbol_context (e);
+ else
+ throw semantic_error ("invalid target symbol for marker, $argN, $name or $format expected",
+ e->tok);
+}
+
+
+
+mark_derived_probe::mark_derived_probe (systemtap_session &s,
+ const string& p_n,
+ const string& p_f,
+ probe* base, probe_point* loc):
+ derived_probe (base, new probe_point(*loc) /* .components soon rewritten */),
+ sess (s), probe_name (p_n), probe_format (p_f),
+ target_symbol_seen (false)
+{
+ // create synthetic probe point name; preserve condition
+ vector<probe_point::component*> comps;
+ comps.push_back (new probe_point::component (TOK_KERNEL));
+ comps.push_back (new probe_point::component (TOK_MARK, new literal_string (probe_name)));
+ comps.push_back (new probe_point::component (TOK_FORMAT, new literal_string (probe_format)));
+ this->sole_location()->components = comps;
+
+ // expand the marker format
+ parse_probe_format();
+
+ // Now expand the local variables in the probe body
+ mark_var_expanding_visitor v (sess, name, mark_args);
+ this->body = v.require (this->body);
+ target_symbol_seen = v.target_symbol_seen;
+
+ if (sess.verbose > 2)
+ clog << "marker-based " << name << " mark=" << probe_name
+ << " fmt='" << probe_format << "'" << endl;
+}
+
+
+static int
+skip_atoi(const char **s)
+{
+ int i = 0;
+ while (isdigit(**s))
+ i = i * 10 + *((*s)++) - '0';
+ return i;
+}
+
+
+void
+mark_derived_probe::parse_probe_format()
+{
+ const char *fmt = probe_format.c_str();
+ int qualifier; // 'h', 'l', or 'L' for integer fields
+ mark_arg *arg;
+
+ for (; *fmt ; ++fmt)
+ {
+ if (*fmt != '%')
+ {
+ /* Skip text */
+ continue;
+ }
+
+repeat:
+ ++fmt;
+
+ // skip conversion flags (if present)
+ switch (*fmt)
+ {
+ case '-':
+ case '+':
+ case ' ':
+ case '#':
+ case '0':
+ goto repeat;
+ }
+
+ // skip minimum field witdh (if present)
+ if (isdigit(*fmt))
+ skip_atoi(&fmt);
+
+ // skip precision (if present)
+ if (*fmt == '.')
+ {
+ ++fmt;
+ if (isdigit(*fmt))
+ skip_atoi(&fmt);
+ }
+
+ // get the conversion qualifier (if present)
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
+ {
+ qualifier = *fmt;
+ ++fmt;
+ if (qualifier == 'l' && *fmt == 'l')
+ {
+ qualifier = 'L';
+ ++fmt;
+ }
+ }
+
+ // get the conversion type
+ switch (*fmt)
+ {
+ case 'c':
+ arg = new mark_arg;
+ arg->str = false;
+ arg->c_type = "int";
+ arg->stp_type = pe_long;
+ mark_args.push_back(arg);
+ continue;
+
+ case 's':
+ arg = new mark_arg;
+ arg->str = true;
+ arg->c_type = "char *";
+ arg->stp_type = pe_string;
+ mark_args.push_back(arg);
+ continue;
+
+ case 'p':
+ arg = new mark_arg;
+ arg->str = false;
+ // This should really be 'void *'. But, then we'll get a
+ // compile error when we assign the void pointer to an
+ // integer without a cast. So, we use 'long' instead, since
+ // it should have the same size as 'void *'.
+ arg->c_type = "long";
+ arg->stp_type = pe_long;
+ mark_args.push_back(arg);
+ continue;
+
+ case '%':
+ continue;
+
+ case 'o':
+ case 'X':
+ case 'x':
+ case 'd':
+ case 'i':
+ case 'u':
+ // fall through...
+ break;
+
+ default:
+ if (!*fmt)
+ --fmt;
+ continue;
+ }
+
+ arg = new mark_arg;
+ arg->str = false;
+ arg->stp_type = pe_long;
+ switch (qualifier)
+ {
+ case 'L':
+ arg->c_type = "long long";
+ break;
+
+ case 'l':
+ arg->c_type = "long";
+ break;
+
+ case 'h':
+ arg->c_type = "short";
+ break;
+
+ default:
+ arg->c_type = "int";
+ break;
+ }
+ mark_args.push_back(arg);
+ }
+}
+
+
+void
+mark_derived_probe::join_group (systemtap_session& s)
+{
+ if (! s.mark_derived_probes)
+ {
+ s.mark_derived_probes = new mark_derived_probe_group ();
+
+ // Make sure <linux/marker.h> is included early.
+ embeddedcode *ec = new embeddedcode;
+ ec->tok = NULL;
+ ec->code = string("#if ! defined(CONFIG_MARKERS)\n")
+ + string("#error \"Need CONFIG_MARKERS!\"\n")
+ + string("#endif\n")
+ + string("#include <linux/marker.h>\n");
+
+ s.embeds.push_back(ec);
+ }
+ s.mark_derived_probes->enroll (this);
+}
+
+
+void
+mark_derived_probe::print_dupe_stamp (ostream& o)
+{
+ if (target_symbol_seen)
+ for (unsigned i = 0; i < mark_args.size(); i++)
+ o << mark_args[i]->c_type << " __mark_arg" << (i+1) << endl;
+}
+
+
+void
+mark_derived_probe::emit_probe_context_vars (translator_output* o)
+{
+ // If we haven't seen a target symbol for this probe, quit.
+ if (! target_symbol_seen)
+ return;
+
+ for (unsigned i = 0; i < mark_args.size(); i++)
+ {
+ string localname = "__mark_arg" + lex_cast<string>(i+1);
+ switch (mark_args[i]->stp_type)
+ {
+ case pe_long:
+ o->newline() << "int64_t " << localname << ";";
+ break;
+ case pe_string:
+ o->newline() << "string_t " << localname << ";";
+ break;
+ default:
+ throw semantic_error ("cannot expand unknown type");
+ break;
+ }
+ }
+}
+
+
+void
+mark_derived_probe::initialize_probe_context_vars (translator_output* o)
+{
+ // If we haven't seen a target symbol for this probe, quit.
+ if (! target_symbol_seen)
+ return;
+
+ bool deref_fault_needed = false;
+ for (unsigned i = 0; i < mark_args.size(); i++)
+ {
+ string localname = "l->__mark_arg" + lex_cast<string>(i+1);
+ switch (mark_args[i]->stp_type)
+ {
+ case pe_long:
+ o->newline() << localname << " = va_arg(*c->mark_va_list, "
+ << mark_args[i]->c_type << ");";
+ break;
+
+ case pe_string:
+ // We're assuming that this is a kernel string (this code is
+ // basically the guts of kernel_string), not a user string.
+ o->newline() << "{ " << mark_args[i]->c_type
+ << " tmp_str = va_arg(*c->mark_va_list, "
+ << mark_args[i]->c_type << ");";
+ o->newline() << "deref_string (" << localname
+ << ", tmp_str, MAXSTRINGLEN); }";
+ deref_fault_needed = true;
+ break;
+
+ default:
+ throw semantic_error ("cannot expand unknown type");
+ break;
+ }
+ }
+ if (deref_fault_needed)
+ // Need to report errors?
+ o->newline() << "deref_fault: ;";
+}
+
+void
+mark_derived_probe::printargs(std::ostream &o) const
+{
+ for (unsigned i = 0; i < mark_args.size(); i++)
+ {
+ string localname = "$arg" + lex_cast<string>(i+1);
+ switch (mark_args[i]->stp_type)
+ {
+ case pe_long:
+ o << " " << localname << ":long";
+ break;
+ case pe_string:
+ o << " " << localname << ":string";
+ break;
+ default:
+ o << " " << localname << ":unknown";
+ break;
+ }
+ }
+}
+
+
+void
+mark_derived_probe_group::emit_module_decls (systemtap_session& s)
+{
+ if (probes.empty())
+ return;
+
+ s.op->newline() << "/* ---- marker probes ---- */";
+
+ s.op->newline() << "static struct stap_marker_probe {";
+ s.op->newline(1) << "const char * const name;";
+ s.op->newline() << "const char * const format;";
+ s.op->newline() << "const char * const pp;";
+ s.op->newline() << "void (* const ph) (struct context *);";
+
+ s.op->newline(-1) << "} stap_marker_probes [" << probes.size() << "] = {";
+ s.op->indent(1);
+ for (unsigned i=0; i < probes.size(); i++)
+ {
+ s.op->newline () << "{";
+ s.op->line() << " .name=" << lex_cast_qstring(probes[i]->probe_name)
+ << ",";
+ s.op->line() << " .format=" << lex_cast_qstring(probes[i]->probe_format)
+ << ",";
+ s.op->line() << " .pp=" << lex_cast_qstring (*probes[i]->sole_location())
+ << ",";
+ s.op->line() << " .ph=&" << probes[i]->name;
+ s.op->line() << " },";
+ }
+ s.op->newline(-1) << "};";
+ s.op->newline();
+
+
+ // Emit the marker callback function
+ s.op->newline();
+ s.op->newline() << "static void enter_marker_probe (void *probe_data, void *call_data, const char *fmt, va_list *args) {";
+ s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;";
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "smp->pp");
+ s.op->newline() << "c->marker_name = smp->name;";
+ s.op->newline() << "c->marker_format = smp->format;";
+ s.op->newline() << "c->mark_va_list = args;";
+ s.op->newline() << "(*smp->ph) (c);";
+ s.op->newline() << "c->mark_va_list = NULL;";
+ s.op->newline() << "c->data = NULL;";
+
+ common_probe_entryfn_epilogue (s.op);
+ s.op->newline(-1) << "}";
+
+ return;
+}
+
+
+void
+mark_derived_probe_group::emit_module_init (systemtap_session &s)
+{
+ if (probes.size () == 0)
+ return;
+
+ s.op->newline() << "/* init marker probes */";
+ s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
+ s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
+ s.op->newline() << "probe_point = smp->pp;";
+ s.op->newline() << "rc = marker_probe_register(smp->name, smp->format, enter_marker_probe, smp);";
+ s.op->newline() << "if (rc) {";
+ s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
+ s.op->newline(1) << "struct stap_marker_probe *smp2 = &stap_marker_probes[j];";
+ s.op->newline() << "marker_probe_unregister(smp2->name, enter_marker_probe, smp2);";
+ s.op->newline(-1) << "}";
+ s.op->newline() << "break;"; // don't attempt to register any more probes
+ s.op->newline(-1) << "}";
+ s.op->newline(-1) << "}"; // for loop
+}
+
+
+void
+mark_derived_probe_group::emit_module_exit (systemtap_session& s)
+{
+ if (probes.empty())
+ return;
+
+ s.op->newline() << "/* deregister marker probes */";
+ s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
+ s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
+ s.op->newline() << "marker_probe_unregister(smp->name, enter_marker_probe, smp);";
+ s.op->newline(-1) << "}"; // for loop
+}
+
+
+struct mark_builder: public derived_probe_builder
+{
+private:
+ bool cache_initialized;
+ typedef multimap<string, string> mark_cache_t;
+ typedef multimap<string, string>::const_iterator mark_cache_const_iterator_t;
+ typedef pair<mark_cache_const_iterator_t, mark_cache_const_iterator_t>
+ mark_cache_const_iterator_pair_t;
+ mark_cache_t mark_cache;
+
+public:
+ mark_builder(): cache_initialized(false) {}
+
+ void build_no_more (systemtap_session &s)
+ {
+ if (! mark_cache.empty())
+ {
+ if (s.verbose > 3)
+ clog << "mark_builder releasing cache" << endl;
+ mark_cache.clear();
+ }
+ }
+
+ void build(systemtap_session & sess,
+ probe * base,
+ probe_point * location,
+ literal_map_t const & parameters,
+ vector<derived_probe *> & finished_results);
+};
+
+
+void
+mark_builder::build(systemtap_session & sess,
+ probe * base,
+ probe_point *loc,
+ literal_map_t const & parameters,
+ vector<derived_probe *> & finished_results)
+{
+ string mark_str_val;
+ bool has_mark_str = get_param (parameters, TOK_MARK, mark_str_val);
+ string mark_format_val;
+ bool has_mark_format = get_param (parameters, TOK_FORMAT, mark_format_val);
+ assert (has_mark_str);
+ (void) has_mark_str;
+
+ if (! cache_initialized)
+ {
+ cache_initialized = true;
+ string module_markers_path = sess.kernel_build_tree + "/Module.markers";
+
+ ifstream module_markers;
+ module_markers.open(module_markers_path.c_str(), ifstream::in);
+ if (! module_markers)
+ {
+ if (sess.verbose>3)
+ clog << module_markers_path << " cannot be opened: "
+ << strerror(errno) << endl;
+ return;
+ }
+
+ string name, module, format;
+ do
+ {
+ module_markers >> name >> module;
+ getline(module_markers, format);
+
+ // trim leading whitespace
+ string::size_type notwhite = format.find_first_not_of(" \t");
+ format.erase(0, notwhite);
+
+ // If the format is empty, make sure we add back a space
+ // character, which is what MARK_NOARGS expands to.
+ if (format.length() == 0)
+ format = " ";
+
+ if (sess.verbose>3)
+ clog << "'" << name << "' '" << module << "' '" << format
+ << "'" << endl;
+
+ if (mark_cache.count(name) > 0)
+ {
+ // If we have 2 markers with the same we've got 2 cases:
+ // different format strings or duplicate format strings.
+ // If an existing marker in the cache doesn't have the
+ // same format string, add this marker.
+ mark_cache_const_iterator_pair_t ret;
+ mark_cache_const_iterator_t it;
+ bool matching_format_string = false;
+
+ ret = mark_cache.equal_range(name);
+ for (it = ret.first; it != ret.second; ++it)
+ {
+ if (format == it->second)
+ {
+ matching_format_string = true;
+ break;
+ }
+ }
+
+ if (! matching_format_string)
+ mark_cache.insert(pair<string,string>(name, format));
+ }
+ else
+ mark_cache.insert(pair<string,string>(name, format));
+ }
+ while (! module_markers.eof());
+ module_markers.close();
+ }
+
+ // Search marker list for matching markers
+ for (mark_cache_const_iterator_t it = mark_cache.begin();
+ it != mark_cache.end(); it++)
+ {
+ // Below, "rc" has negative polarity: zero iff matching.
+ int rc = fnmatch(mark_str_val.c_str(), it->first.c_str(), 0);
+ if (! rc)
+ {
+ bool add_result = true;
+
+ // Match format strings (if the user specified one)
+ if (has_mark_format && fnmatch(mark_format_val.c_str(),
+ it->second.c_str(), 0))
+ add_result = false;
+
+ if (add_result)
+ {
+ derived_probe *dp
+ = new mark_derived_probe (sess,
+ it->first, it->second,
+ base, loc);
+ finished_results.push_back (dp);
+ }
+ }
+ }
+}
+
+
+
+void
+register_tapset_mark(systemtap_session& s)
+{
+ match_node* root = s.pattern_root;
+ derived_probe_builder *builder = new mark_builder();
+
+ root = root->bind(TOK_KERNEL);
+ root = root->bind_str(TOK_MARK);
+
+ root->bind(builder);
+ root->bind_str(TOK_FORMAT)->bind(builder);
+}
+
+/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
diff --git a/tapsets.cxx b/tapsets.cxx
index b4b58292..3ea94a73 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -8509,708 +8509,6 @@ kprobe_builder::build(systemtap_session & sess,
// ------------------------------------------------------------------------
-// statically inserted macro-based derived probes
-// ------------------------------------------------------------------------
-
-static string TOK_FORMAT("format");
-
-struct mark_arg
-{
- bool str;
- string c_type;
- exp_type stp_type;
-};
-
-struct mark_derived_probe: public derived_probe
-{
- mark_derived_probe (systemtap_session &s,
- const string& probe_name, const string& probe_format,
- probe* base_probe, probe_point* location);
-
- systemtap_session& sess;
- string probe_name, probe_format;
- vector <struct mark_arg *> mark_args;
- bool target_symbol_seen;
-
- void join_group (systemtap_session& s);
- void print_dupe_stamp (ostream& o);
- void emit_probe_context_vars (translator_output* o);
- void initialize_probe_context_vars (translator_output* o);
- void printargs (std::ostream &o) const;
-
- void parse_probe_format ();
-};
-
-
-struct mark_derived_probe_group: public generic_dpg<mark_derived_probe>
-{
-public:
- void emit_module_decls (systemtap_session& s);
- void emit_module_init (systemtap_session& s);
- void emit_module_exit (systemtap_session& s);
-};
-
-
-struct mark_var_expanding_visitor: public var_expanding_visitor
-{
- mark_var_expanding_visitor(systemtap_session& s, const string& pn,
- vector <struct mark_arg *> &mark_args):
- sess (s), probe_name (pn), mark_args (mark_args),
- target_symbol_seen (false) {}
- systemtap_session& sess;
- string probe_name;
- vector <struct mark_arg *> &mark_args;
- bool target_symbol_seen;
-
- void visit_target_symbol (target_symbol* e);
- void visit_target_symbol_arg (target_symbol* e);
- void visit_target_symbol_context (target_symbol* e);
-};
-
-
-void
-hex_dump(unsigned char *data, size_t len)
-{
- // Dump data
- size_t idx = 0;
- while (idx < len)
- {
- string char_rep;
-
- clog << " 0x" << setfill('0') << setw(8) << hex << internal << idx;
-
- for (int i = 0; i < 4; i++)
- {
- clog << " ";
- size_t limit = idx + 4;
- while (idx < len && idx < limit)
- {
- clog << setfill('0') << setw(2)
- << ((unsigned) *((unsigned char *)data + idx));
- if (isprint(*((char *)data + idx)))
- char_rep += *((char *)data + idx);
- else
- char_rep += '.';
- idx++;
- }
- while (idx < limit)
- {
- clog << " ";
- idx++;
- }
- }
- clog << " " << char_rep << dec << setfill(' ') << endl;
- }
-}
-
-
-void
-mark_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
-{
- string argnum_s = e->base_name.substr(4,e->base_name.length()-4);
- int argnum = atoi (argnum_s.c_str());
-
- if (argnum < 1 || argnum > (int)mark_args.size())
- throw semantic_error ("invalid marker argument number", e->tok);
-
- if (is_active_lvalue (e))
- throw semantic_error("write to marker parameter not permitted", e->tok);
-
- if (e->components.size() > 0)
- {
- switch (e->components[0].first)
- {
- case target_symbol::comp_literal_array_index:
- throw semantic_error("marker argument may not be used as array",
- e->tok);
- break;
- case target_symbol::comp_struct_member:
- throw semantic_error("marker argument may not be used as a structure",
- e->tok);
- break;
- default:
- throw semantic_error ("invalid marker argument use", e->tok);
- break;
- }
- }
-
- // Remember that we've seen a target variable.
- target_symbol_seen = true;
-
- e->probe_context_var = "__mark_arg" + lex_cast<string>(argnum);
- e->type = mark_args[argnum-1]->stp_type;
- provide (e);
-}
-
-
-void
-mark_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
-{
- string sname = e->base_name;
-
- if (is_active_lvalue (e))
- throw semantic_error("write to marker '" + sname + "' not permitted", e->tok);
-
- if (e->components.size() > 0)
- {
- switch (e->components[0].first)
- {
- case target_symbol::comp_literal_array_index:
- throw semantic_error("marker '" + sname + "' may not be used as array",
- e->tok);
- break;
- case target_symbol::comp_struct_member:
- throw semantic_error("marker '" + sname + "' may not be used as a structure",
- e->tok);
- break;
- default:
- throw semantic_error ("invalid marker '" + sname + "' use", e->tok);
- break;
- }
- }
-
- string fname;
- if (e->base_name == "$format") {
- fname = string("_mark_format_get");
- } else {
- fname = string("_mark_name_get");
- }
-
- // Synthesize a functioncall.
- functioncall* n = new functioncall;
- n->tok = e->tok;
- n->function = fname;
- n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
- provide (n);
-}
-
-void
-mark_var_expanding_visitor::visit_target_symbol (target_symbol* e)
-{
- assert(e->base_name.size() > 0 && e->base_name[0] == '$');
-
- if (e->base_name.substr(0,4) == "$arg")
- visit_target_symbol_arg (e);
- else if (e->base_name == "$format" || e->base_name == "$name")
- visit_target_symbol_context (e);
- else
- throw semantic_error ("invalid target symbol for marker, $argN, $name or $format expected",
- e->tok);
-}
-
-
-
-mark_derived_probe::mark_derived_probe (systemtap_session &s,
- const string& p_n,
- const string& p_f,
- probe* base, probe_point* loc):
- derived_probe (base, new probe_point(*loc) /* .components soon rewritten */),
- sess (s), probe_name (p_n), probe_format (p_f),
- target_symbol_seen (false)
-{
- // create synthetic probe point name; preserve condition
- vector<probe_point::component*> comps;
- comps.push_back (new probe_point::component (TOK_KERNEL));
- comps.push_back (new probe_point::component (TOK_MARK, new literal_string (probe_name)));
- comps.push_back (new probe_point::component (TOK_FORMAT, new literal_string (probe_format)));
- this->sole_location()->components = comps;
-
- // expand the marker format
- parse_probe_format();
-
- // Now expand the local variables in the probe body
- mark_var_expanding_visitor v (sess, name, mark_args);
- this->body = v.require (this->body);
- target_symbol_seen = v.target_symbol_seen;
-
- if (sess.verbose > 2)
- clog << "marker-based " << name << " mark=" << probe_name
- << " fmt='" << probe_format << "'" << endl;
-}
-
-
-static int
-skip_atoi(const char **s)
-{
- int i = 0;
- while (isdigit(**s))
- i = i * 10 + *((*s)++) - '0';
- return i;
-}
-
-
-void
-mark_derived_probe::parse_probe_format()
-{
- const char *fmt = probe_format.c_str();
- int qualifier; // 'h', 'l', or 'L' for integer fields
- mark_arg *arg;
-
- for (; *fmt ; ++fmt)
- {
- if (*fmt != '%')
- {
- /* Skip text */
- continue;
- }
-
-repeat:
- ++fmt;
-
- // skip conversion flags (if present)
- switch (*fmt)
- {
- case '-':
- case '+':
- case ' ':
- case '#':
- case '0':
- goto repeat;
- }
-
- // skip minimum field witdh (if present)
- if (isdigit(*fmt))
- skip_atoi(&fmt);
-
- // skip precision (if present)
- if (*fmt == '.')
- {
- ++fmt;
- if (isdigit(*fmt))
- skip_atoi(&fmt);
- }
-
- // get the conversion qualifier (if present)
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
- {
- qualifier = *fmt;
- ++fmt;
- if (qualifier == 'l' && *fmt == 'l')
- {
- qualifier = 'L';
- ++fmt;
- }
- }
-
- // get the conversion type
- switch (*fmt)
- {
- case 'c':
- arg = new mark_arg;
- arg->str = false;
- arg->c_type = "int";
- arg->stp_type = pe_long;
- mark_args.push_back(arg);
- continue;
-
- case 's':
- arg = new mark_arg;
- arg->str = true;
- arg->c_type = "char *";
- arg->stp_type = pe_string;
- mark_args.push_back(arg);
- continue;
-
- case 'p':
- arg = new mark_arg;
- arg->str = false;
- // This should really be 'void *'. But, then we'll get a
- // compile error when we assign the void pointer to an
- // integer without a cast. So, we use 'long' instead, since
- // it should have the same size as 'void *'.
- arg->c_type = "long";
- arg->stp_type = pe_long;
- mark_args.push_back(arg);
- continue;
-
- case '%':
- continue;
-
- case 'o':
- case 'X':
- case 'x':
- case 'd':
- case 'i':
- case 'u':
- // fall through...
- break;
-
- default:
- if (!*fmt)
- --fmt;
- continue;
- }
-
- arg = new mark_arg;
- arg->str = false;
- arg->stp_type = pe_long;
- switch (qualifier)
- {
- case 'L':
- arg->c_type = "long long";
- break;
-
- case 'l':
- arg->c_type = "long";
- break;
-
- case 'h':
- arg->c_type = "short";
- break;
-
- default:
- arg->c_type = "int";
- break;
- }
- mark_args.push_back(arg);
- }
-}
-
-
-void
-mark_derived_probe::join_group (systemtap_session& s)
-{
- if (! s.mark_derived_probes)
- {
- s.mark_derived_probes = new mark_derived_probe_group ();
-
- // Make sure <linux/marker.h> is included early.
- embeddedcode *ec = new embeddedcode;
- ec->tok = NULL;
- ec->code = string("#if ! defined(CONFIG_MARKERS)\n")
- + string("#error \"Need CONFIG_MARKERS!\"\n")
- + string("#endif\n")
- + string("#include <linux/marker.h>\n");
-
- s.embeds.push_back(ec);
- }
- s.mark_derived_probes->enroll (this);
-}
-
-
-void
-mark_derived_probe::print_dupe_stamp (ostream& o)
-{
- if (target_symbol_seen)
- for (unsigned i = 0; i < mark_args.size(); i++)
- o << mark_args[i]->c_type << " __mark_arg" << (i+1) << endl;
-}
-
-
-void
-mark_derived_probe::emit_probe_context_vars (translator_output* o)
-{
- // If we haven't seen a target symbol for this probe, quit.
- if (! target_symbol_seen)
- return;
-
- for (unsigned i = 0; i < mark_args.size(); i++)
- {
- string localname = "__mark_arg" + lex_cast<string>(i+1);
- switch (mark_args[i]->stp_type)
- {
- case pe_long:
- o->newline() << "int64_t " << localname << ";";
- break;
- case pe_string:
- o->newline() << "string_t " << localname << ";";
- break;
- default:
- throw semantic_error ("cannot expand unknown type");
- break;
- }
- }
-}
-
-
-void
-mark_derived_probe::initialize_probe_context_vars (translator_output* o)
-{
- // If we haven't seen a target symbol for this probe, quit.
- if (! target_symbol_seen)
- return;
-
- bool deref_fault_needed = false;
- for (unsigned i = 0; i < mark_args.size(); i++)
- {
- string localname = "l->__mark_arg" + lex_cast<string>(i+1);
- switch (mark_args[i]->stp_type)
- {
- case pe_long:
- o->newline() << localname << " = va_arg(*c->mark_va_list, "
- << mark_args[i]->c_type << ");";
- break;
-
- case pe_string:
- // We're assuming that this is a kernel string (this code is
- // basically the guts of kernel_string), not a user string.
- o->newline() << "{ " << mark_args[i]->c_type
- << " tmp_str = va_arg(*c->mark_va_list, "
- << mark_args[i]->c_type << ");";
- o->newline() << "deref_string (" << localname
- << ", tmp_str, MAXSTRINGLEN); }";
- deref_fault_needed = true;
- break;
-
- default:
- throw semantic_error ("cannot expand unknown type");
- break;
- }
- }
- if (deref_fault_needed)
- // Need to report errors?
- o->newline() << "deref_fault: ;";
-}
-
-void
-mark_derived_probe::printargs(std::ostream &o) const
-{
- for (unsigned i = 0; i < mark_args.size(); i++)
- {
- string localname = "$arg" + lex_cast<string>(i+1);
- switch (mark_args[i]->stp_type)
- {
- case pe_long:
- o << " " << localname << ":long";
- break;
- case pe_string:
- o << " " << localname << ":string";
- break;
- default:
- o << " " << localname << ":unknown";
- break;
- }
- }
-}
-
-
-void
-mark_derived_probe_group::emit_module_decls (systemtap_session& s)
-{
- if (probes.empty())
- return;
-
- s.op->newline() << "/* ---- marker probes ---- */";
-
- s.op->newline() << "static struct stap_marker_probe {";
- s.op->newline(1) << "const char * const name;";
- s.op->newline() << "const char * const format;";
- s.op->newline() << "const char * const pp;";
- s.op->newline() << "void (* const ph) (struct context *);";
-
- s.op->newline(-1) << "} stap_marker_probes [" << probes.size() << "] = {";
- s.op->indent(1);
- for (unsigned i=0; i < probes.size(); i++)
- {
- s.op->newline () << "{";
- s.op->line() << " .name=" << lex_cast_qstring(probes[i]->probe_name)
- << ",";
- s.op->line() << " .format=" << lex_cast_qstring(probes[i]->probe_format)
- << ",";
- s.op->line() << " .pp=" << lex_cast_qstring (*probes[i]->sole_location())
- << ",";
- s.op->line() << " .ph=&" << probes[i]->name;
- s.op->line() << " },";
- }
- s.op->newline(-1) << "};";
- s.op->newline();
-
-
- // Emit the marker callback function
- s.op->newline();
- s.op->newline() << "static void enter_marker_probe (void *probe_data, void *call_data, const char *fmt, va_list *args) {";
- s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;";
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "smp->pp");
- s.op->newline() << "c->marker_name = smp->name;";
- s.op->newline() << "c->marker_format = smp->format;";
- s.op->newline() << "c->mark_va_list = args;";
- s.op->newline() << "(*smp->ph) (c);";
- s.op->newline() << "c->mark_va_list = NULL;";
- s.op->newline() << "c->data = NULL;";
-
- common_probe_entryfn_epilogue (s.op);
- s.op->newline(-1) << "}";
-
- return;
-}
-
-
-void
-mark_derived_probe_group::emit_module_init (systemtap_session &s)
-{
- if (probes.size () == 0)
- return;
-
- s.op->newline() << "/* init marker probes */";
- s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
- s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
- s.op->newline() << "probe_point = smp->pp;";
- s.op->newline() << "rc = marker_probe_register(smp->name, smp->format, enter_marker_probe, smp);";
- s.op->newline() << "if (rc) {";
- s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
- s.op->newline(1) << "struct stap_marker_probe *smp2 = &stap_marker_probes[j];";
- s.op->newline() << "marker_probe_unregister(smp2->name, enter_marker_probe, smp2);";
- s.op->newline(-1) << "}";
- s.op->newline() << "break;"; // don't attempt to register any more probes
- s.op->newline(-1) << "}";
- s.op->newline(-1) << "}"; // for loop
-}
-
-
-void
-mark_derived_probe_group::emit_module_exit (systemtap_session& s)
-{
- if (probes.empty())
- return;
-
- s.op->newline() << "/* deregister marker probes */";
- s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
- s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
- s.op->newline() << "marker_probe_unregister(smp->name, enter_marker_probe, smp);";
- s.op->newline(-1) << "}"; // for loop
-}
-
-
-struct mark_builder: public derived_probe_builder
-{
-private:
- bool cache_initialized;
- typedef multimap<string, string> mark_cache_t;
- typedef multimap<string, string>::const_iterator mark_cache_const_iterator_t;
- typedef pair<mark_cache_const_iterator_t, mark_cache_const_iterator_t>
- mark_cache_const_iterator_pair_t;
- mark_cache_t mark_cache;
-
-public:
- mark_builder(): cache_initialized(false) {}
-
- void build_no_more (systemtap_session &s)
- {
- if (! mark_cache.empty())
- {
- if (s.verbose > 3)
- clog << "mark_builder releasing cache" << endl;
- mark_cache.clear();
- }
- }
-
- void build(systemtap_session & sess,
- probe * base,
- probe_point * location,
- literal_map_t const & parameters,
- vector<derived_probe *> & finished_results);
-};
-
-
-void
-mark_builder::build(systemtap_session & sess,
- probe * base,
- probe_point *loc,
- literal_map_t const & parameters,
- vector<derived_probe *> & finished_results)
-{
- string mark_str_val;
- bool has_mark_str = get_param (parameters, TOK_MARK, mark_str_val);
- string mark_format_val;
- bool has_mark_format = get_param (parameters, TOK_FORMAT, mark_format_val);
- assert (has_mark_str);
- (void) has_mark_str;
-
- if (! cache_initialized)
- {
- cache_initialized = true;
- string module_markers_path = sess.kernel_build_tree + "/Module.markers";
-
- ifstream module_markers;
- module_markers.open(module_markers_path.c_str(), ifstream::in);
- if (! module_markers)
- {
- if (sess.verbose>3)
- clog << module_markers_path << " cannot be opened: "
- << strerror(errno) << endl;
- return;
- }
-
- string name, module, format;
- do
- {
- module_markers >> name >> module;
- getline(module_markers, format);
-
- // trim leading whitespace
- string::size_type notwhite = format.find_first_not_of(" \t");
- format.erase(0, notwhite);
-
- // If the format is empty, make sure we add back a space
- // character, which is what MARK_NOARGS expands to.
- if (format.length() == 0)
- format = " ";
-
- if (sess.verbose>3)
- clog << "'" << name << "' '" << module << "' '" << format
- << "'" << endl;
-
- if (mark_cache.count(name) > 0)
- {
- // If we have 2 markers with the same we've got 2 cases:
- // different format strings or duplicate format strings.
- // If an existing marker in the cache doesn't have the
- // same format string, add this marker.
- mark_cache_const_iterator_pair_t ret;
- mark_cache_const_iterator_t it;
- bool matching_format_string = false;
-
- ret = mark_cache.equal_range(name);
- for (it = ret.first; it != ret.second; ++it)
- {
- if (format == it->second)
- {
- matching_format_string = true;
- break;
- }
- }
-
- if (! matching_format_string)
- mark_cache.insert(pair<string,string>(name, format));
- }
- else
- mark_cache.insert(pair<string,string>(name, format));
- }
- while (! module_markers.eof());
- module_markers.close();
- }
-
- // Search marker list for matching markers
- for (mark_cache_const_iterator_t it = mark_cache.begin();
- it != mark_cache.end(); it++)
- {
- // Below, "rc" has negative polarity: zero iff matching.
- int rc = fnmatch(mark_str_val.c_str(), it->first.c_str(), 0);
- if (! rc)
- {
- bool add_result = true;
-
- // Match format strings (if the user specified one)
- if (has_mark_format && fnmatch(mark_format_val.c_str(),
- it->second.c_str(), 0))
- add_result = false;
-
- if (add_result)
- {
- derived_probe *dp
- = new mark_derived_probe (sess,
- it->first, it->second,
- base, loc);
- finished_results.push_back (dp);
- }
- }
- }
-}
-
-
-
-// ------------------------------------------------------------------------
// statically inserted kernel-tracepoint derived probes
// ------------------------------------------------------------------------
@@ -10040,6 +9338,7 @@ void
register_standard_tapsets(systemtap_session & s)
{
register_tapset_been(s);
+ register_tapset_mark(s);
register_tapset_perfmon(s);
register_tapset_procfs(s);
register_tapset_timers(s);
@@ -10104,12 +9403,6 @@ register_standard_tapsets(systemtap_session & s)
s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK)
->bind(new itrace_builder ());
- // marker-based parts
- s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)
- ->bind(new mark_builder());
- s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)->bind_str(TOK_FORMAT)
- ->bind(new mark_builder());
-
// kernel tracepoint probes
s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_TRACE)
->bind(new tracepoint_builder());
diff --git a/tapsets.h b/tapsets.h
index f561aa59..d4fe7a91 100644
--- a/tapsets.h
+++ b/tapsets.h
@@ -21,6 +21,7 @@ void common_probe_entryfn_prologue (translator_output* o, std::string statestr,
void common_probe_entryfn_epilogue (translator_output* o, bool overload_processing = true);
void register_tapset_been(systemtap_session& sess);
+void register_tapset_mark(systemtap_session& sess);
void register_tapset_perfmon(systemtap_session& sess);
void register_tapset_procfs(systemtap_session& sess);
void register_tapset_timers(systemtap_session& sess);