From 305a3c4476e91749dcdacaaedf0b8198c9385cbb Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 22 Jun 2010 12:37:43 -0400 Subject: [PATCH] Handle $N numeric literal for -DSTAP_SDT_V2 probe asm arg descriptor. sdt.h (__stap_argN): Switch gcc asm constraint from "ro" to "ron" to allow $N tapsets.cxx (sdt_uprobe_var_expanding_visitor::visit_target_symbol): Add literal_arg to support $N. --- includes/sys/sdt.h | 22 ++++----- tapsets.cxx | 109 +++++++++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index ba233f5a5..dc8922847 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -148,17 +148,17 @@ typedef struct #endif /* variadic macro args not allowed by -ansi -pedantic so... */ -/* Use "ro" constraint as "g" constraint sometimes gives an auto increment operand */ -#define __stap_arg1 "ro"(arg1) -#define __stap_arg2 "ro"(arg1), "ro"(arg2) -#define __stap_arg3 "ro"(arg1), "ro"(arg2), "ro"(arg3) -#define __stap_arg4 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4) -#define __stap_arg5 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4), "ro"(arg5) -#define __stap_arg6 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4), "ro"(arg5), "ro"(arg6) -#define __stap_arg7 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4), "ro"(arg5), "ro"(arg6), "ro"(arg7) -#define __stap_arg8 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4), "ro"(arg5), "ro"(arg6), "ro"(arg7), "ro"(arg8) -#define __stap_arg9 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4), "ro"(arg5), "ro"(arg6), "ro"(arg7), "ro"(arg8), "ro"(arg9) -#define __stap_arg10 "ro"(arg1), "ro"(arg2), "ro"(arg3), "ro"(arg4), "ro"(arg5), "ro"(arg6), "ro"(arg7), "ro"(arg8), "ro"(arg9), "ro"(arg10) +/* Use "ron" constraint as "g" constraint sometimes gives an auto increment operand */ +#define __stap_arg1 "ron"(arg1) +#define __stap_arg2 "ron"(arg1), "ron"(arg2) +#define __stap_arg3 "ron"(arg1), "ron"(arg2), "ron"(arg3) +#define __stap_arg4 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4) +#define __stap_arg5 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4), "ron"(arg5) +#define __stap_arg6 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4), "ron"(arg5), "ron"(arg6) +#define __stap_arg7 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4), "ron"(arg5), "ron"(arg6), "ron"(arg7) +#define __stap_arg8 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4), "ron"(arg5), "ron"(arg6), "ron"(arg7), "ron"(arg8) +#define __stap_arg9 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4), "ron"(arg5), "ron"(arg6), "ron"(arg7), "ron"(arg8), "ron"(arg9) +#define __stap_arg10 "ron"(arg1), "ron"(arg2), "ron"(arg3), "ron"(arg4), "ron"(arg5), "ron"(arg6), "ron"(arg7), "ron"(arg8), "ron"(arg9), "ron"(arg10) #if defined STAP_SDT_V1 || ! defined STAP_SDT_V2 #define STAP_PROBE_POINT(provider,probe,argc,arg_format,args) \ diff --git a/tapsets.cxx b/tapsets.cxx index c2f29e6ea..8a8bf17f3 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -4541,9 +4541,15 @@ sdt_uprobe_var_expanding_visitor::visit_target_symbol (target_symbol *e) } if (argno < 1 || argno > arg_count) throw semantic_error("invalid argument number", e->tok); - bool arg_in_memory = false; + enum arg_type + { + literal_arg, + register_arg, + memory_arg + } arg_type; functioncall *fc = new functioncall; binary_expression *be = new binary_expression; + literal_number* ln; string reg; string disp_str; int disp = 0; @@ -4561,68 +4567,85 @@ sdt_uprobe_var_expanding_visitor::visit_target_symbol (target_symbol *e) if (0 != (rc = regcomp(&preg, pattern, 0))) throw semantic_error("Failed to parse probe operand"); if (0 != (rc = regexec(&preg, arg_tokens[argno-1].c_str(), nmatch, pmatch, 0))) - throw semantic_error("Unsupported assembler operand while accessing " - + probe_name + " " + e->name + " " + arg_tokens[argno-1], - e->tok); - // Is there a displacement? - if (pmatch[2].rm_so > pmatch[1].rm_so) { - string disp_str = (char*)&arg_tokens[argno-1][pmatch[1].rm_so]; - disp = lex_cast(disp_str.substr(0,pmatch[1].rm_eo - pmatch[1].rm_so)); + // Do we have a numeric literal? + // Check this separately instead of complicating the above pattern. + if (0 != (rc = regcomp(&preg, "\\$[0-9][0-9]*", 0))) + throw semantic_error("Failed to parse probe operand"); + if (0 != (rc = regexec(&preg, arg_tokens[argno-1].c_str(), nmatch, pmatch, 0))) + throw semantic_error("Unsupported assembler operand while accessing " + + probe_name + " " + e->name + " " + arg_tokens[argno-1], + e->tok); + arg_type = literal_arg; + ln = new literal_number(lex_cast(((char*)&arg_tokens[argno-1][pmatch[0].rm_so+1]))); + ln->tok = e->tok; } - // Is there an indirect register? - if ((arg_tokens[argno-1][pmatch[2].rm_so]) == '(') - arg_in_memory = true; - // Is there a register? - if (pmatch[3].rm_eo >= pmatch[3].rm_so) + else { - reg = (char*)&arg_tokens[argno-1][pmatch[3].rm_so+1]; - reg.erase(pmatch[3].rm_eo - pmatch[3].rm_so - 1); - } + // Is there a displacement? + if (pmatch[2].rm_so > pmatch[1].rm_so) + { + string disp_str = (char*)&arg_tokens[argno-1][pmatch[1].rm_so]; + disp = lex_cast(disp_str.substr(0,pmatch[1].rm_eo - pmatch[1].rm_so)); + } + // Is there an indirect register? + if ((arg_tokens[argno-1][pmatch[2].rm_so]) == '(') + arg_type = memory_arg; + else + arg_type = register_arg; + // Is there a register? + if (pmatch[3].rm_eo >= pmatch[3].rm_so) + { + reg = (char*)&arg_tokens[argno-1][pmatch[3].rm_so+1]; + reg.erase(pmatch[3].rm_eo - pmatch[3].rm_so - 1); + } + if (reg.length() == 0) + throw semantic_error("Unsupported assembler operand while accessing " + + probe_name + " " + e->name, e->tok); + // synthesize user_long(%{fetch_register(R)%} + D) + fc->function = "user_long"; + fc->tok = e->tok; + be->tok = e->tok; - if (reg.length() == 0) - throw semantic_error("Unsupported assembler operand while accessing " - + probe_name + " " + e->name, e->tok); + embedded_expr *get_arg1 = new embedded_expr; + get_arg1->tok = e->tok; + get_arg1->code = string("/* unprivileged */ /* pure */") + + (is_user_module (process_name) + ? string("u_fetch_register(") + : string("k_fetch_register(")) + + lex_cast(dwarf_regs[reg]) + string(")"); + // XXX: may we ever need to cast that to a narrower type? - // synthesize user_long(%{fetch_register(R)%} + D) - fc->function = "user_long"; - fc->tok = e->tok; - be->tok = e->tok; - - embedded_expr *get_arg1 = new embedded_expr; - get_arg1->tok = e->tok; - get_arg1->code = string("/* unprivileged */ /* pure */") - + (is_user_module (process_name) - ? string("u_fetch_register(") - : string("k_fetch_register(")) - + lex_cast(dwarf_regs[reg]) + string(")"); - // XXX: may we ever need to cast that to a narrower type? - - be->left = get_arg1; - be->op = "+"; - literal_number* inc = new literal_number(disp); - inc->tok = e->tok; - be->right = inc; - fc->args.push_back(be); + be->left = get_arg1; + be->op = "+"; + literal_number* inc = new literal_number(disp); + inc->tok = e->tok; + be->right = inc; + fc->args.push_back(be); + } if (e->components.empty()) // We have a scalar { if (e->addressof) throw semantic_error("cannot take address of sdt variable", e->tok); - if (arg_in_memory) + if (arg_type == memory_arg) provide(fc); - else + else if (arg_type == register_arg) provide(be); + else if (arg_type == literal_arg) + provide(ln); return; } cast_op *cast = new cast_op; cast->name = "@cast"; cast->tok = e->tok; - if (arg_in_memory) + if (arg_type == memory_arg) cast->operand = fc; - else + else if (arg_type == register_arg) cast->operand = be; + else if (arg_type == literal_arg) + provide(ln); cast->components = e->components; cast->type_name = probe_name + "_arg" + lex_cast(argno); cast->module = process_name; -- 2.43.5