From a0c0ed1c030d8e812eed19b096c626b7ce233358 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Tue, 28 Jul 2009 19:50:24 -0400 Subject: PR6978: support $$parms for process.syscall * tapset-utrace.cxx (visit_target_symbol_arg): Handle $$parms. * testsuite/systemtap.base/utrace_p4.exp: Add test case. * testsuite/systemtap.base/utrace_p5.exp: Ditto. --- tapset-utrace.cxx | 125 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 41 deletions(-) (limited to 'tapset-utrace.cxx') diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index ec20282a..a3a4ca3d 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -407,54 +407,97 @@ utrace_var_expanding_visitor::visit_target_symbol_cached (target_symbol* e) void utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) { - string argnum_s = e->base_name.substr(4,e->base_name.length()-4); - int argnum = lex_cast(argnum_s); - if (flags != UDPF_SYSCALL) - throw semantic_error ("only \"process(PATH_OR_PID).syscall\" support $argN.", e->tok); + throw semantic_error ("only \"process(PATH_OR_PID).syscall\" support $argN or $$parms.", e->tok); - if (e->components.size() > 0) + if (e->base_name == "$$parms") { - switch (e->components[0].first) - { - case target_symbol::comp_literal_array_index: - throw semantic_error("utrace target variable '$argN' may not be used as array", - e->tok); - break; - case target_symbol::comp_struct_member: - throw semantic_error("utrace target variable '$argN' may not be used as a structure", - e->tok); - break; - default: - throw semantic_error ("invalid use of utrace target variable '$argN'", - e->tok); - break; - } - } + // copy from tracepoint + print_format* pf = new print_format; + token* pf_tok = new token(*e->tok); + pf_tok->content = "sprintf"; + pf->tok = pf_tok; + pf->print_to_stream = false; + pf->print_with_format = true; + pf->print_with_delim = false; + pf->print_with_newline = false; + pf->print_char = false; + + target_symbol_seen = true; + + for (unsigned i = 0; i < 6; ++i) + { + if (i > 0) + pf->raw_components += " "; + pf->raw_components += "$arg" + lex_cast(i+1); + target_symbol *tsym = new target_symbol; + tsym->tok = e->tok; + tsym->base_name = "$arg" + lex_cast(i+1); + tsym->saved_conversion_error = 0; + pf->raw_components += "=%#x"; //FIXME: missing type info + + functioncall* n = new functioncall; //same as the following + n->tok = e->tok; + n->function = "_utrace_syscall_arg"; + n->referent = 0; + literal_number *num = new literal_number(i); + num->tok = e->tok; + n->args.push_back(num); + + pf->args.push_back(n); + } + pf->components = print_format::string_to_components(pf->raw_components); + + provide (pf); + } + else // $argN + { + string argnum_s = e->base_name.substr(4,e->base_name.length()-4); + int argnum = lex_cast(argnum_s); + + if (e->components.size() > 0) + { + switch (e->components[0].first) + { + case target_symbol::comp_literal_array_index: + throw semantic_error("utrace target variable '$argN' may not be used as array", + e->tok); + break; + case target_symbol::comp_struct_member: + throw semantic_error("utrace target variable '$argN' may not be used as a structure", + e->tok); + break; + default: + throw semantic_error ("invalid use of utrace target variable '$argN'", + e->tok); + break; + } + } - // FIXME: max argnument number should not be hardcoded. - if (argnum < 1 || argnum > 6) - throw semantic_error ("invalid syscall argument number (1-6)", e->tok); + // FIXME: max argnument number should not be hardcoded. + if (argnum < 1 || argnum > 6) + throw semantic_error ("invalid syscall argument number (1-6)", e->tok); - bool lvalue = is_active_lvalue(e); - if (lvalue) - throw semantic_error("utrace '$argN' variable is read-only", e->tok); + bool lvalue = is_active_lvalue(e); + if (lvalue) + throw semantic_error("utrace '$argN' variable is read-only", e->tok); - // Remember that we've seen a target variable. - target_symbol_seen = true; + // Remember that we've seen a target variable. + target_symbol_seen = true; - // We're going to substitute a synthesized '_utrace_syscall_arg' - // function call for the '$argN' reference. - functioncall* n = new functioncall; - n->tok = e->tok; - n->function = "_utrace_syscall_arg"; - n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session + // We're going to substitute a synthesized '_utrace_syscall_arg' + // function call for the '$argN' reference. + functioncall* n = new functioncall; + n->tok = e->tok; + n->function = "_utrace_syscall_arg"; + n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session - literal_number *num = new literal_number(argnum - 1); - num->tok = e->tok; - n->args.push_back(num); + literal_number *num = new literal_number(argnum - 1); + num->tok = e->tok; + n->args.push_back(num); - provide (n); + provide (n); + } } void @@ -542,12 +585,12 @@ utrace_var_expanding_visitor::visit_target_symbol (target_symbol* e) if (e->addressof) throw semantic_error("cannot take address of utrace variable", e->tok); - if (e->base_name.substr(0,4) == "$arg") + if (e->base_name.substr(0,4) == "$arg" || e->base_name == "$$parms") visit_target_symbol_arg(e); else if (e->base_name == "$syscall" || e->base_name == "$return") visit_target_symbol_context(e); else - throw semantic_error ("invalid target symbol for utrace probe, $syscall, $return or $argN expected", + throw semantic_error ("invalid target symbol for utrace probe, $syscall, $return, $argN or $$parms expected", e->tok); } -- cgit From c67847a0d05f8c7207513e79378fc8d84563e109 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 31 Jul 2009 17:00:09 -0700 Subject: Make a real type for target_symbol->components Now the dereferences on target_symbol and cast_op are tracked with a struct instead of just a generic pair. The first immediate benefit is that we can track the token for more exact error reporting. * staptree.h (target_symbol): Add a new component type. * staptree.cxx (target_symbol::component::print): New. (operator<<(ostream&, target_symbol::component&): New. (target_symbol::print): Adapt component printing. (cast_op::print): Ditto. * parse.cxx (parser::parse_target_symbol_components): Adapt to the new component construction. * dwflpp.cxx (dwflpp::find_struct_member): take the component as a parameter for a better token in error messages (dwflpp::translate_components): Adapt to the new component type. * tapsets.cxx (dwarf_var_expanding_visitor::visit_target_symbol): Don't overwrite the token in target_symbol saved errors. (tracepoint_var_expanding_visitor::visit_target_symbol_arg): Ditto. --- tapset-utrace.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tapset-utrace.cxx') diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index a3a4ca3d..3befcbd5 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -457,7 +457,7 @@ utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) if (e->components.size() > 0) { - switch (e->components[0].first) + switch (e->components[0].type) { case target_symbol::comp_literal_array_index: throw semantic_error("utrace target variable '$argN' may not be used as array", @@ -507,7 +507,7 @@ utrace_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) if (e->components.size() > 0) { - switch (e->components[0].first) + switch (e->components[0].type) { case target_symbol::comp_literal_array_index: throw semantic_error("utrace target variable '" + sname + "' may not be used as array", -- cgit From dc5a09fc9a61c8b33078164b6855dea54a33627c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 31 Jul 2009 17:24:13 -0700 Subject: Unify no-component assertions on target variables There are several tapsets that can't deal with component dereferences on their target variables, and they all check-and-throw in the same way. This refactors the checks into a target_symbol member. * staptree.cxx (target_symbol::assert_no_components): New. * tapsets.cxx (tracepoint_var_expanding_visitor::visit_target_symbol_arg, tracepoint_var_expanding_visitor::visit_target_symbol_context): Use the new assertion function to check for no components. * tapset-mark.cxx (mark_var_expanding_visitor::visit_target_symbol_arg, mark_var_expanding_visitor::visit_target_symbol_context): Ditto. * tapset-perfmon.cxx (perfmon_var_expanding_visitor::visit_target_symbol): Ditto. * tapset-procfs.cxx (procfs_var_expanding_visitor::visit_target_symbol): Ditto. * tapset-utrace.cxx (utrace_var_expanding_visitor::visit_target_symbol_arg, utrace_var_expanding_visitor::visit_target_symbol_context): Ditto. --- tapset-utrace.cxx | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) (limited to 'tapset-utrace.cxx') diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index 3befcbd5..87053f7d 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -455,24 +455,7 @@ utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) string argnum_s = e->base_name.substr(4,e->base_name.length()-4); int argnum = lex_cast(argnum_s); - if (e->components.size() > 0) - { - switch (e->components[0].type) - { - case target_symbol::comp_literal_array_index: - throw semantic_error("utrace target variable '$argN' may not be used as array", - e->tok); - break; - case target_symbol::comp_struct_member: - throw semantic_error("utrace target variable '$argN' may not be used as a structure", - e->tok); - break; - default: - throw semantic_error ("invalid use of utrace target variable '$argN'", - e->tok); - break; - } - } + e->assert_no_components("utrace"); // FIXME: max argnument number should not be hardcoded. if (argnum < 1 || argnum > 6) @@ -505,24 +488,7 @@ utrace_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) { string sname = e->base_name; - if (e->components.size() > 0) - { - switch (e->components[0].type) - { - case target_symbol::comp_literal_array_index: - throw semantic_error("utrace target variable '" + sname + "' may not be used as array", - e->tok); - break; - case target_symbol::comp_struct_member: - throw semantic_error("utrace target variable '" + sname + "' may not be used as a structure", - e->tok); - break; - default: - throw semantic_error ("invalid use of utrace target variable '" + sname + "'", - e->tok); - break; - } - } + e->assert_no_components("utrace"); bool lvalue = is_active_lvalue(e); if (lvalue) -- cgit From 8b095b454b34e88c04592be6c651153f802eced6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 3 Aug 2009 15:49:40 -0700 Subject: Add update_visitor::replace I noticed that most uses of update_visitor::require() were simply writing the value back to the same place, i.e. foo = require(foo). The new replace() method just encapsulates that paradigm, so we don't have the duplication between the LHS and RHS. * staptree.h (update_visitor::replace): New. * elaborate.cxx, staptree.cxx, tapset-mark.cxx, tapset-perfmon.cxx, tapset-procfs.cxx, tapset-utrace.cxx, tapsets.cxx: Update all require calls that are simply updating the value in-place. --- tapset-utrace.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tapset-utrace.cxx') diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index 87053f7d..a07e08b8 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -120,7 +120,7 @@ utrace_derived_probe::utrace_derived_probe (systemtap_session &s, { // Expand local variables in the probe body utrace_var_expanding_visitor v (s, l, name, flags); - this->body = v.require (this->body); + v.replace (this->body); target_symbol_seen = v.target_symbol_seen; // If during target-variable-expanding the probe, we added a new block -- cgit