diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | elaborate.cxx | 306 | ||||
-rw-r--r-- | elaborate.h | 62 | ||||
-rw-r--r-- | parse.cxx | 66 | ||||
-rw-r--r-- | parse.h | 2 | ||||
-rw-r--r-- | staptree.cxx | 25 | ||||
-rw-r--r-- | staptree.h | 13 | ||||
-rw-r--r-- | tapsets.cxx | 903 | ||||
-rw-r--r-- | tapsets.h | 54 |
9 files changed, 729 insertions, 717 deletions
@@ -1,3 +1,18 @@ +2005-06-27 Graydon Hoare <graydon@redhat.com> + + * staptree.{h,cxx} (probe_alias): New structure. + * parse.{h,cxx} (parser::parse): Parse probes or probe aliases. + (parser::parse_probe): Likewise. + * tapsets.{h,cxx}: + (derived_probe_builder): + (match_key): + (match_node): + (alias_derived_probe): Move from here, + * elaborate.{h,cxx}: to here. + * elaborate.h (systemtap_session::pattern_root): New member. + (register_library_aliases): New function. + * tapsets.cxx: Build one dwarf_derived_probe per target address. + 2005-06-23 Graydon Hoare <graydon@redhat.com> * tapsets.cxx diff --git a/elaborate.cxx b/elaborate.cxx index 2104c005..707d22f6 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -9,6 +9,7 @@ #include "config.h" #include "elaborate.h" #include "parse.h" +#include "tapsets.h" extern "C" { #include <sys/utsname.h> @@ -50,9 +51,306 @@ derived_probe::derived_probe (probe *p, probe_point *l): this->locals = p->locals; } +// ------------------------------------------------------------------------ + +// Members of match_key. + +match_key::match_key(string const & n) + : name(n), + have_parameter(false), + parameter_type(tok_junk) +{ +} + +match_key::match_key(probe_point::component const & c) + : name(c.functor), + have_parameter(c.arg != NULL), + parameter_type(c.arg ? c.arg->tok->type : tok_junk) +{ +} + +match_key & +match_key::with_number() +{ + have_parameter = true; + parameter_type = tok_number; + return *this; +} + +match_key & +match_key::with_string() +{ + have_parameter = true; + parameter_type = tok_string; + return *this; +} + +string +match_key::str() const +{ + if (have_parameter) + switch (parameter_type) + { + case tok_string: return name + "(string)"; + case tok_number: return name + "(number)"; + default: return name + "(...)"; + } + return name; +} + +bool +match_key::operator<(match_key const & other) const +{ + return ((name < other.name) + + || (name == name + && have_parameter < other.have_parameter) + + || (name == name + && have_parameter == other.have_parameter + && parameter_type < other.parameter_type)); +} + +// ------------------------------------------------------------------------ +// Members of match_node +// ------------------------------------------------------------------------ + +match_node::match_node() + : end(NULL) +{} + +match_node * +match_node::bind(match_key const & k) +{ + map<match_key, match_node *>::const_iterator i = sub.find(k); + if (i != sub.end()) + return i->second; + match_node * n = new match_node(); + sub.insert(make_pair(k, n)); + return n; +} + +void +match_node::bind(derived_probe_builder * e) +{ + if (end) + throw semantic_error("already have a pattern ending"); + end = e; +} + +match_node * +match_node::bind(string const & k) +{ + return bind(match_key(k)); +} + +match_node * +match_node::bind_str(string const & k) +{ + return bind(match_key(k).with_string()); +} + +match_node * +match_node::bind_num(string const & k) +{ + return bind(match_key(k).with_number()); +} + +derived_probe_builder * +match_node::find_builder(vector<probe_point::component *> const & components, + unsigned pos, + vector< pair<string, literal *> > & parameters) +{ + assert(pos <= components.size()); + if (pos == components.size()) + { + // Probe_point ends here. We match iff we have + // an "end" entry here. If we don't, it'll be null. + return end; + } + else + { + // Probe_point contains a component here. We match iff there's + // an entry in the sub table, and its value matches the rest + // of the probe_point. + match_key k(*components[pos]); + if (verbose) + clog << "searching for component " << k.str() << endl; + map<match_key, match_node *>::const_iterator i = sub.find(k); + if (i == sub.end()) + { + if (verbose) + clog << "no match found" << endl; + return NULL; + } + else + { + if (verbose) + clog << "matched " << k.str() << endl; + derived_probe_builder * builder = NULL; + if (k.have_parameter) + { + assert(components[pos]->arg); + parameters.push_back(make_pair(components[pos]->functor, + components[pos]->arg)); + } + else + { + // store a "null parameter" for any component we run into, anyways + literal_string *empty = NULL; + parameters.push_back(make_pair(components[pos]->functor, empty)); + } + builder = i->second->find_builder(components, pos+1, parameters); + if (k.have_parameter && !builder) + parameters.pop_back(); + return builder; + } + } +} + +static void +param_vec_to_map(vector< pair<string, literal *> > const & param_vec, + map<string, literal *> & param_map) +{ + for (vector< pair<string, literal *> >::const_iterator i = param_vec.begin(); + i != param_vec.end(); ++i) + { + param_map[i->first] = i->second; + } +} + +// ------------------------------------------------------------------------ +// Alias probes // ------------------------------------------------------------------------ +struct +alias_expansion_builder + : public derived_probe_builder +{ + probe_alias * alias; + + alias_expansion_builder(probe_alias * a) + : alias(a) + {} + + virtual void build(probe * use, + probe_point * location, + std::map<std::string, literal *> const & parameters, + vector<probe *> & results_to_expand_further, + vector<derived_probe *> & finished_results) + { + // We're going to build a new probe and wrap it up in an + // alias_expansion_probe so that the expansion loop recognizer it as + // such and re-expands its expansion. + + probe * n = new probe(); + n->body = new block(); + + // The new probe gets the location list of the alias, + n->locations = alias->locations; + + // the token location of the use, + n->tok = use->tok; + + // and a set of locals and statements representing the + // concatenation of the alias' body with the use's. + copy(alias->locals.begin(), alias->locals.end(), back_inserter(n->locals)); + copy(use->locals.begin(), use->locals.end(), back_inserter(n->locals)); + copy(alias->body->statements.begin(), + alias->body->statements.end(), + back_inserter(n->body->statements)); + copy(use->body->statements.begin(), + use->body->statements.end(), + back_inserter(n->body->statements)); + + results_to_expand_further.push_back(n); + } +}; + + +// ------------------------------------------------------------------------ +// Pattern matching +// ------------------------------------------------------------------------ + + +// Register all the aliases we've seen in library files, and the user +// file, as patterns. + +void +systemtap_session::register_library_aliases() +{ + vector<stapfile*> files(library_files); + files.push_back(user_file); + + for (unsigned f = 0; f < files.size(); ++f) + { + stapfile * file = files[f]; + for (unsigned a = 0; a < file->aliases.size(); ++a) + { + probe_alias * alias = file->aliases[a]; + for (unsigned n = 0; n < alias->alias_names.size(); ++n) + { + probe_point * name = alias->alias_names[n]; + if (verbose) + { + clog << "registering probe alias "; + for (unsigned c = 0; c < name->components.size(); ++c) + clog << (c > 0 ? "." : "") << name->components[c]->functor; + clog << endl; + } + match_node * n = pattern_root; + for (unsigned c = 0; c < name->components.size(); ++c) + { + probe_point::component * comp = name->components[c]; + // XXX: alias parameters + if (comp->arg) + throw semantic_error("alias component " + + comp->functor + + " contains illegal parameter"); + n = n->bind(comp->functor); + } + n->bind(new alias_expansion_builder(alias)); + } + } + } +} + + +// The match-and-expand loop. +void +symresolution_info::derive_probes (match_node * root, + probe *p, vector<derived_probe*>& dps) +{ + for (unsigned i = 0; i < p->locations.size(); ++i) + { + probe_point *loc = p->locations[i]; + vector< pair<string, literal *> > param_vec; + map<string, literal *> param_map; + vector<probe *> re_expand; + + derived_probe_builder * builder = + root->find_builder(loc->components, 0, param_vec); + + if (!builder) + throw semantic_error ("no match for probe point", loc->tok); + + param_vec_to_map(param_vec, param_map); + + builder->build(p, loc, param_map, re_expand, dps); + + // Recursively expand any further-expanding results + if (!re_expand.empty()) + { + for (unsigned j = 0; j < re_expand.size(); ++j) + derive_probes(root, re_expand[j], dps); + } + } +} + +// ------------------------------------------------------------------------ + + static int semantic_pass_symbols (systemtap_session&); static int semantic_pass_types (systemtap_session&); @@ -62,7 +360,7 @@ static int semantic_pass_types (systemtap_session&); // Link up symbols to their declarations. Set the session's // files/probes/functions/globals vectors from the transitively // reached set of stapfiles in s.library_files, starting from -// s.user_file. Perform automatic tapset inclusion and XXX: probe +// s.user_file. Perform automatic tapset inclusion and probe // alias expansion. static int semantic_pass_symbols (systemtap_session& s) @@ -114,7 +412,7 @@ semantic_pass_symbols (systemtap_session& s) { // much magic happens here: probe alias expansion, // provider identification - sym.derive_probes (p, dps); + sym.derive_probes (s.pattern_root, p, dps); } catch (const semantic_error& e) { @@ -149,6 +447,9 @@ semantic_pass_symbols (systemtap_session& s) int semantic_pass (systemtap_session& s) { + s.register_library_aliases(); + register_standard_tapsets(s.pattern_root); + int rc = semantic_pass_symbols (s); if (rc == 0) rc = semantic_pass_types (s); return rc; @@ -159,6 +460,7 @@ semantic_pass (systemtap_session& s) systemtap_session::systemtap_session (): + pattern_root(new match_node), user_file (0), op (0), up (0), num_errors (0) { } diff --git a/elaborate.h b/elaborate.h index 06cec813..3c0c8ed4 100644 --- a/elaborate.h +++ b/elaborate.h @@ -13,12 +13,16 @@ #include "parse.h" #include <string> #include <vector> - +#include <iostream> +#include <sstream> +#include <map> // ------------------------------------------------------------------------ struct systemtap_session; struct derived_probe; +struct match_node; + struct symresolution_info: public traversing_visitor { protected: @@ -30,7 +34,7 @@ public: symresolution_info (systemtap_session& s); // XXX: instead in systemtap_session? - void derive_probes (probe *p, std::vector<derived_probe*>& dps); + void derive_probes (match_node * root, probe *p, std::vector<derived_probe*>& dps); protected: vardecl* find_scalar (const std::string& name); @@ -130,6 +134,57 @@ struct derived_probe: public probe // } }; +// ------------------------------------------------------------------------ + +struct +derived_probe_builder +{ + virtual void build(probe * base, + probe_point * location, + std::map<std::string, literal *> const & parameters, + std::vector<probe *> & results_to_expand_further, + std::vector<derived_probe *> & finished_results) = 0; + virtual ~derived_probe_builder() {} +}; + + +struct +match_key +{ + std::string name; + bool have_parameter; + token_type parameter_type; + + match_key(std::string const & n); + match_key(probe_point::component const & c); + + match_key & with_number(); + match_key & with_string(); + std::string str() const; + bool operator<(match_key const & other) const; +}; + + +class +match_node +{ + std::map<match_key, match_node *> sub; + derived_probe_builder * end; + + public: + match_node(); + derived_probe_builder * find_builder(std::vector<probe_point::component *> const & components, + unsigned pos, + std::vector< std::pair<std::string, literal *> > & parameters); + + match_node * bind(match_key const & k); + match_node * bind(std::string const & k); + match_node * bind_str(std::string const & k); + match_node * bind_num(std::string const & k); + void bind(derived_probe_builder * e); +}; + +// ------------------------------------------------------------------------ class unparser; @@ -139,6 +194,9 @@ struct systemtap_session { systemtap_session (); + match_node * pattern_root; + void register_library_aliases(); + // parse trees for the various script files stapfile* user_file; std::vector<stapfile*> library_files; @@ -373,7 +373,15 @@ parser::parse () empty = false; if (t->type == tok_identifier && t->content == "probe") - f->probes.push_back (parse_probe ()); + { + probe * p; + probe_alias * a; + parse_probe (p, a); + if (a) + f->aliases.push_back(a); + else + f->probes.push_back (p); + } else if (t->type == tok_identifier && t->content == "global") parse_global (f->globals); else if (t->type == tok_identifier && t->content == "function") @@ -414,31 +422,49 @@ parser::parse () } -probe* -parser::parse_probe () +void +parser::parse_probe (probe * & probe_ret, + probe_alias * & alias_ret) { const token* t0 = next (); if (! (t0->type == tok_identifier && t0->content == "probe")) throw parse_error ("expected 'probe'"); - probe *p = new probe; - p->tok = t0; + probe_ret = NULL; + alias_ret = NULL; + + vector<probe_point *> aliases; + vector<probe_point *> locations; + + bool equals_ok = true; while (1) { const token *t = peek (); if (t && t->type == tok_identifier) { - p->locations.push_back (parse_probe_point ()); + probe_point * pp = parse_probe_point (); t = peek (); - if (t && t->type == tok_operator && t->content == ",") + if (equals_ok && t + && t->type == tok_operator && t->content == "=") { + aliases.push_back(pp); + next (); + continue; + } + else if (t && t->type == tok_operator && t->content == ",") + { + locations.push_back(pp); + equals_ok = false; next (); continue; } else if (t && t->type == tok_operator && t->content == "{") - break; + { + locations.push_back(pp); + break; + } else throw parse_error ("expected ',' or '{'"); // XXX: unify logic with that in parse_symbol() @@ -446,10 +472,22 @@ parser::parse_probe () else throw parse_error ("expected probe point specifier"); } - + + probe *p; + if (aliases.empty()) + { + probe_ret = new probe; + p = probe_ret; + } + else + { + alias_ret = new probe_alias(aliases);; + p = alias_ret; + } + + p->tok = t0; + p->locations = locations; p->body = parse_stmt_block (); - - return p; } @@ -646,7 +684,7 @@ parser::parse_probe_point () t = peek (); if (t && t->type == tok_operator - && (t->content == "{" || t->content == ",")) + && (t->content == "{" || t->content == "," || t->content == "=")) break; if (t && t->type == tok_operator && t->content == "(") @@ -660,7 +698,7 @@ parser::parse_probe_point () t = peek (); if (t && t->type == tok_operator - && (t->content == "{" || t->content == ",")) + && (t->content == "{" || t->content == "," || t->content == "=")) break; else if (t && t->type == tok_operator && t->content == "(") @@ -671,7 +709,7 @@ parser::parse_probe_point () if (t && t->type == tok_operator && t->content == ".") next (); else - throw parse_error ("expected '.' or ',' or '(' or '{'"); + throw parse_error ("expected '.' or ',' or '(' or '{' or '='"); } return pl; @@ -95,7 +95,7 @@ private: unsigned num_errors; private: // nonterminals - probe* parse_probe (); + void parse_probe (probe *&, probe_alias *&); probe_point* parse_probe_point (); literal* parse_literal (); void parse_global (std::vector<vardecl*>&); diff --git a/staptree.cxx b/staptree.cxx index f74f9a91..1243df98 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -373,6 +373,12 @@ void stapfile::print (ostream& o) o << endl; } + for (unsigned i=0; i<aliases.size(); i++) + { + aliases[i]->print (o); + o << endl; + } + for (unsigned i=0; i<probes.size(); i++) { probes[i]->print (o); @@ -417,6 +423,25 @@ void probe_point::print (ostream& o) } } +probe_alias::probe_alias(std::vector<probe_point*> const & aliases): + probe (), alias_names (aliases) +{ +} + +void probe_alias::printsig (ostream& o) +{ + for (unsigned i=0; i<alias_names.size(); i++) + { + o << (i>0 ? " = " : ""); + alias_names[i]->print (o); + } + for (unsigned i=0; i<locations.size(); i++) + { + o << (i>0 ? ", " : ""); + locations[i]->print (o); + } +} + ostream& operator << (ostream& o, probe_point& k) { @@ -356,10 +356,12 @@ struct next_statement: public statement struct probe; +struct probe_alias; struct stapfile { std::string name; std::vector<probe*> probes; + std::vector<probe_alias*> aliases; std::vector<functiondecl*> functions; std::vector<vardecl*> globals; void print (std::ostream& o); @@ -392,9 +394,18 @@ struct probe std::vector<vardecl*> locals; probe (); void print (std::ostream& o); - void printsig (std::ostream &o); + virtual void printsig (std::ostream &o); + virtual ~probe() {} }; +struct probe_alias + : public probe +{ + probe_alias(std::vector<probe_point*> const & aliases); + std::vector<probe_point*> alias_names; + virtual void printsig (std::ostream &o); + virtual ~probe_alias() {} +}; // An derived visitor instance is used to visit the entire diff --git a/tapsets.cxx b/tapsets.cxx index bdbb1bf2..a56fb659 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -30,227 +30,6 @@ extern "C" { using namespace std; -// Members of match_key. - -match_key::match_key(string const & n) - : name(n), - have_parameter(false), - parameter_type(tok_junk) -{ -} - -match_key::match_key(probe_point::component const & c) - : name(c.functor), - have_parameter(c.arg != NULL), - parameter_type(c.arg ? c.arg->tok->type : tok_junk) -{ -} - -match_key & -match_key::with_number() -{ - have_parameter = true; - parameter_type = tok_number; - return *this; -} - -match_key & -match_key::with_string() -{ - have_parameter = true; - parameter_type = tok_string; - return *this; -} - -string -match_key::str() const -{ - if (have_parameter) - switch (parameter_type) - { - case tok_string: return name + "(string)"; - case tok_number: return name + "(number)"; - default: return name + "(...)"; - } - return name; -} - -bool -match_key::operator<(match_key const & other) const -{ - return ((name < other.name) - - || (name == name - && have_parameter < other.have_parameter) - - || (name == name - && have_parameter == other.have_parameter - && parameter_type < other.parameter_type)); -} - - -// Members of match_node. - -match_node::match_node() - : end(NULL) -{} - -match_node & -match_node::bind(match_key const & k) -{ - map<match_key, match_node *>::const_iterator i = sub.find(k); - if (i != sub.end()) - return *i->second; - match_node * n = new match_node(); - sub.insert(make_pair(k, n)); - return *n; -} - -void -match_node::bind(derived_probe_builder * e) -{ - if (end) - throw semantic_error("already have a pattern ending"); - end = e; -} - -match_node & -match_node::bind(string const & k) -{ - return bind(match_key(k)); -} - -match_node & -match_node::bind_str(string const & k) -{ - return bind(match_key(k).with_string()); -} - -match_node & -match_node::bind_num(string const & k) -{ - return bind(match_key(k).with_number()); -} - -derived_probe_builder * -match_node::find_builder(vector<probe_point::component *> const & components, - unsigned pos, - vector< pair<string, literal *> > & parameters) -{ - assert(pos <= components.size()); - if (pos == components.size()) - { - // Probe_point ends here. We match iff we have - // an "end" entry here. If we don't, it'll be null. - return end; - } - else - { - // Probe_point contains a component here. We match iff there's - // an entry in the sub table, and its value matches the rest - // of the probe_point. - match_key k(*components[pos]); - map<match_key, match_node *>::const_iterator i = sub.find(k); - if (i == sub.end()) - return NULL; - else - { - derived_probe_builder * builder = NULL; - if (k.have_parameter) - { - assert(components[pos]->arg); - parameters.push_back(make_pair(components[pos]->functor, - components[pos]->arg)); - } - else - { - // store a "null parameter" for any component we run into, anyways - literal_string *empty = NULL; - parameters.push_back(make_pair(components[pos]->functor, empty)); - } - builder = i->second->find_builder(components, pos+1, parameters); - if (k.have_parameter && !builder) - parameters.pop_back(); - return builder; - } - } -} - - -static void -param_vec_to_map(vector< pair<string, literal *> > const & param_vec, - map<string, literal *> & param_map) -{ - for (vector< pair<string, literal *> >::const_iterator i = param_vec.begin(); - i != param_vec.end(); ++i) - { - param_map[i->first] = i->second; - } -} - -// XXX: bind patterns for probe aliases found in AST - -struct -alias_derived_probe -{ - alias_derived_probe(probe_point * expansion) - : alias_expansion(expansion) {} - probe_point * alias_expansion; - void emit_registrations (translator_output* o, unsigned i) {} - void emit_deregistrations (translator_output* o, unsigned i) {} - void emit_probe_entries (translator_output* o, unsigned i) {} -}; - -// The root of the global pattern-matching tree. -static match_node * root_node; - - -// The match-and-expand loop. -void -symresolution_info::derive_probes (probe *p, vector<derived_probe*>& dps) -{ - if (!root_node) - { - root_node = new match_node(); - register_standard_tapsets(*root_node); - } - - assert(root_node); - - deque<probe_point *> work(p->locations.begin(), p->locations.end()); - - while(!work.empty()) - { - probe_point *loc = work.front(); - work.pop_front(); - - vector< pair<string, literal *> > param_vec; - map<string, literal *> param_map; - - derived_probe_builder * builder = - root_node->find_builder(loc->components, 0, param_vec); - - if (!builder) - throw semantic_error ("no match for probe point", loc->tok); - - param_vec_to_map(param_vec, param_map); - - derived_probe *derived = builder->build(p, loc, param_map); - assert(derived); - - // Append to worklist if it's an alias; append to result otherwise. - alias_derived_probe *as_alias = dynamic_cast<alias_derived_probe *>(derived); - if (as_alias) - { - work.push_back(as_alias->alias_expansion); - delete derived; - } - else - dps.push_back (derived); - } -} - - // ------------------------------------------------------------------------ // begin/end probes are run right during registration / deregistration // ------------------------------------------------------------------------ @@ -273,11 +52,13 @@ be_builder { bool begin; be_builder(bool b) : begin(b) {} - virtual derived_probe * build(probe * base, - probe_point * location, - map<string, literal *> const & parameters) + virtual void build(probe * base, + probe_point * location, + std::map<std::string, literal *> const & parameters, + vector<probe *> & results_to_expand_further, + vector<derived_probe *> & finished_results) { - return new be_derived_probe(base, location, begin); + finished_results.push_back(new be_derived_probe(base, location, begin)); } virtual ~be_builder() {} }; @@ -334,10 +115,10 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j) } +#ifdef HAVE_ELFUTILS_LIBDWFL_H // ------------------------------------------------------------------------ // Dwarf derived probes. // ------------------------------------------------------------------------ -#ifdef HAVE_ELFUTILS_LIBDWFL_H // Helper for dealing with selected portions of libdwfl in a more readable // fashion, and with specific cleanup / checking / logging options. @@ -665,6 +446,19 @@ dwflpp } }; +static string TOK_PROCESS("process"); +static string TOK_KERNEL("kernel"); +static string TOK_MODULE("module"); + +static string TOK_FUNCTION("function"); +static string TOK_RETURN("return"); +static string TOK_CALLEES("callees"); + +static string TOK_STATEMENT("statement"); +static string TOK_LABEL("label"); +static string TOK_RELATIVE("relative"); + + enum function_spec_type { @@ -674,53 +468,51 @@ function_spec_type }; enum -probe_type +dwarf_probe_type { probe_address, - probe_function_return + probe_function_return, }; -struct -probe_spec -{ - probe_spec(Dwarf_Addr a, probe_type ty) - : address(a), type(ty) - {} - Dwarf_Addr address; - probe_type type; - bool operator<(probe_spec const & other) const - { - return ((address < other.address) || - ((address == other.address) && (type < other.type))); - } -}; - struct dwarf_builder; struct dwarf_derived_probe : public derived_probe { - dwarf_derived_probe (probe* p, probe_point* l, - map<string, literal *> const & params); - - static string TOK_PROCESS; - static string TOK_KERNEL; - static string TOK_MODULE; - static string TOK_FUNCTION; - static string TOK_STATEMENT; - static string TOK_CALLEES; - static string TOK_RETURN; - static string TOK_RELATIVE; - static string TOK_LABEL; + dwarf_derived_probe (probe * p, + probe_point * l, + string const & module_name, + dwarf_probe_type type, + Dwarf_Addr addr); + string module_name; + dwarf_probe_type type; + Dwarf_Addr addr; + // Pattern registration helpers. - static void register_relative_variants(match_node & root, + static void register_relative_variants(match_node * root, dwarf_builder * dw); - static void register_statement_variants(match_node & root, + static void register_statement_variants(match_node * root, dwarf_builder * dw); - static void register_callee_variants(match_node & root, + static void register_callee_variants(match_node * root, dwarf_builder * dw); - static void register_function_and_statement_variants(match_node & root, + static void register_function_and_statement_variants(match_node * root, dwarf_builder * dw); - static void register_patterns(match_node & root); + static void register_patterns(match_node * root); + + virtual void emit_registrations (translator_output * o, unsigned i); + virtual void emit_deregistrations (translator_output * o, unsigned i); + virtual void emit_probe_entries (translator_output * o, unsigned i); + virtual ~dwarf_derived_probe() {} +}; + +// Helper struct to thread through the dwfl callbacks. +struct +dwarf_query +{ + dwarf_query(probe * base_probe, + probe_point * base_loc, + dwflpp & dw, + map<string, literal *> const & params, + vector<derived_probe *> & results); // Parameter extractors. static bool has_null_param(map<string, literal *> const & params, @@ -730,63 +522,47 @@ struct dwarf_derived_probe : public derived_probe static bool get_number_param(map<string, literal *> const & params, string const & k, long & v); - // The results of all our hard work go in these vectors. - set<probe_spec> kernel_probes; - map<string, set<probe_spec>*> module_probes; - - void add_kernel_probe(probe_spec const & p); - void add_module_probe(string const & module, probe_spec const & p); - - // Helper struct to thread through the dwfl callbacks. - struct - dwarf_query - { - dwarf_query(dwarf_derived_probe & probe, - dwflpp & d, - map<string, literal *> const & params); - - bool has_kernel; - bool has_process; - bool has_module; - string process_val; - string module_val; - string function_val; - - bool has_function_str; - bool has_statement_str; - bool has_function_num; - bool has_statement_num; - string statement_str_val; - string function_str_val; - long statement_num_val; - long function_num_val; - - bool has_callees; - long callee_val; - - bool has_return; - - bool has_label; - string label_val; - - bool has_relative; - long relative_val; - - function_spec_type parse_function_spec(string & spec); - function_spec_type spec_type; - string function; - string file; - int line; - - - dwarf_derived_probe & probe; - dwflpp & dw; - }; - - virtual void emit_registrations (translator_output* o, unsigned i); - virtual void emit_deregistrations (translator_output* o, unsigned i); - virtual void emit_probe_entries (translator_output* o, unsigned i); - virtual ~dwarf_derived_probe() {} + vector<derived_probe *> & results; + void add_kernel_probe(dwarf_probe_type type, Dwarf_Addr addr); + void add_module_probe(string const & module, + dwarf_probe_type type, Dwarf_Addr addr); + + bool has_kernel; + bool has_process; + bool has_module; + string process_val; + string module_val; + string function_val; + + bool has_function_str; + bool has_statement_str; + bool has_function_num; + bool has_statement_num; + string statement_str_val; + string function_str_val; + long statement_num_val; + long function_num_val; + + bool has_callees; + long callee_val; + + bool has_return; + + bool has_label; + string label_val; + + bool has_relative; + long relative_val; + + function_spec_type parse_function_spec(string & spec); + function_spec_type spec_type; + string function; + string file; + int line; + + probe * base_probe; + probe_point * base_loc; + dwflpp & dw; }; struct @@ -794,18 +570,17 @@ dwarf_builder : public derived_probe_builder { dwarf_builder() {} - virtual derived_probe * build(probe * base, - probe_point * location, - map<string, literal *> const & parameters) - { - return new dwarf_derived_probe(base, location, parameters); - } + virtual void build(probe * base, + probe_point * location, + std::map<std::string, literal *> const & parameters, + vector<probe *> & results_to_expand_further, + vector<derived_probe *> & finished_results); virtual ~dwarf_builder() {} }; bool -dwarf_derived_probe::has_null_param(map<string, literal *> const & params, - string const & k) +dwarf_query::has_null_param(map<string, literal *> const & params, + string const & k) { map<string, literal *>::const_iterator i = params.find(k); if (i != params.end() && i->second == NULL) @@ -814,8 +589,8 @@ dwarf_derived_probe::has_null_param(map<string, literal *> const & params, } bool -dwarf_derived_probe::get_string_param(map<string, literal *> const & params, - string const & k, string & v) +dwarf_query::get_string_param(map<string, literal *> const & params, + string const & k, string & v) { map<string, literal *>::const_iterator i = params.find(k); if (i == params.end()) @@ -828,8 +603,8 @@ dwarf_derived_probe::get_string_param(map<string, literal *> const & params, } bool -dwarf_derived_probe::get_number_param(map<string, literal *> const & params, - string const & k, long & v) +dwarf_query::get_number_param(map<string, literal *> const & params, + string const & k, long & v) { map<string, literal *>::const_iterator i = params.find(k); if (i == params.end()) @@ -844,39 +619,34 @@ dwarf_derived_probe::get_number_param(map<string, literal *> const & params, } void -dwarf_derived_probe::add_kernel_probe(probe_spec const & p) +dwarf_query::add_kernel_probe(dwarf_probe_type type, + Dwarf_Addr addr) { - kernel_probes.insert(p); + results.push_back(new dwarf_derived_probe(base_probe, base_loc, + "", type, addr)); } void -dwarf_derived_probe::add_module_probe(string const & module, - probe_spec const & p) +dwarf_query::add_module_probe(string const & module, + dwarf_probe_type type, + Dwarf_Addr addr) { - set<probe_spec>* specs; - - map<string, set<probe_spec>*>::const_iterator i - = module_probes.find(module); - - if (i == module_probes.end()) - { - specs = new set<probe_spec>(); - module_probes.insert(make_pair(module, specs)); - } - else - { - specs = i->second; - } - specs->insert(p); + results.push_back(new dwarf_derived_probe(base_probe, base_loc, + module, type, addr)); } -dwarf_derived_probe::dwarf_query::dwarf_query(dwarf_derived_probe & probe, - dwflpp & d, - map<string, literal *> const & params) - : probe(probe), - dw(d) +dwarf_query::dwarf_query(probe * base_probe, + probe_point * base_loc, + dwflpp & dw, + map<string, literal *> const & params, + vector<derived_probe *> & results) + : results(results), + base_probe(base_probe), + base_loc(base_loc), + dw(dw) { + // Reduce the query to more reasonable semantic values (booleans, // extracted strings, numbers, etc). @@ -917,10 +687,10 @@ lex_cast(IN const & in) } function_spec_type -dwarf_derived_probe::dwarf_query::parse_function_spec(string & spec) +dwarf_query::parse_function_spec(string & spec) { string::const_iterator i = spec.begin(), e = spec.end(); - + function.clear(); file.clear(); line = 0; @@ -976,41 +746,44 @@ dwarf_derived_probe::dwarf_query::parse_function_spec(string & spec) } bad: - throw semantic_error("malformed specification '" + spec + "'", probe.tok); + throw semantic_error("malformed specification '" + spec + "'", + base_probe->tok); } static void -query_statement(Dwarf_Addr stmt_addr, dwarf_derived_probe::dwarf_query *q) +query_statement(Dwarf_Addr stmt_addr, dwarf_query * q) { // XXX: implement if (q->has_relative) - throw semantic_error("incomplete: do not know how to interpret .relative", q->probe.tok); + throw semantic_error("incomplete: do not know how to interpret .relative", + q->base_probe->tok); - probe_type ty = (((q->has_function_str || q->has_function_num) && q->has_return) - ? probe_function_return - : probe_address); + dwarf_probe_type ty = (((q->has_function_str || q->has_function_num) && q->has_return) + ? probe_function_return + : probe_address); if (q->has_module) - q->probe.add_module_probe(q->dw.module_name, - probe_spec(q->dw.global_address_to_module(stmt_addr), ty)); + q->add_module_probe(q->dw.module_name, + ty, q->dw.global_address_to_module(stmt_addr)); else - q->probe.add_kernel_probe(probe_spec(stmt_addr, ty)); + q->add_kernel_probe(ty, stmt_addr); } static int query_function(Dwarf_Func * func, void * arg) { - dwarf_derived_probe::dwarf_query *q = - static_cast<dwarf_derived_probe::dwarf_query *>(arg); + dwarf_query * q = static_cast<dwarf_query *>(arg); // XXX: implement if (q->has_callees) - throw semantic_error("incomplete: do not know how to interpret .callees", q->probe.tok); + throw semantic_error("incomplete: do not know how to interpret .callees", + q->base_probe->tok); if (q->has_label) - throw semantic_error("incomplete: do not know how to interpret .label", q->probe.tok); + throw semantic_error("incomplete: do not know how to interpret .label", + q->base_probe->tok); q->dw.focus_on_function(func); @@ -1059,8 +832,7 @@ query_function(Dwarf_Func * func, void * arg) static int query_cu (Dwarf_Die * cudie, void * arg) { - dwarf_derived_probe::dwarf_query *q = - static_cast<dwarf_derived_probe::dwarf_query *>(arg); + dwarf_query * q = static_cast<dwarf_query *>(arg); q->dw.focus_on_cu(cudie); @@ -1099,8 +871,7 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)), void *arg __attribute__ ((unused))) { - dwarf_derived_probe::dwarf_query *q = - static_cast<dwarf_derived_probe::dwarf_query *>(arg); + dwarf_query * q = static_cast<dwarf_query *>(arg); q->dw.focus_on_module(mod); @@ -1136,57 +907,20 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)), return DWARF_CB_OK; } -dwarf_derived_probe::dwarf_derived_probe (probe* p, probe_point* l, - map<string, literal *> const & params) - : derived_probe (p, l) +dwarf_derived_probe::dwarf_derived_probe (probe * p, + probe_point * l, + string const & module_name, + dwarf_probe_type type, + Dwarf_Addr addr) + : derived_probe (p, l), + module_name(module_name), + type(type), + addr(addr) { - dwflpp dw; - dwarf_query q(*this, dw, params); - - dw.setup(q.has_kernel || q.has_module); - - if (q.has_kernel && q.has_statement_num) - { - // If we have kernel.statement(0xbeef), the address is global - // (relative to the kernel) and we can seek directly to the - // statement in question. - query_statement(q.statement_num_val, &q); - } - else if (q.has_kernel && q.has_function_num) - { - // If we have kernel.function(0xbeef), the address is global - // (relative to the kernel) and we can seek directly to the - // cudie in question. - dw.focus_on_cu_containing_global_address(q.function_num_val); - dw.iterate_over_functions(&query_function, &q); - } - else - { - // Otherwise we have module("foo"), kernel.statement("foo"), or - // kernel.function("foo"); in these cases we need to scan all - // the modules. - assert((q.has_kernel && q.has_function_str) || - (q.has_kernel && q.has_statement_str) || - (q.has_module)); - dw.iterate_over_modules(&query_module, &q); - } } -string dwarf_derived_probe::TOK_PROCESS("process"); -string dwarf_derived_probe::TOK_KERNEL("kernel"); -string dwarf_derived_probe::TOK_MODULE("module"); - -string dwarf_derived_probe::TOK_FUNCTION("function"); -string dwarf_derived_probe::TOK_RETURN("return"); -string dwarf_derived_probe::TOK_CALLEES("callees"); - -string dwarf_derived_probe::TOK_STATEMENT("statement"); -string dwarf_derived_probe::TOK_LABEL("label"); -string dwarf_derived_probe::TOK_RELATIVE("relative"); - - void -dwarf_derived_probe::register_relative_variants(match_node & root, +dwarf_derived_probe::register_relative_variants(match_node * root, dwarf_builder * dw) { // Here we match 2 forms: @@ -1194,12 +928,12 @@ dwarf_derived_probe::register_relative_variants(match_node & root, // . // .relative(NN) - root.bind(dw); - root.bind_num(TOK_RELATIVE).bind(dw); + root->bind(dw); + root->bind_num(TOK_RELATIVE)->bind(dw); } void -dwarf_derived_probe::register_statement_variants(match_node & root, +dwarf_derived_probe::register_statement_variants(match_node * root, dwarf_builder * dw) { // Here we match 3 forms: @@ -1209,12 +943,12 @@ dwarf_derived_probe::register_statement_variants(match_node & root, // .label("foo") register_relative_variants(root, dw); - register_relative_variants(root.bind(TOK_RETURN), dw); - register_relative_variants(root.bind_str(TOK_LABEL), dw); + register_relative_variants(root->bind(TOK_RETURN), dw); + register_relative_variants(root->bind_str(TOK_LABEL), dw); } void -dwarf_derived_probe::register_callee_variants(match_node & root, +dwarf_derived_probe::register_callee_variants(match_node * root, dwarf_builder * dw) { // Here we match 3 forms: @@ -1227,12 +961,12 @@ dwarf_derived_probe::register_callee_variants(match_node & root, // recursive .callees.callees.callees... pattern-matching on our part. register_statement_variants(root, dw); - register_statement_variants(root.bind(TOK_CALLEES), dw); - register_statement_variants(root.bind_num(TOK_CALLEES), dw); + register_statement_variants(root->bind(TOK_CALLEES), dw); + register_statement_variants(root->bind_num(TOK_CALLEES), dw); } void -dwarf_derived_probe::register_function_and_statement_variants(match_node & root, +dwarf_derived_probe::register_function_and_statement_variants(match_node * root, dwarf_builder * dw) { // Here we match 4 forms: @@ -1242,14 +976,14 @@ dwarf_derived_probe::register_function_and_statement_variants(match_node & root, // .statement("foo") // .statement(0xdeadbeef) - register_callee_variants(root.bind_str(TOK_FUNCTION), dw); - register_callee_variants(root.bind_num(TOK_FUNCTION), dw); - register_statement_variants(root.bind_str(TOK_STATEMENT), dw); - register_statement_variants(root.bind_num(TOK_STATEMENT), dw); + register_callee_variants(root->bind_str(TOK_FUNCTION), dw); + register_callee_variants(root->bind_num(TOK_FUNCTION), dw); + register_statement_variants(root->bind_str(TOK_STATEMENT), dw); + register_statement_variants(root->bind_num(TOK_STATEMENT), dw); } void -dwarf_derived_probe::register_patterns(match_node & root) +dwarf_derived_probe::register_patterns(match_node * root) { dwarf_builder *dw = new dwarf_builder(); @@ -1259,9 +993,9 @@ dwarf_derived_probe::register_patterns(match_node & root) // .module("foo") // .process("foo") - register_function_and_statement_variants(root.bind(TOK_KERNEL), dw); - register_function_and_statement_variants(root.bind_str(TOK_MODULE), dw); - register_function_and_statement_variants(root.bind_str(TOK_PROCESS), dw); + register_function_and_statement_variants(root->bind(TOK_KERNEL), dw); + register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw); + register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw); } static string @@ -1271,228 +1005,63 @@ probe_entry_function_name(unsigned probenum) } static string -probe_entry_struct_kprobe_name(unsigned probenum, - unsigned entrynum) -{ - return "dwarf_kprobe_" + lex_cast<string>(probenum) - + "_entry_" + lex_cast<string>(entrynum); -} - -static string -end_of_block(unsigned probenum) +probe_entry_struct_kprobe_name(unsigned probenum) { - return "block_end_" + lex_cast<string>(probenum); + return "dwarf_kprobe_" + lex_cast<string>(probenum); } -typedef unsigned module_index; -typedef unsigned probe_index; -typedef unsigned entry_index; - -static void -foreach_dwarf_probe_entry(dwarf_derived_probe const & p, - translator_output *o, - probe_index probenum, - void (*kernel_entry_cb)(translator_output *, - probe_index, - entry_index, - probe_spec const &), - void (*module_cb)(translator_output *, - probe_index, - module_index, - string const &), - void (*module_entry_cb)(translator_output *, - probe_index, - string const &, - module_index, - entry_index, - probe_spec const &)) +void +dwarf_derived_probe::emit_registrations (translator_output* o, unsigned probenum) { - // Just a helper function for an ugly iteration task. - - entry_index entrynum = 0; - - for (set<probe_spec>::const_iterator i = p.kernel_probes.begin(); - i != p.kernel_probes.end(); ++i, ++entrynum) + if (module_name.empty()) { - if (kernel_entry_cb) - kernel_entry_cb(o, probenum, entrynum, *i); + o->newline() << probe_entry_struct_kprobe_name(probenum) + << ".addr = 0x" << hex << addr << ";"; + o->newline() << "register_probe (&" + << probe_entry_struct_kprobe_name(probenum) + << ");"; } - - module_index modnum = 0; - - for (map<string, set<probe_spec>*>::const_iterator i = p.module_probes.begin(); - i != p.module_probes.end(); ++i, ++modnum) + else { - string modname = i->first; - set<probe_spec>* probes = i->second; - if (module_cb) - module_cb(o, probenum, modnum, modname); - for (set<probe_spec>::const_iterator j = probes->begin(); - j != probes->end(); ++j, ++entrynum) - { - if (module_entry_cb) - module_entry_cb(o, probenum, modname, modnum, entrynum, *j); - } + o->newline() << "{"; + o->indent(1); + o->newline() << "struct module *mod = get_module(\"" << module_name << "\");"; + o->newline() << "if (!mod)"; + o->indent(1); + o->newline() << "rc++"; + o->indent(-1); + o->newline() << "else"; + o->newline() << "{"; + o->indent(1); + o->newline() << probe_entry_struct_kprobe_name(probenum) + << ".addr = mod->module_core + 0x" << hex << addr << ";"; + o->newline() << "register_probe (&" + << probe_entry_struct_kprobe_name(probenum) + << ");"; + o->indent(-1); + o->newline() << "}"; + o->indent(-1); + o->newline() << "}"; } } - -static void -declare_dwarf_kernel_entry(translator_output *o, - probe_index probenum, - entry_index entrynum, - probe_spec const & probe) -{ - o->newline() << "/* probe for " - << (probe.type == probe_function_return ? "return from " : "") - << "function at 0x" << hex << probe.address << " in kernel */"; - o->newline() << "static struct kprobe " - << probe_entry_struct_kprobe_name(probenum, entrynum); - o->newline() << "{"; - o->indent(1); - o->newline() << ".addr = 0x" << hex << probe.address << ","; - o->newline() << ".pre_handler = &" << probe_entry_function_name(probenum) << ","; - o->indent(-1); - o->newline() << "}"; -} - -static void -register_dwarf_kernel_entry(translator_output *o, - probe_index probenum, - entry_index entrynum, - probe_spec const & probe) -{ - o->newline() << "register_probe (&" - << probe_entry_struct_kprobe_name(probenum, entrynum) - << ");"; -} - -static void -deregister_dwarf_kernel_entry(translator_output *o, - probe_index probenum, - entry_index entrynum, - probe_spec const & probe) -{ - o->newline() << "deregister_probe (&" - << probe_entry_struct_kprobe_name(probenum, entrynum) - << ");"; -} - -static void -register_dwarf_module(translator_output *o, - probe_index probenum, - module_index modnum, - string const & modname) -{ - o->newline() << "mod = get_module(\"" << modname << "\");"; - o->newline() << "if (!mod)"; - o->newline() << "{"; - o->indent(1); - o->newline() << "rc = 1;"; - o->newline() << "goto " << end_of_block(probenum) << ";"; - o->indent(-1); - o->newline() << "}"; - -} - -static void -declare_dwarf_module_entry(translator_output *o, - probe_index probenum, - string const & modname, - module_index modnum, - entry_index entrynum, - probe_spec const & probe) -{ - o->newline(); - o->newline() << "/* probe for " - << (probe.type == probe_function_return ? "return from " : "") - << "function at 0x" << hex << probe.address - << " in module " << modname << " */"; - - o->newline() << "static struct kprobe "; - o->newline() << probe_entry_struct_kprobe_name(probenum, entrynum); - o->newline() << "{"; - o->indent(1); - o->newline() << "/* .addr is calculated at init-time */"; - o->newline() << ".addr = 0,"; - o->newline() << ".pre_handler = &" << probe_entry_function_name(probenum) << ","; - o->indent(-1); - o->newline() << "}"; - o->newline(); -} - -static void -register_dwarf_module_entry(translator_output *o, - probe_index probenum, - string const & modname, - module_index modnum, - entry_index entrynum, - probe_spec const & probe) -{ - o->newline(); - o->newline() << probe_entry_struct_kprobe_name(probenum, entrynum) - << ".addr = mod->module_core + 0x" << hex << probe.address << ";"; - o->newline() << "register_probe (&" - << probe_entry_struct_kprobe_name(probenum, entrynum) - << ");"; -} - -static void -deregister_dwarf_module_entry(translator_output *o, - probe_index probenum, - string const & modname, - module_index modnum, - entry_index entrynum, - probe_spec const & probe) -{ - o->newline() << "deregister_probe (&" - << probe_entry_struct_kprobe_name(probenum, entrynum) - << ");"; -} - - -void -dwarf_derived_probe::emit_registrations (translator_output* o, unsigned probenum) -{ - o->newline() << "{"; - o->indent(1); - o->newline() << "struct module *mod = NULL;"; - foreach_dwarf_probe_entry(*this, o, probenum, - ®ister_dwarf_kernel_entry, - ®ister_dwarf_module, - ®ister_dwarf_module_entry); - o->newline(); - o->newline() << end_of_block(probenum) << ":"; - o->newline(); - o->indent(-1); - o->newline() << "}"; -} - void dwarf_derived_probe::emit_deregistrations (translator_output* o, unsigned probenum) { o->newline(); - foreach_dwarf_probe_entry(*this, o, probenum, - &deregister_dwarf_kernel_entry, - NULL, - &deregister_dwarf_module_entry); - o->newline(); + o->newline() << "deregister_probe (&" + << probe_entry_struct_kprobe_name(probenum) + << ");"; } void dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum) { - // We should have expanded each location in the initial probe to a - // separate derived_probe instance; each derived_probe should only - // have one location. - assert(locations.size() == 1); - // Construct a single entry function, and a struct kprobe for each - // address this derived probe will match, all of which point into - // the entry function. + // Construct a single entry function, and a struct kprobe pointing into + // the entry function. The entry function will call the probe function. - // First the entry function - o->newline() << "/* probe " << probenum << " entry function */"; + o->newline(); o->newline() << "static void "; o->newline() << probe_entry_function_name(probenum) << " ()"; o->newline() << "{"; @@ -1507,11 +1076,57 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum o->newline() << "c->busy --;"; o->newline(-1) << "}" << endl; - foreach_dwarf_probe_entry(*this, o, probenum, - &declare_dwarf_kernel_entry, - NULL, - &declare_dwarf_module_entry); + o->newline(); + o->newline() << "static struct kprobe " + << probe_entry_struct_kprobe_name(probenum); + o->newline() << "{"; + o->indent(1); + o->newline() << ".addr = 0x0, /* filled in during module init */" ; + o->newline() << ".pre_handler = &" << probe_entry_function_name(probenum) << ","; + o->indent(-1); + o->newline() << "}"; + o->newline(); +} + +void +dwarf_builder::build(probe * base, + probe_point * location, + std::map<std::string, literal *> const & parameters, + vector<probe *> & results_to_expand_further, + vector<derived_probe *> & finished_results) +{ + + dwflpp dw; + dwarf_query q(base, location, dw, parameters, finished_results); + + dw.setup(q.has_kernel || q.has_module); + + if (q.has_kernel && q.has_statement_num) + { + // If we have kernel.statement(0xbeef), the address is global + // (relative to the kernel) and we can seek directly to the + // statement in question. + query_statement(q.statement_num_val, &q); + } + else if (q.has_kernel && q.has_function_num) + { + // If we have kernel.function(0xbeef), the address is global + // (relative to the kernel) and we can seek directly to the + // cudie in question. + dw.focus_on_cu_containing_global_address(q.function_num_val); + dw.iterate_over_functions(&query_function, &q); + } + else + { + // Otherwise we have module("foo"), kernel.statement("foo"), or + // kernel.function("foo"); in these cases we need to scan all + // the modules. + assert((q.has_kernel && q.has_function_str) || + (q.has_kernel && q.has_statement_str) || + (q.has_module)); + dw.iterate_over_modules(&query_module, &q); + } } #endif /* HAVE_ELFUTILS_LIBDWFL_H */ @@ -1522,11 +1137,11 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum // ------------------------------------------------------------------------ void -register_standard_tapsets(match_node & root) +register_standard_tapsets(match_node * root) { // Rudimentary binders for begin and end targets - root.bind("begin").bind(new be_builder(true)); - root.bind("end").bind(new be_builder(false)); + root->bind("begin")->bind(new be_builder(true)); + root->bind("end")->bind(new be_builder(false)); #ifdef HAVE_ELFUTILS_LIBDWFL_H dwarf_derived_probe::register_patterns(root); @@ -12,61 +12,9 @@ #include "config.h" #include "staptree.h" #include "elaborate.h" -#include "translate.h" -#include <iostream> -#include <sstream> -#include <vector> -#include <map> - -struct -derived_probe_builder -{ - virtual derived_probe * build(probe * base, - probe_point * location, - std::map<std::string, literal *> const & parameters) = 0; - virtual ~derived_probe_builder() {} -}; - - -struct -match_key -{ - std::string name; - bool have_parameter; - token_type parameter_type; - - match_key(std::string const & n); - match_key(probe_point::component const & c); - - match_key & with_number(); - match_key & with_string(); - std::string str() const; - bool operator<(match_key const & other) const; -}; - - -class -match_node -{ - std::map<match_key, match_node *> sub; - derived_probe_builder * end; - - public: - match_node(); - derived_probe_builder * find_builder(std::vector<probe_point::component *> const & components, - unsigned pos, - std::vector< std::pair<std::string, literal *> > & parameters); - - match_node & bind(match_key const & k); - match_node & bind(std::string const & k); - match_node & bind_str(std::string const & k); - match_node & bind_num(std::string const & k); - void bind(derived_probe_builder * e); -}; - void -register_standard_tapsets(match_node & root); +register_standard_tapsets(match_node * root); #endif // TAPSETS_H |