diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | NEWS | 16 | ||||
-rw-r--r-- | elaborate.cxx | 2 | ||||
-rw-r--r-- | parse.cxx | 4 | ||||
-rw-r--r-- | runtime/ChangeLog | 5 | ||||
-rw-r--r-- | runtime/sym.c | 4 | ||||
-rw-r--r-- | stapprobes.5.in | 6 | ||||
-rw-r--r-- | staptree.h | 3 | ||||
-rw-r--r-- | tapsets.cxx | 74 | ||||
-rw-r--r-- | testsuite/ChangeLog | 8 | ||||
-rwxr-xr-x | testsuite/buildok/twentyeight.stp | 3 | ||||
-rwxr-xr-x | testsuite/semko/thirtyeight.stp | 3 | ||||
-rwxr-xr-x | testsuite/semko/thirtyseven.stp | 3 | ||||
-rw-r--r-- | testsuite/systemtap.base/probefunc.exp | 6 |
14 files changed, 123 insertions, 26 deletions
@@ -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: @@ -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); } } @@ -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 @@ -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\")" |