diff options
-rw-r--r-- | elaborate.cxx | 18 | ||||
-rw-r--r-- | staptree.cxx | 10 | ||||
-rw-r--r-- | staptree.h | 6 | ||||
-rw-r--r-- | tapset/logging.stp | 8 | ||||
-rw-r--r-- | tapset/timestamp.stp | 2 | ||||
-rw-r--r-- | tapsets.cxx | 3 | ||||
-rw-r--r-- | testsuite/systemtap.base/optim_arridx.exp | 2 | ||||
-rw-r--r-- | translate.cxx | 5 |
8 files changed, 35 insertions, 19 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index f0c6c5a9..e7ea7b23 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1044,7 +1044,7 @@ semantic_pass_conditions (systemtap_session & sess) expression* e = p->sole_location()->condition; if (e) { - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(sess); e->visit (& vut); if (! vut.written.empty()) @@ -1199,7 +1199,7 @@ void add_global_var_display (systemtap_session& s) // it would clutter up the list of probe points with "end ...". if (s.listing_mode) return; - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(s); for (unsigned i=0; i<s.probes.size(); i++) { s.probes[i]->body->visit (& vut); @@ -1986,7 +1986,7 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p) // written nor read. void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterations) { - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(s); for (unsigned i=0; i<s.probes.size(); i++) { @@ -2183,7 +2183,7 @@ dead_assignment_remover::visit_assignment (assignment* e) break; } - varuse_collecting_visitor lvut; + varuse_collecting_visitor lvut(session); e->left->visit (& lvut); if (lvut.side_effect_free () && !is_global) // XXX: use _wrt() once we track focal_vars { @@ -2216,7 +2216,7 @@ void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p) // Recompute the varuse data, which will probably match the opt2 // copy of the computation, except for those totally unused // variables that opt2 removed. - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(s); for (unsigned i=0; i<s.probes.size(); i++) s.probes[i]->body->visit (& vut); // includes reachable functions too @@ -2320,7 +2320,7 @@ dead_stmtexpr_remover::visit_if_statement (if_statement *s) { // We may be able to elide this statement, if the condition // expression is side-effect-free. - varuse_collecting_visitor vct; + varuse_collecting_visitor vct(session); s->condition->visit(& vct); if (vct.side_effect_free ()) { @@ -2384,7 +2384,7 @@ dead_stmtexpr_remover::visit_for_loop (for_loop *s) { // We may be able to elide this statement, if the condition // expression is side-effect-free. - varuse_collecting_visitor vct; + varuse_collecting_visitor vct(session); if (s->init) s->init->visit(& vct); s->cond->visit(& vct); if (s->incr) s->incr->visit(& vct); @@ -2421,7 +2421,7 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s) // NB. While we don't share nodes in the parse tree, let's not // deallocate *s anyway, just in case... - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(session); s->value->visit (& vut); if (vut.side_effect_free_wrt (focal_vars)) @@ -2761,7 +2761,7 @@ void_statement_reducer::visit_functioncall (functioncall* e) return; } - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(session); vut.traversed.insert (e->referent); vut.current_function = e->referent; e->referent->body->visit (& vut); diff --git a/staptree.cxx b/staptree.cxx index 8d251731..df075f44 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -10,6 +10,7 @@ #include "staptree.h" #include "parse.h" #include "util.h" +#include "session.h" #include <iostream> #include <typeinfo> @@ -1684,6 +1685,14 @@ functioncall_traversing_visitor::visit_functioncall (functioncall* e) void varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s) { + assert (current_function); // only they get embedded code + + // Don't allow embedded C functions in unprivileged mode unless + // they are tagged with /* unprivileged */ + if (session.unprivileged && s->code.find ("/* unprivileged */") == string::npos) + throw semantic_error ("function may not be used when --unprivileged is specified", + current_function->tok); + // We want to elide embedded-C functions when possible. For // example, each $target variable access is expanded to an // embedded-C function call. Yet, for safety reasons, we should @@ -1694,7 +1703,6 @@ varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s) // $target variables as rvalues will have this; lvalues won't. // Also, explicit side-effect-free tapset functions will have this. - assert (current_function); // only they get embedded code if (s->code.find ("/* pure */") != string::npos) return; @@ -23,6 +23,8 @@ extern "C" { } struct token; // parse.h +struct systemtap_session; // session.h + struct semantic_error: public std::runtime_error { const token* tok1; @@ -752,12 +754,14 @@ struct functioncall_traversing_visitor: public traversing_visitor // the elaboration-time optimizer pass. struct varuse_collecting_visitor: public functioncall_traversing_visitor { + systemtap_session& session; std::set<vardecl*> read; std::set<vardecl*> written; bool embedded_seen; expression* current_lvalue; expression* current_lrvalue; - varuse_collecting_visitor(): + varuse_collecting_visitor(systemtap_session& s): + session (s), embedded_seen (false), current_lvalue(0), current_lrvalue(0) {} diff --git a/tapset/logging.stp b/tapset/logging.stp index d2cca612..91f9672b 100644 --- a/tapset/logging.stp +++ b/tapset/logging.stp @@ -8,21 +8,21 @@ // send a string out with a newline // Deprecated. print* functions are much more efficient. -function log (msg:string) %{ +function log (msg:string) %{ /* unprivileged */ _stp_printf ("%s\n", THIS->msg); %} -function warn (msg:string) %{ +function warn (msg:string) %{ /* unprivileged */ _stp_warn ("%s", THIS->msg); %} // NB: exit() does *not* cause immediate return from current function/probe -function exit () %{ +function exit () %{ /* unprivileged */ atomic_set (&session_state, STAP_SESSION_STOPPING); _stp_exit (); %} -function error (msg:string) %{ +function error (msg:string) %{ /* unprivileged */ /* This is an assignment of a local char[] to a global char*. It would normally be just as unsafe as returning a pointer to a local variable from a function. However, the translated diff --git a/tapset/timestamp.stp b/tapset/timestamp.stp index 0b9d350a..1980932a 100644 --- a/tapset/timestamp.stp +++ b/tapset/timestamp.stp @@ -16,7 +16,7 @@ * * Return the processor cycle counter value, or 0 if unavailable. */ -function get_cycles:long () %{ /* pure */ +function get_cycles:long () %{ /* pure */ /* unprivileged */ cycles_t c = get_cycles(); THIS->__retvalue = (int64_t) c; %} diff --git a/tapsets.cxx b/tapsets.cxx index 3017e203..0a07e7a8 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2662,6 +2662,9 @@ void dwarf_cast_expanding_visitor::filter_special_modules(string& module) void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) { + if (s.unprivileged) + throw semantic_error("typecasting may not be used when --unprivileged is specified", e->tok); + bool lvalue = is_active_lvalue(e); if (lvalue && !s.guru_mode) throw semantic_error("write to typecast value not permitted", e->tok); diff --git a/testsuite/systemtap.base/optim_arridx.exp b/testsuite/systemtap.base/optim_arridx.exp index 1f3f4371..c33952a6 100644 --- a/testsuite/systemtap.base/optim_arridx.exp +++ b/testsuite/systemtap.base/optim_arridx.exp @@ -10,7 +10,7 @@ elide_global_a:long elide_global_b:long # functions exit:unknown () -%{ +%{ /* unprivileged */ atomic_set (&session_state, STAP_SESSION_STOPPING); _stp_exit (); %} diff --git a/translate.cxx b/translate.cxx index 5336dc66..172c1287 100644 --- a/translate.cxx +++ b/translate.cxx @@ -57,7 +57,8 @@ struct c_unparser: public unparser, public visitor c_unparser (systemtap_session* ss): session (ss), o (ss->op), current_probe(0), current_function (0), - tmpvar_counter (0), label_counter (0) {} + tmpvar_counter (0), label_counter (0), + vcv_needs_global_locks (*ss) {} ~c_unparser () {} void emit_map_type_instantiations (); @@ -1600,7 +1601,7 @@ c_unparser::emit_probe (derived_probe* v) v->emit_probe_local_init(o); // emit all read/write locks for global variables - varuse_collecting_visitor vut; + varuse_collecting_visitor vut(*session); if (v->needs_global_locks ()) { v->body->visit (& vut); |