summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--NEWS16
-rw-r--r--elaborate.cxx2
-rw-r--r--parse.cxx4
-rw-r--r--runtime/ChangeLog5
-rw-r--r--runtime/sym.c4
-rw-r--r--stapprobes.5.in6
-rw-r--r--staptree.h3
-rw-r--r--tapsets.cxx74
-rw-r--r--testsuite/ChangeLog8
-rwxr-xr-xtestsuite/buildok/twentyeight.stp3
-rwxr-xr-xtestsuite/semko/thirtyeight.stp3
-rwxr-xr-xtestsuite/semko/thirtyseven.stp3
-rw-r--r--testsuite/systemtap.base/probefunc.exp6
14 files changed, 123 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index ac5073e1..0d2a8732 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2007-03-22 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 4224.
+ * staptree.h (probe): Add privileged field.
+ * elaborate.cxx, parse.cxx: Pass privileged flag to probes.
+ * tapsets.cxx (dwarf_query): Add has_absolute field.
+ (dwarf_derived_probe ctor): Tolerate it.
+ (register_patterns): Expose it.
+ (dwarf_builder::build): Implement it with no dwfl whatsoever.
+ * NEWS: Document kernel.statement().absolute.
+ * stapprobes.5.in: Ditto.
+
2007-03-21 Will Cohen <wcohen@redhat.com>
* Makefile.am:
diff --git a/NEWS b/NEWS
index a3d705d6..9347675c 100644
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,22 @@
preemption disabled). This will allow begin/end probes to be
longer, to support generating longer reports.
+- The numeric forms of kernel.statement() and kernel.function() probe points
+ are now interpreted as relocatable values - treated as relative to the
+ _stext symbol in that kernel binary. Since some modern kernel images
+ are relocated to a different virtual address at startup, such addresses
+ may shift up or down when actually inserted into a running kernel.
+
+ kernel.statement(0xdeadbeef): validated, interpreted relative to _stext,
+ may map to 0xceadbeef at run time.
+
+ In order to specify unrelocated addresses, use the new ".absolute"
+ probe point suffix for such numeric addresses. These are only
+ allowed in guru mode, and provide access to no $target variables.
+ They don't use debugging information at all, actually.
+
+ kernel.statement(0xfeedface).absolute: raw, unvalidated, guru mode only
+
* What's new since version 0.5.10?
- Offline processing of debugging information, enabling general
diff --git a/elaborate.cxx b/elaborate.cxx
index c2e57856..04eb1fa2 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -41,6 +41,7 @@ derived_probe::derived_probe (probe *p):
{
this->locations = p->locations;
this->tok = p->tok;
+ this->privileged = p->privileged;
this->body = deep_copy_visitor::deep_copy(p->body);
}
}
@@ -55,6 +56,7 @@ derived_probe::derived_probe (probe *p, probe_point *l):
if (p)
{
this->tok = p->tok;
+ this->privileged = p->privileged;
this->body = deep_copy_visitor::deep_copy(p->body);
}
}
diff --git a/parse.cxx b/parse.cxx
index 5674daa8..41784430 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1,5 +1,5 @@
// recursive descent parser for systemtap scripts
-// Copyright (C) 2005-2006 Red Hat Inc.
+// Copyright (C) 2005-2007 Red Hat Inc.
// Copyright (C) 2006 Intel Corporation.
//
// This file is part of systemtap, and is free software. You can
@@ -899,6 +899,7 @@ parser::parse_probe (std::vector<probe *> & probe_ret,
p->tok = t0;
p->locations = locations;
p->body = parse_stmt_block ();
+ p->privileged = privileged;
probe_ret.push_back (p);
}
else
@@ -911,6 +912,7 @@ parser::parse_probe (std::vector<probe *> & probe_ret,
p->tok = t0;
p->locations = locations;
p->body = parse_stmt_block ();
+ p->privileged = privileged;
alias_ret.push_back (p);
}
}
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 96471c74..427c804d 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,7 @@
+2007-03-22 Frank Ch. Eigler <fche@elastic.org>
+
+ * sym.c (_stp_module_relocate): Tolerate empty section string.
+
2007-03-21 Martin Hunt <hunt@redhat.com>
* sym.h: Declare _stp_module_relocate.
@@ -8,6 +12,7 @@
(_stp_symbol_snprint): Ditto.
2007-03-21 Martin Hunt <hunt@redhat.com>
+
* map.c (_stp_map_init): Fix signed vs unsigned comparison warning.
2007-03-20 Frank Ch. Eigler <fche@elastic.org>
diff --git a/runtime/sym.c b/runtime/sym.c
index a461157e..8d344b4a 100644
--- a/runtime/sym.c
+++ b/runtime/sym.c
@@ -35,7 +35,9 @@ unsigned long _stp_module_relocate (const char *module, const char *section, uns
dbug("_stp_relocate_module: %s, %s, %lx\n", module, section, offset);
STP_LOCK_MODULES;
- if (! module || _stp_num_modules == 0) {
+ if (! module
+ || !strcmp (section, "") /* absolute, unrelocated address */
+ || _stp_num_modules == 0) {
STP_UNLOCK_MODULES;
return offset;
}
diff --git a/stapprobes.5.in b/stapprobes.5.in
index 59daee8e..9f97ef01 100644
--- a/stapprobes.5.in
+++ b/stapprobes.5.in
@@ -183,6 +183,8 @@ module(MPATTERN).inline(PATTERN)
.br
kernel.statement(PATTERN)
.br
+kernel.statement(ADDRESS).absolute
+.br
module(MPATTERN).statement(PATTERN)
.ESAMPLE
In the above list, MPATTERN stands for a string literal that aims to
@@ -200,7 +202,9 @@ wildcard pattern, such as
Finally, the third part is optional if the file name part was given,
and identifies the line number in the source file, preceded by a ":".
As an alternative, PATTERN may be a numeric constant, indicating an
-(module-relative or kernel-absolute) address.
+(module-relative or kernel-_stext-relative) address. In guru mode
+only, absolute kernel addresses may be specified with the ".absolute"
+suffix.
.PP
Some of the source-level variables, such as function parameters,
locals, globals visible in the compilation unit, may be visible to
diff --git a/staptree.h b/staptree.h
index 7585a01f..b63c6c33 100644
--- a/staptree.h
+++ b/staptree.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-// Copyright (C) 2005, 2006 Red Hat Inc.
+// Copyright (C) 2005-2007 Red Hat Inc.
// Copyright (C) 2006 Intel Corporation.
//
// This file is part of systemtap, and is free software. You can
@@ -586,6 +586,7 @@ struct probe
virtual void printsig (std::ostream &o) const;
virtual probe* basest () { return this; }
virtual ~probe() {}
+ bool privileged;
private:
static unsigned last_probeidx;
public:
diff --git a/tapsets.cxx b/tapsets.cxx
index 0dddc33a..9fe3fba7 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -130,7 +130,7 @@ be_derived_probe::join_group (systemtap_session& s)
void
common_probe_entryfn_prologue (translator_output* o, string statestr,
bool overload_processing = true,
- bool interruptible = false)
+ bool interruptible = false)
{
o->newline() << "struct context* __restrict__ c;";
if (! interruptible)
@@ -203,7 +203,7 @@ common_probe_entryfn_prologue (translator_output* o, string statestr,
void
common_probe_entryfn_epilogue (translator_output* o,
bool overload_processing = true,
- bool interruptible = false)
+ bool interruptible = false)
{
if (overload_processing)
o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
@@ -377,6 +377,7 @@ static string TOK_CALLEES("callees");
static string TOK_STATEMENT("statement");
static string TOK_LABEL("label");
static string TOK_RELATIVE("relative");
+static string TOK_ABSOLUTE("absolute");
struct
@@ -2014,6 +2015,8 @@ struct dwarf_query
bool has_relative;
long relative_val;
+ bool has_absolute;
+
function_spec_type parse_function_spec(string & spec);
function_spec_type spec_type;
string function;
@@ -2145,6 +2148,8 @@ dwarf_query::dwarf_query(systemtap_session & sess,
has_label = get_string_param(params, TOK_LABEL, label_val);
has_relative = get_number_param(params, TOK_RELATIVE, relative_val);
+ has_absolute = has_null_param(params, TOK_ABSOLUTE);
+
if (has_function_str)
spec_type = parse_function_spec(function_str_val);
else if (has_inline_str)
@@ -2358,6 +2363,8 @@ dwarf_query::add_probe_point(const string& funcname,
string blacklist_section; // linking section for blacklist purposes
const string& module = dw.module_name; // "kernel" or other
+ assert (! has_absolute); // already handled in dwarf_builder::build()
+
if (dwfl_module_relocations (dw.module) > 0)
{
// This is arelocatable module; libdwfl already knows its
@@ -2427,7 +2434,7 @@ dwarf_query::add_probe_point(const string& funcname,
{
// PR 4224: adapt to relocatable kernel by subtracting the _stext address here.
reloc_addr = addr - sess.sym_stext;
- reloc_section = "_stext"; // a deliberate eyesore
+ reloc_section = "_stext"; // a message to runtime's _stp_module_relocate
}
if (! bad)
@@ -3462,7 +3469,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
// actual relocation.
Dwarf_Addr addr,
dwarf_query& q,
- Dwarf_Die* scope_die)
+ Dwarf_Die* scope_die /* may be null */)
: derived_probe (q.base_probe, 0 /* location-less */),
module (module), section (section), addr (addr),
has_return (q.has_return),
@@ -3470,30 +3477,35 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
maxactive_val (q.maxactive_val)
{
// Assert relocation invariants
- if (section == "")
+ 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);
- // Make a target-variable-expanded copy of the probe body
- dwarf_var_expanding_copy_visitor v (q, scope_die, dwfl_addr);
- require <block*> (&v, &(this->body), q.base_probe->body);
this->tok = q.base_probe->tok;
- // If when 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->statements.insert(this->body->statements.begin(), v.add_block);
-
- // 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)
+ // Make a target-variable-expanded copy of the probe body
+ if (scope_die)
{
- stapfile *f = new stapfile;
- f->probes.push_back(v.add_probe);
- q.sess.files.push_back(f);
+ dwarf_var_expanding_copy_visitor v (q, scope_die, dwfl_addr);
+ require <block*> (&v, &(this->body), q.base_probe->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->statements.insert(this->body->statements.begin(), v.add_block);
+
+ // 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
// Set the sole element of the "locations" vector as a
// "reverse-engineered" form of the incoming (q.base_loc) probe
@@ -3537,6 +3549,9 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
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 (has_return)
@@ -3652,6 +3667,8 @@ dwarf_derived_probe::register_patterns(match_node * root)
register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
+ root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw);
+
// register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
}
@@ -3880,6 +3897,25 @@ dwarf_builder::build(systemtap_session & sess,
dwarf_query q(sess, base, location, *dw, parameters, finished_results);
+ if (q.has_absolute)
+ {
+ // assert guru mode for absolute probes
+ if (! q.base_probe->privileged)
+ {
+ throw semantic_error ("absolute statement probe in unprivileged script", q.base_probe->tok);
+ }
+
+ // For kernel.statement(NUM).absolute probe points, we bypass
+ // all the debuginfo stuff: We just wire up a
+ // dwarf_derived_probe right here and now.
+ dwarf_derived_probe* p = new dwarf_derived_probe ("", "", 0, "kernel", "",
+ q.statement_num_val, q.statement_num_val,
+ q, 0);
+ finished_results.push_back (p);
+ return;
+ }
+
+
if (q.has_kernel &&
(q.has_function_num || q.has_inline_num || q.has_statement_num))
{
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index d22d6f5d..6db55406 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2007-03-22 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 4224.
+ * systemtap.base/probefunc.exp: Use kernel.statement().absolute
+ instead with grep-found schedule_tick address.
+ * semko/thirtyseven.stp, thirtyeight.stp: New tests.
+ * buildok/twentyeight.stp: New test.
+
2007-03-22 David Smith <dsmith@redhat.com>
* systemtap.stress/conversions.exp: Fixed test case bug that only
diff --git a/testsuite/buildok/twentyeight.stp b/testsuite/buildok/twentyeight.stp
new file mode 100755
index 00000000..03946bb0
--- /dev/null
+++ b/testsuite/buildok/twentyeight.stp
@@ -0,0 +1,3 @@
+#! stap -gp4
+
+probe kernel.statement(0).absolute { }
diff --git a/testsuite/semko/thirtyeight.stp b/testsuite/semko/thirtyeight.stp
new file mode 100755
index 00000000..6b7f1be4
--- /dev/null
+++ b/testsuite/semko/thirtyeight.stp
@@ -0,0 +1,3 @@
+#! stap -p3
+
+probe kernel.statement(0).absolute {} /* needs guru mode */
diff --git a/testsuite/semko/thirtyseven.stp b/testsuite/semko/thirtyseven.stp
new file mode 100755
index 00000000..b0c8225e
--- /dev/null
+++ b/testsuite/semko/thirtyseven.stp
@@ -0,0 +1,3 @@
+#! stap -gp3
+
+probe kernel.statement(0).absolute { print ($any_variable) }
diff --git a/testsuite/systemtap.base/probefunc.exp b/testsuite/systemtap.base/probefunc.exp
index 1cea688a..e131fafb 100644
--- a/testsuite/systemtap.base/probefunc.exp
+++ b/testsuite/systemtap.base/probefunc.exp
@@ -38,11 +38,11 @@ close $symfd
set prefix "probefunc:"
-# test probefunc() with kernel.statement()
+# test probefunc() with kernel.statement().absolute
set output_string "\\mscheduler_tick\\M\r\n"
-set probepoint "kernel.statement(0x$addr)"
+set probepoint "kernel.statement(0x$addr).absolute"
set script [format $systemtap_script $probepoint]
-stap_run $prefix$probepoint sleep_one_sec $output_string -e $script
+stap_run $prefix$probepoint sleep_one_sec $output_string -g -e $script
# test probefunc() with kernel.function()
set probepoint "kernel.function(\"scheduler_tick\")"