summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroland <roland>2006-06-27 21:20:47 +0000
committerroland <roland>2006-06-27 21:20:47 +0000
commite38d6504b909da172c5c4a5f8730bcee4bf62389 (patch)
tree6d29b3cdd33dda78c139f01e3506ac87e0f6cec1
parentcdec6e886e20a034d610ac34a9fdf7f77fee1b23 (diff)
downloadsystemtap-steved-e38d6504b909da172c5c4a5f8730bcee4bf62389.tar.gz
systemtap-steved-e38d6504b909da172c5c4a5f8730bcee4bf62389.tar.xz
systemtap-steved-e38d6504b909da172c5c4a5f8730bcee4bf62389.zip
2006-06-27 Roland McGrath <roland@redhat.com>
* tapsets.cxx (dwflpp::emit_address): New instance method. Get relocation details from Dwfl to emit in comment after address constant. (dwflpp::loc2c_emit_address): Just call that.
-rw-r--r--tapsets.cxx132
1 files changed, 81 insertions, 51 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 92655070..116464c4 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -133,7 +133,7 @@ derived_probe::emit_common_header (translator_output* o)
o->newline() << "_stp_exit ();";
o->newline(-1) << "}";
o->newline(-1) << "}";
-
+
o->newline() << "atomic_dec (&c->busy);";
o->newline(-1) << "}";
}
@@ -146,7 +146,7 @@ derived_probe::emit_probe_prologue (translator_output* o,
o->newline() << "struct context* c;";
o->newline() << "unsigned long flags;";
- // NB: this cycles_t stuff might go into the common header block above
+ // NB: this cycles_t stuff might go into the common header block above
o->newline() << "#ifdef STP_TIMING";
o->newline() << "cycles_t cycles_atstart;";
o->newline() << "#endif";
@@ -387,7 +387,7 @@ symbol_cache
void make_entry_for_function(Dwarf_Die *func_die);
static int function_callback(Dwarf_Die * func, void * arg);
void index_module(Dwarf * mod);
-public:
+public:
void select_die_subsets(Dwarf * mod,
string const & pattern,
set<Dwarf_Die> & cus,
@@ -433,7 +433,7 @@ symbol_cache::index_module(Dwarf *module_dwarf)
}
inline bool
-operator<(Dwarf_Die const & a,
+operator<(Dwarf_Die const & a,
Dwarf_Die const & b)
{
return (a.addr < b.addr)
@@ -442,13 +442,13 @@ operator<(Dwarf_Die const & a,
}
inline bool
-operator==(Dwarf_Die const & a,
+operator==(Dwarf_Die const & a,
Dwarf_Die const & b)
{
return !((a < b) || (b < a));
}
-void
+void
symbol_cache::select_die_subsets(Dwarf *mod,
string const & pattern,
set<Dwarf_Die> & cus,
@@ -464,7 +464,7 @@ symbol_cache::select_die_subsets(Dwarf *mod,
if (i == indices.end())
{
this->curr_index = new index;
- index_module(mod);
+ index_module(mod);
indices.insert(make_pair(mod, this->curr_index));
ix = this->curr_index;
this->curr_index = NULL;
@@ -490,7 +490,7 @@ symbol_cache::select_die_subsets(Dwarf *mod,
// Now perform a lower-bound on the multimap, refine that result
// set, and copy the CU and function DIEs into the parameter sets.
index::const_iterator j = stem.empty() ? ix->begin() : ix->lower_bound(stem);
- while (j != ix->end() &&
+ while (j != ix->end() &&
(stem.empty() || j->first.compare(0, stem.size(), stem) == 0))
{
if (fnmatch(pattern.c_str(), j->first.c_str(), 0) == 0)
@@ -498,10 +498,10 @@ symbol_cache::select_die_subsets(Dwarf *mod,
cus.insert(j->second.cu);
funcs.insert(make_pair(j->second.cu, j->second.function));
}
- ++j;
+ ++j;
}
}
-
+
static int
@@ -583,8 +583,8 @@ dwflpp
void limit_search_to_function_pattern(string const & pattern)
{
get_module_dwarf(true);
- cache.select_die_subsets(module_dwarf, pattern,
- pattern_limited_cus,
+ cache.select_die_subsets(module_dwarf, pattern,
+ pattern_limited_cus,
pattern_limited_funcs);
}
@@ -604,7 +604,7 @@ dwflpp
pattern_limited_cus.clear();
pattern_limited_funcs.clear();
-
+
cu_name.clear();
cu = NULL;
@@ -1020,11 +1020,11 @@ dwflpp
Dwarf_Addr entrypc = it->first;
Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
func_info* func = &it->second;
- dwfl_assert ("dwarf_highpc", dwarf_highpc (& func->die,
+ dwfl_assert ("dwarf_highpc", dwarf_highpc (& func->die,
& highpc));
if (func->decl_file == 0) func->decl_file = "";
-
+
unsigned entrypc_srcline_idx = 0;
Dwarf_Line* entrypc_srcline = 0;
// open-code binary search for exact match
@@ -1040,10 +1040,10 @@ dwflpp
else if (l + 1 == h) { break; } // ran off bottom of tree
else if (addr < entrypc) { l = entrypc_srcline_idx; }
else { h = entrypc_srcline_idx; }
- }
+ }
}
- if (entrypc_srcline == 0)
- throw semantic_error ("missing entrypc dwarf line record for function '"
+ if (entrypc_srcline == 0)
+ throw semantic_error ("missing entrypc dwarf line record for function '"
+ func->name + "'");
if (sess.verbose>2)
@@ -1080,9 +1080,9 @@ dwflpp
<< "@" << postprologue_file << ":" << postprologue_lineno << "\n";
if (postprologue_addr >= highpc)
- {
- ranoff_end = true;
- postprologue_srcline_idx --;
+ {
+ ranoff_end = true;
+ postprologue_srcline_idx --;
continue;
}
if (ranoff_end ||
@@ -1102,7 +1102,7 @@ dwflpp
break;
}
-
+
// Let's try the next srcline.
postprologue_srcline_idx ++;
} // loop over srclines
@@ -1168,14 +1168,44 @@ dwflpp
throw semantic_error (msg);
}
+ void emit_address (struct obstack *pool, Dwarf_Addr address)
+ {
+ // For now what we actually use is just a hard-wired constant.
+ obstack_printf (pool, "%#" PRIx64 "UL", address);
+
+ // Turn this address into a section-relative offset if it should be one.
+ // We emit a comment approximating the variable+offset expression that
+ // relocatable module probing code will need to have.
+ Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
+ dwfl_assert ("dwfl_addrmodule", mod == NULL);
+ int n = dwfl_module_relocations (mod);
+ dwfl_assert ("dwfl_module_relocations", n < 0);
+ if (n > 0)
+ {
+ int i = dwfl_module_relocate_address (mod, &address);
+ dwfl_assert ("dwfl_module_relocate_address", i < 0);
+ const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+ dwfl_assert ("dwfl_module_info", modname == NULL);
+ const char *secname = dwfl_module_relocation_info (mod, i, NULL);
+ dwfl_assert ("dwfl_module_relocation_info", secname == NULL);
+ if (n > 1 || secname[0] != '\0')
+ // This gives us the module name, and section name within the
+ // module, for a kernel module (or other ET_REL module object).
+ obstack_printf (pool, " /* %s(%s)+%#" PRIx64 " */",
+ modname, secname, address);
+ else
+ // This would happen for a Dwfl_Module that's a user-level DSO.
+ obstack_printf (pool, " /* %s+%#" PRIx64 " */",
+ modname, address);
+ }
+ }
static void loc2c_emit_address (void *arg, struct obstack *pool,
Dwarf_Addr address)
{
dwflpp *dwfl = (dwflpp *) arg;
- obstack_printf (pool, "%#" PRIx64 "UL /* hard-coded %s address */",
- address, dwfl_module_info (dwfl->module, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL));
+ dwfl->emit_address (pool, address);
}
Dwarf_Attribute *
@@ -1806,16 +1836,16 @@ dwarf_query
struct dwarf_builder: public derived_probe_builder
{
- dwflpp *kern_dw;
- dwflpp *user_dw;
- dwarf_builder()
- : kern_dw(NULL), user_dw(NULL)
+ dwflpp *kern_dw;
+ dwflpp *user_dw;
+ dwarf_builder()
+ : kern_dw(NULL), user_dw(NULL)
{}
- ~dwarf_builder()
- {
- if (kern_dw)
+ ~dwarf_builder()
+ {
+ if (kern_dw)
delete kern_dw;
- if (user_dw)
+ if (user_dw)
delete user_dw;
}
virtual void build(systemtap_session & sess,
@@ -2061,12 +2091,12 @@ target_variable_flavour_calculating_visitor::visit_target_symbol (target_symbol
// or is illegally used (write in non-guru mode for instance),
// just pretend that it's OK anyway. dwarf_var_expanding_copy_visitor
// will take care of throwing the appropriate exception.
-
+
bool lvalue = is_active_lvalue(e);
flavour += lvalue ? 'w' : 'r';
exp_type ty;
string expr;
- try
+ try
{
if (q.has_return && e->base_name == "$return")
expr = q.dw.literal_stmt_for_return (scope_die,
@@ -2086,7 +2116,7 @@ target_variable_flavour_calculating_visitor::visit_target_symbol (target_symbol
{
ty = pe_unknown;
}
-
+
switch (ty)
{
case pe_unknown:
@@ -2658,7 +2688,7 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)),
dwarf_query * q = static_cast<dwarf_query *>(arg);
try
- {
+ {
q->dw.focus_on_module(mod);
// If we have enough information in the pattern to skip a module and
@@ -2704,7 +2734,7 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)),
// Otherwise if we have a function("foo") or statement("foo")
// specifier, we have to scan over all the CUs looking for
// the function(s) in question
-
+
q->dw.limit_search_to_function_pattern(q->function);
assert(q->has_function_str || q->has_inline_str || q->has_statement_str);
@@ -3144,7 +3174,7 @@ dwarf_derived_probe::emit_registrations (translator_output* o)
}
o->newline() << "if (unlikely (rc)) {";
- o->newline(1) << "probe_point = " << string("dwarf_kprobe_") + name
+ o->newline(1) << "probe_point = " << string("dwarf_kprobe_") + name
+ string("_location_names[i];");
o->newline() << "break;";
o->newline(-1) << "}";
@@ -3752,15 +3782,15 @@ mark_derived_probe::mark_derived_probe (systemtap_session &s,
{
if (i > 0)
probe_sig_expanded += ", ";
- switch (probe_sig[i])
+ switch (probe_sig[i])
{
case 'N': probe_sig_expanded += "int64_t"; break;
case 'S': probe_sig_expanded += "const char *"; break;
- default:
+ default:
throw semantic_error ("unsupported probe signature " + probe_sig,
this->tok);
}
- probe_sig_expanded += " arg" + lex_cast<string>(i+1); // arg1 ...
+ probe_sig_expanded += " arg" + lex_cast<string>(i+1); // arg1 ...
}
// Now make a local-variable-expanded copy of the probe body
@@ -3780,7 +3810,7 @@ mark_derived_probe::emit_probe_context_vars (translator_output* o)
for (unsigned i=0; i<probe_sig.length(); i++)
{
string localname = "__mark_arg" + lex_cast<string>(i+1);
- switch (probe_sig[i])
+ switch (probe_sig[i])
{
case 'S': o->newline() << "string_t " << localname << ";"; break;
case 'N': o->newline() << "int64_t " << localname << ";"; break;
@@ -3806,11 +3836,11 @@ mark_derived_probe::emit_probe_entries (translator_output* o)
string locals = "c->locals[0]." + name;
string localname = locals + ".__mark_arg" + lex_cast<string>(k+1);
string argname = "arg" + lex_cast<string>(k+1);
- switch (probe_sig[k])
+ switch (probe_sig[k])
{
case 'S': o->newline() << "strlcpy (" << localname << ", " << argname
<< ", MAXSTRINGLEN);"; break;
- // XXX: dupe with c_unparser::c_strcpy
+ // XXX: dupe with c_unparser::c_strcpy
case 'N': o->newline() << localname << " = " << argname << ";"; break;
}
}
@@ -3845,7 +3875,7 @@ mark_derived_probe::emit_registrations (translator_output * o)
o->newline() << "if (*fn != & enter_" << name << ") rc = 1;";
o->newline(-1) << "}";
-
+
}
@@ -4013,16 +4043,16 @@ mark_builder::build(systemtap_session & sess,
(match[2].rm_eo - match[2].rm_so));
// Below, "rc" has negative polarity: zero iff matching
- rc = (has_module
+ rc = (has_module
? fnmatch (param_module.c_str(), ext.module.c_str(), 0)
: (ext.module != "")); // kernel.*
rc |= fnmatch (param_probe.c_str(), probe_name.c_str(), 0);
-
+
if (! rc)
{
// cout << "match (" << probe_name << "):" << probe_sig << endl;
- derived_probe *dp
+ derived_probe *dp
= new mark_derived_probe (sess,
probe_name, probe_sig,
ext.address,
@@ -4094,7 +4124,7 @@ hrtimer_derived_probe::emit_interval (translator_output* o)
o->newline(1) << "unsigned long nsecs;";
o->newline() << "int64_t i = " << interval << "LL;";
if (randomize != 0)
- {
+ {
o->newline() << "int64_t r;";
o->newline() << "get_random_bytes(&r, sizeof(r));";
o->newline() << "r &= ((uint64_t)1 << (8*sizeof(r) - 1)) - 1;";
@@ -4209,7 +4239,7 @@ struct hrtimer_builder: public derived_probe_builder
clog << "rounded timer randomization from "
<< i_ns << " ns to " << i_ms <<" ms. "<< endl;
}
-
+
finished_results.push_back(
new timer_derived_probe(base, location, i_ms, r_ms, true));
}