summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-09-11 14:58:50 -0700
committerJosh Stone <jistone@redhat.com>2009-09-11 15:37:47 -0700
commit6b66b9f7f81a45d8ecce987dc4436efc1b94fad4 (patch)
tree28d5bbdbe11415dbac09cb374df84ec77b38ddaa
parent4f46087f18da349f124d7fd28721cd274b7176d1 (diff)
downloadsystemtap-steved-6b66b9f7f81a45d8ecce987dc4436efc1b94fad4.tar.gz
systemtap-steved-6b66b9f7f81a45d8ecce987dc4436efc1b94fad4.tar.xz
systemtap-steved-6b66b9f7f81a45d8ecce987dc4436efc1b94fad4.zip
Remove duplicate uprobe_derived_probe code
Much of uprobe_derived_probe is a straight copy of dwarf_derived_probe, and some of the comments even acknowledge this. I'm instead making this an inheritance, so the duplication can be chopped away. * tapsets.cxx (struct dwarf_derived_probe): Reorganize for inheritance. (dwarf_derived_probe::dwarf_derived_probe): Adapt to handle process. (struct uprobe_derived_probe): Inherit from dwarf_derived_probe and remove duplicate members and methods. (uprobe_derived_probe::emit_module_decls): Member name changes.
-rw-r--r--tapsets.cxx266
1 files changed, 47 insertions, 219 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index deb1e795..af709863 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -351,11 +351,8 @@ struct dwarf_derived_probe: public derived_probe
bool access_vars;
void printsig (std::ostream &o) const;
- void join_group (systemtap_session& s);
+ virtual void join_group (systemtap_session& s);
void emit_probe_local_init(translator_output * o);
-
- string args;
- void saveargs(dwarf_query& q, Dwarf_Die* scope_die);
void printargs(std::ostream &o) const;
// Pattern registration helpers.
@@ -369,42 +366,48 @@ struct dwarf_derived_probe: public derived_probe
dwarf_builder * dw,
bool unprivileged_ok_p = false);
static void register_patterns(systemtap_session& s);
+
+protected:
+ dwarf_derived_probe(probe *base,
+ probe_point *location,
+ Dwarf_Addr addr,
+ bool has_return):
+ derived_probe(base, location), addr(addr), has_return(has_return),
+ has_maxactive(0), maxactive_val(0), access_vars(false)
+ {}
+
+private:
+ string args;
+ void saveargs(dwarf_query& q, Dwarf_Die* scope_die);
};
-struct uprobe_derived_probe: public derived_probe
+struct uprobe_derived_probe: public dwarf_derived_probe
{
- bool return_p;
- string module; // * => unrestricted
int pid; // 0 => unrestricted
- string section; // empty => absolute address
- Dwarf_Addr address;
- // bool has_maxactive;
- // long maxactive_val;
uprobe_derived_probe (const string& function,
const string& filename,
int line,
const string& module,
- int pid,
const string& section,
Dwarf_Addr dwfl_addr,
Dwarf_Addr addr,
dwarf_query & q,
- Dwarf_Die* scope_die);
+ Dwarf_Die* scope_die):
+ dwarf_derived_probe(function, filename, line, module, section,
+ dwfl_addr, addr, q, scope_die), pid(0)
+ {}
// alternate constructor for process(PID).statement(ADDR).absolute
uprobe_derived_probe (probe *base,
probe_point *location,
int pid,
Dwarf_Addr addr,
- bool return_p);
-
- string args;
- void saveargs(dwarf_query& q, Dwarf_Die* scope_die);
- void printargs(std::ostream &o) const;
+ bool has_return):
+ dwarf_derived_probe(base, location, addr, has_return), pid(pid)
+ {}
- void printsig (std::ostream &o) const;
void join_group (systemtap_session& s);
};
@@ -1003,7 +1006,7 @@ dwarf_query::add_probe_point(const string& funcname,
if (has_process)
{
results.push_back (new uprobe_derived_probe(funcname, filename, line,
- module, 0, reloc_section, addr, reloc_addr,
+ module, reloc_section, addr, reloc_addr,
*this, scope_die));
}
else
@@ -2730,16 +2733,25 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
module (module), section (section), addr (addr),
has_return (q.has_return),
has_maxactive (q.has_maxactive),
- maxactive_val (q.maxactive_val)
+ maxactive_val (q.maxactive_val),
+ access_vars(false)
{
- // Assert relocation invariants
- if (section == "" && dwfl_addr != addr) // addr should be absolute
- throw semantic_error ("missing relocation base against", q.base_loc->tok);
- if (section != "" && dwfl_addr == addr) // addr should be an offset
- throw semantic_error ("inconsistent relocation address", q.base_loc->tok);
-
- this->tok = q.base_probe->tok;
- this->access_vars = false;
+ if (q.has_process)
+ {
+ // We may receive probes on two types of ELF objects: ET_EXEC or ET_DYN.
+ // ET_EXEC ones need no further relocation on the addr(==dwfl_addr), whereas
+ // ET_DYN ones do (addr += run-time mmap base address). We tell these apart
+ // by the incoming section value (".absolute" vs. ".dynamic").
+ // XXX Assert invariants here too?
+ }
+ else
+ {
+ // Assert kernel relocation invariants
+ if (section == "" && dwfl_addr != addr) // addr should be absolute
+ throw semantic_error ("missing relocation base against", tok);
+ if (section != "" && dwfl_addr == addr) // addr should be an offset
+ throw semantic_error ("inconsistent relocation address", tok);
+ }
// XXX: hack for strange g++/gcc's
#ifndef USHRT_MAX
@@ -2747,7 +2759,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
#endif
// Range limit maxactive() value
- if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX))
+ if (has_maxactive && (maxactive_val < 0 || maxactive_val > USHRT_MAX))
throw semantic_error ("maxactive value out of range [0,"
+ lex_cast(USHRT_MAX) + "]",
q.base_loc->tok);
@@ -2755,9 +2767,11 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
// Expand target variables in the probe body
if (!null_die(scope_die))
{
+ // XXX: user-space deref's for q.has_process!
dwarf_var_expanding_visitor v (q, scope_die, dwfl_addr);
v.replace (this->body);
- this->access_vars = v.visited;
+ if (!q.has_process)
+ access_vars = v.visited;
// If during target-variable-expanding the probe, we added a new block
// of code, add it to the start of the probe.
@@ -4217,192 +4231,6 @@ public:
};
-uprobe_derived_probe::uprobe_derived_probe (const string& function,
- const string& filename,
- int line,
- const string& module,
- int pid,
- const string& section,
- Dwarf_Addr dwfl_addr,
- Dwarf_Addr addr,
- dwarf_query & q,
- Dwarf_Die* scope_die /* may be null */):
- derived_probe (q.base_probe, new probe_point (*q.base_loc) /* .components soon rewritten */ ),
- return_p (q.has_return), module (module), pid (pid), section (section), address (addr)
-{
- // We may receive probes on two types of ELF objects: ET_EXEC or ET_DYN.
- // ET_EXEC ones need no further relocation on the addr(==dwfl_addr), whereas
- // ET_DYN ones do (addr += run-time mmap base address). We tell these apart
- // by the incoming section value (".absolute" vs. ".dynamic").
-
- this->tok = q.base_probe->tok;
-
- // Expand target variables in the probe body
- if (!null_die(scope_die))
- {
- dwarf_var_expanding_visitor v (q, scope_die, dwfl_addr); // XXX: user-space deref's!
- v.replace (this->body);
-
- // If during target-variable-expanding the probe, we added a new block
- // of code, add it to the start of the probe.
- if (v.add_block)
- this->body = new block(v.add_block, this->body);
-
- // If when target-variable-expanding the probe, we added a new
- // probe, add it in a new file to the list of files to be processed.
- if (v.add_probe)
- {
- stapfile *f = new stapfile;
- f->probes.push_back(v.add_probe);
- q.sess.files.push_back(f);
- }
- }
- // else - null scope_die - $target variables will produce an error during translate phase
-
- // Save the local variables for listing mode
- if (q.sess.listing_mode_vars)
- saveargs(q, scope_die);
-
- // Reset the sole element of the "locations" vector as a
- // "reverse-engineered" form of the incoming (q.base_loc) probe
- // point. This allows a user to see what function / file / line
- // number any particular match of the wildcards.
-
- vector<probe_point::component*> comps;
- if(q.has_process)
- comps.push_back (new probe_point::component(TOK_PROCESS, new literal_string(module)));
- else
- assert (0);
-
- string fn_or_stmt;
- if (q.has_function_str || q.has_function_num)
- fn_or_stmt = "function";
- else
- fn_or_stmt = "statement";
-
- if (q.has_function_str || q.has_statement_str)
- {
- string retro_name = function;
- if (filename != "")
- {
- retro_name += ("@" + string (filename));
- if (line > 0)
- retro_name += (":" + lex_cast (line));
- }
- comps.push_back
- (new probe_point::component
- (fn_or_stmt, new literal_string (retro_name)));
- }
- else if (q.has_function_num || q.has_statement_num)
- {
- Dwarf_Addr retro_addr;
- if (q.has_function_num)
- retro_addr = q.function_num_val;
- else
- retro_addr = q.statement_num_val;
- comps.push_back (new probe_point::component
- (fn_or_stmt,
- new literal_number(retro_addr))); // XXX: should be hex if possible
-
- if (q.has_absolute)
- comps.push_back (new probe_point::component (TOK_ABSOLUTE));
- }
-
- if (q.has_call)
- comps.push_back (new probe_point::component(TOK_CALL));
- if (q.has_inline)
- comps.push_back (new probe_point::component(TOK_INLINE));
- if (return_p)
- comps.push_back (new probe_point::component(TOK_RETURN));
- /*
- if (has_maxactive)
- comps.push_back (new probe_point::component
- (TOK_MAXACTIVE, new literal_number(maxactive_val)));
- */
-
- // Overwrite it.
- this->sole_location()->components = comps;
-}
-
-
-uprobe_derived_probe::uprobe_derived_probe (probe *base,
- probe_point *location,
- int pid,
- Dwarf_Addr addr,
- bool has_return):
- derived_probe (base, location), // location is not rewritten here
- return_p (has_return), pid (pid), address (addr)
-{
-}
-
-
-void
-uprobe_derived_probe::saveargs(dwarf_query& q, Dwarf_Die* scope_die)
-{
- // same as dwarf_derived_probe::saveargs
-
- if (null_die(scope_die))
- return;
-
- stringstream argstream;
- string type_name;
- Dwarf_Die type_die;
-
- if (return_p &&
- dwarf_attr_die (scope_die, DW_AT_type, &type_die) &&
- dwarf_type_name(&type_die, type_name))
- argstream << " $return:" << type_name;
-
- Dwarf_Die arg;
- vector<Dwarf_Die> scopes = q.dw.getscopes_die(scope_die);
- if (dwarf_child (&scopes[0], &arg) == 0)
- do
- {
- switch (dwarf_tag (&arg))
- {
- case DW_TAG_variable:
- case DW_TAG_formal_parameter:
- break;
-
- default:
- continue;
- }
-
- const char *arg_name = dwarf_diename (&arg);
- if (!arg_name)
- continue;
-
- type_name.clear();
- if (!dwarf_attr_die (&arg, DW_AT_type, &type_die) ||
- !dwarf_type_name(&type_die, type_name))
- continue;
-
- argstream << " $" << arg_name << ":" << type_name;
- }
- while (dwarf_siblingof (&arg, &arg) == 0);
-
- args = argstream.str();
-}
-
-
-void
-uprobe_derived_probe::printargs(std::ostream &o) const
-{
- // same as dwarf_derived_probe::printargs
- o << args;
-}
-
-
-void
-uprobe_derived_probe::printsig (ostream& o) const
-{
- // Same as dwarf_derived_probe.
- sole_location()->print (o);
- o << " /* pc=" << section << "+0x" << hex << address << dec << " */";
- printsig_nested (o);
-}
-
-
void
uprobe_derived_probe::join_group (systemtap_session& s)
{
@@ -4550,10 +4378,10 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
string key = make_pbm_key (p);
unsigned value = module_index[key];
s.op->line() << " .tfi=" << value << ",";
- s.op->line() << " .address=(unsigned long)0x" << hex << p->address << dec << "ULL,";
+ s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
s.op->line() << " .ph=&" << p->name << ",";
- if (p->return_p) s.op->line() << " .return_p=1,";
+ if (p->has_return) s.op->line() << " .return_p=1,";
s.op->line() << " },";
}
s.op->newline(-1) << "};";