From: Martin Cermak Date: Thu, 5 Nov 2015 20:50:55 +0000 (-0500) Subject: Prefix global functions in the generated code. X-Git-Tag: release-3.0~331 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=8f54215ef850c809;p=systemtap.git Prefix global functions in the generated code. Add '__global_' prefix to global functions in the generated code. Treat selected internal synthetic functions as private. Fix using a private function in user script and test-cover it. * elaborate.cxx: Correctly match global function names to respective functiondecls. Match synthetic private functions coming from tapset-procfs.cxx (*_procfs_value_*), and tapsets.cxx (_sdt_arg_get_addr_) to respective functiondecls. * main.cxx: Update the --dump-functions feature to correctly deal with new internal function names. * parse.cxx: Add the "__global_" prefix to global functions in the generated code. * staptree.cxx: Update functiondecl::printsig() so that it outputs unmangled function name. * tapset-procfs.cxx: Treat internal synthetic functions '*_procfs_value_get*', '*_procfs_value_set*', '*_procfs_value_append*' as private. * tapsets.cxx: Treat internal synthetic functions '*_sdt_arg_get_addr_*' as private. * optim_arridx.exp: Adapt the testcase to new naming. * private.exp: Add subtest examining use of a private function in user script. --- diff --git a/elaborate.cxx b/elaborate.cxx index e372e731e..149358055 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -2348,7 +2348,7 @@ symresolution_info::find_var (interned_string name, int arity, const token* tok) string pname = "__private_" + detox_path(tok->location.file->name) + string(name); for (unsigned i=0; iname == name && name.substr(0, 9) == "__global_") || + if ((session.globals[i]->name == name && startswith(name, "__global_")) || (session.globals[i]->name == gname) || (session.globals[i]->name == pname)) { @@ -2396,8 +2396,13 @@ symresolution_info::find_var (interned_string name, int arity, const token* tok) functiondecl* symresolution_info::find_function (const string& name, unsigned arity, const token *tok) { + string gname = "__global_" + string(name); + string pname = "__private_" + detox_path(tok->location.file->name) + string(name); + // the common path - if (session.functions.find(name) != session.functions.end()) + + // internal global functions bypassing the parser, such as __global_dwarf_tvar_[gs]et + if ((session.functions.find(name) != session.functions.end()) && startswith(name, "__private_")) { functiondecl* fd = session.functions[name]; assert (fd->name == name); @@ -2408,14 +2413,37 @@ symresolution_info::find_function (const string& name, unsigned arity, const tok name.c_str(), fd->formal_args.size()), tok, fd->tok); } + // tapset or user script global functions coming from the parser + if (session.functions.find(gname) != session.functions.end()) + { + functiondecl* fd = session.functions[gname]; + assert (fd->name == gname); + if (fd->formal_args.size() == arity) + return fd; + + throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)", + name.c_str(), fd->formal_args.size()), tok, fd->tok); + } + + // tapset or user script private functions coming from the parser + if (session.functions.find(pname) != session.functions.end()) + { + functiondecl* fd = session.functions[pname]; + assert (fd->name == pname); + if (fd->formal_args.size() == arity) + return fd; + + throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)", + name.c_str(), fd->formal_args.size()), tok, fd->tok); + } + // search library functions for (unsigned i=0; ifunctions.size(); j++) { - string pname = "__private_" + detox_path(tok->location.file->name) + string(name); - if ((f->functions[j]->name == name) || + if ((f->functions[j]->name == gname) || (f->functions[j]->name == pname)) { if (f->functions[j]->formal_args.size() == arity) diff --git a/main.cxx b/main.cxx index f88701cba..250d0221e 100644 --- a/main.cxx +++ b/main.cxx @@ -831,7 +831,9 @@ passes_0_4 (systemtap_session &s) functiondecl& curfunc = *func->second; if (curfunc.synthetic) continue; - if (!s.verbose && startswith(curfunc.name, "_")) + if (!startswith(curfunc.name, "__global_")) + continue; + if (!s.verbose && startswith(curfunc.name, "__global__")) continue; curfunc.printsigtags(cout, s.verbose>0 /* all_tags */ ); cout << endl; diff --git a/parse.cxx b/parse.cxx index 5a708a8c2..fde1772a1 100644 --- a/parse.cxx +++ b/parse.cxx @@ -2325,7 +2325,7 @@ parser::do_parse_functiondecl (vector& functions, const token* t, if (functions[i]->name == t->content) throw PARSE_ERROR (_("duplicate function name")); - string name = t->content; + string name = "__global_" + string(t->content); if (priv) name = "__private_" + detox_path(fname) + string(t->content); diff --git a/staptree.cxx b/staptree.cxx index 45b539907..0db5e285c 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -575,7 +575,7 @@ void functiondecl::print (ostream& o) const void functiondecl::printsig (ostream& o) const { - o << name << ":" << type << " ("; + o << tok->content << ":" << type << " ("; for (unsigned i=0; i0 ? ", " : "") << *formal_args[i] diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx index 9f93e0519..3a012c3f0 100644 --- a/tapset-procfs.cxx +++ b/tapset-procfs.cxx @@ -453,12 +453,12 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e) embeddedcode *ec = new embeddedcode; ec->tok = e->tok; - string fname; + string fname = "__private_" + detox_path(string(e->tok->location.file->name)); string locvalue = "CONTEXT->ips.procfs_data"; if (! lvalue) { - fname = "_procfs_value_get"; + fname += "_procfs_value_get"; ec->code = string(" struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string("); /* pure */\n") + string(" if (!_stp_copy_from_user(STAP_RETVALUE, data->buffer, data->count))\n") @@ -470,7 +470,7 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e) { if (*op == "=") { - fname = "_procfs_value_set"; + fname += "_procfs_value_set"; ec->code = string("struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n") + string(" strlcpy(data->buffer, STAP_ARG_value, data->bufsize);\n") + string(" if (strlen(STAP_ARG_value) > data->bufsize-1)\n") @@ -480,7 +480,7 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e) } else if (*op == ".=") { - fname = "_procfs_value_append"; + fname += "_procfs_value_append"; ec->code = string("struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n") + string(" strlcat(data->buffer, STAP_ARG_value, data->bufsize);\n") + string(" if (data->count + strlen(STAP_ARG_value) > data->bufsize-1)\n") diff --git a/tapsets.cxx b/tapsets.cxx index 897e1d7c9..b01330614 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3527,10 +3527,11 @@ synthetic_embedded_deref_call(dwflpp& dw, expression* pointer=NULL) { // Synthesize a functiondecl for the given embedded code string. + string fhash = detox_path(string(e->tok->location.file->name)); functiondecl *fdecl = new functiondecl; fdecl->synthetic = true; fdecl->tok = e->tok; - fdecl->name = function_name; + fdecl->name = "__private_" + fhash + function_name; // The fdecl type is generic, but we'll be detailed on the fcall below. fdecl->type = pe_long; fdecl->type_details.reset(new exp_type_dwarf(&dw, function_type, @@ -6619,10 +6620,11 @@ sdt_uprobe_var_expanding_visitor::try_parse_arg_varname (target_symbol *e, user_int_call->function = precision_to_function(precision); user_int_call->tok = e->tok; + string fhash = detox_path(string(e->tok->location.file->name)); functiondecl *get_addr_decl = new functiondecl; get_addr_decl->tok = e->tok; get_addr_decl->synthetic = true; - get_addr_decl->name = "_sdt_arg_get_addr_" + lex_cast(tick++); + get_addr_decl->name = "__private_" + fhash + "_sdt_arg_get_addr_" + lex_cast(tick++); get_addr_decl->type = pe_long; // build _stp_umodule_relocate(module, addr, current) diff --git a/testsuite/systemtap.base/optim_arridx.exp b/testsuite/systemtap.base/optim_arridx.exp index ef265b678..b89d08c25 100644 --- a/testsuite/systemtap.base/optim_arridx.exp +++ b/testsuite/systemtap.base/optim_arridx.exp @@ -36,15 +36,15 @@ begin /* <- begin */ (__global_arr2[(idx2) = (2)]) = (20) (__global_arr2[3]) = (30) (__global_arr2[(j) = (4)]) = (40) -(__global_arr1[fna((k) = (0)), k]) = (1) +(__global_arr1[__global_fna((k) = (0)), k]) = (1) (__global_arr1[(b) = (1), b]) = (2) (__global_arr1[2, 2]) = (3) (__global_arr3[0]) = (4) (m) = (1) for (2; (m) <= (10); (m)++) (__global_arr2[m]) = ((m) * (10)) printf("%d %d %d %d\\n", __global_arr1[0, 0], __global_arr2[0], idx2, j) -(aa) = (fna(1)) -(bb) = (fnb((cc) = (1), (__global_elide_global_a) = (2))) +(aa) = (__global_fna(1)) +(bb) = (__global_fnb((cc) = (1), (__global_elide_global_a) = (2))) for (1; (bb) < (10); (bb)++) (cc) += (bb) for ((dd) = (1); (dd) < (10); 1) (dd) += (1) if ((__global_elide_global_b) = (1)) (ee) = (1) @@ -52,7 +52,7 @@ if ((__global_elide_global_b) = (1)) (ee) = (1) (cc) = ((dd) = (5)) (cc) = ((4) + ((cc) = (1))) printf("%d %d %d %d %d\\n", aa, bb, cc, dd, ee) -exit() +__global_exit() } end /* <- end */ # locals diff --git a/testsuite/systemtap.base/private.exp b/testsuite/systemtap.base/private.exp index ae0fb3cb6..596a3db5a 100644 --- a/testsuite/systemtap.base/private.exp +++ b/testsuite/systemtap.base/private.exp @@ -135,6 +135,21 @@ foreach runtime [get_runtime_list] { } catch {close}; catch {wait} if {$__counter == 1} {pass $subtest} else {fail $subtest} + + # Subtest + set subtest "$test private-function-in-user-script" + set __counter 0 + eval spawn "stap --runtime=$runtime -e {private function foo() { println(42) } probe oneshot \{ foo() \}}" + expect { + -timeout 160 + -re {^42\r\n} { + incr __counter + exp_continue + } + timeout {fail "$subtest (timeout)"} + } + catch {close}; catch {wait} + if {$__counter == 1} {pass $subtest} else {fail $subtest} } # Cleanup