From: Mark Wielaard Date: Thu, 28 Jul 2011 16:10:20 +0000 (+0200) Subject: Guard regparm in probe context with STAP_NEED_REGPARM. X-Git-Tag: release-1.7~155^2~53 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=309d67d89b3798146b64242889be2d662c08cde3;p=systemtap.git Guard regparm in probe context with STAP_NEED_REGPARM. regparm is only used on i386 (and x86_64 when probing 32bit) for signaling what the parameter packing is for the probed function as set in register.stp. So only include it in the probe context struct when actually used in a stap script. Also updated docs and fixed signature on other arches. --- diff --git a/stapfuncs.3stap b/stapfuncs.3stap index 345955ffc..c3541be0f 100644 --- a/stapfuncs.3stap +++ b/stapfuncs.3stap @@ -156,6 +156,8 @@ regparm:unknown (n:long) The probed function was built with the gcc \-mregparm=n option. (The i386 kernel is built with \-mregparm=3, so systemtap considers regparm(3) the default for kernel functions on that architecture.) +Only valid on i386 and x86_64 (when probing 32bit applications). +Produces an error on other architectures. For some architectures, the *_arg functions may reject unusually high values of n. diff --git a/tapset/arm/registers.stp b/tapset/arm/registers.stp index 5a64b9e0b..1f3087960 100644 --- a/tapset/arm/registers.stp +++ b/tapset/arm/registers.stp @@ -151,7 +151,7 @@ function asmlinkage() %{ /* pure */ %} function fastcall() %{ /* pure */ %} -function regparm() %{ +function regparm(n:long) %{ snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), "regparm is invalid on arm."); CONTEXT->last_error = CONTEXT->error_buffer; diff --git a/tapset/i386/registers.stp b/tapset/i386/registers.stp index c1e98ac00..5646caa29 100644 --- a/tapset/i386/registers.stp +++ b/tapset/i386/registers.stp @@ -1,3 +1,10 @@ +%{ +/* Set to include regparm field in probe context in translate.cxx. */ +#ifndef STAP_NEED_REGPARM +#define STAP_NEED_REGPARM 1 +#endif +%} + global _reg_offsets, _stp_regs_registered, _sp_offset, _ss_offset function test_x86_gs:long() %{ /* pure */ diff --git a/tapset/powerpc/registers.stp b/tapset/powerpc/registers.stp index 5d507252b..8fbfbd500 100644 --- a/tapset/powerpc/registers.stp +++ b/tapset/powerpc/registers.stp @@ -215,7 +215,7 @@ function asmlinkage() %{ /* pure */ %} function fastcall() %{ /* pure */ %} -function regparm() %{ +function regparm(n:long) %{ snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), "regparm is invalid on powerpc."); CONTEXT->last_error = CONTEXT->error_buffer; diff --git a/tapset/s390/registers.stp b/tapset/s390/registers.stp index 3215afa33..df49229b0 100644 --- a/tapset/s390/registers.stp +++ b/tapset/s390/registers.stp @@ -215,7 +215,7 @@ function asmlinkage() %{ /* pure */ %} function fastcall() %{ /* pure */ %} -function regparm() %{ +function regparm(n:long) %{ snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), "regparm is invalid on s390."); CONTEXT->last_error = CONTEXT->error_buffer; diff --git a/tapset/x86_64/registers.stp b/tapset/x86_64/registers.stp index e7abb18b7..9876c08a7 100644 --- a/tapset/x86_64/registers.stp +++ b/tapset/x86_64/registers.stp @@ -1,3 +1,10 @@ +%{ +/* Set to include regparm field in probe context in translate.cxx. */ +#ifndef STAP_NEED_REGPARM +#define STAP_NEED_REGPARM 1 +#endif +%} + global _reg_offsets, _r32_offsets, _stp_regs_registered function _stp_register_regs() { diff --git a/tapsets.cxx b/tapsets.cxx index 2984fd64b..75b94ae39 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -162,7 +162,9 @@ common_probe_entryfn_prologue (translator_output* o, string statestr, o->newline() << "c->pi = 0;"; o->newline() << "c->pi_longs = 0;"; o->newline() << "c->regflags = 0;"; + o->newline() << "#ifdef STAP_NEED_REGPARM"; // i386 or x86_64 register.stp o->newline() << "c->regparm = 0;"; + o->newline() << "#endif"; o->newline() << "c->marker_name = NULL;"; o->newline() << "c->marker_format = NULL;"; diff --git a/translate.cxx b/translate.cxx index 37de9dbd1..caf9f32a8 100644 --- a/translate.cxx +++ b/translate.cxx @@ -929,7 +929,7 @@ c_unparser::emit_common_header () o->newline() << "static atomic_t skipped_count_uprobe_reg = ATOMIC_INIT (0);"; o->newline() << "static atomic_t skipped_count_uprobe_unreg = ATOMIC_INIT (0);"; - // Defines for the regsflags field. Maybe merge with regparm field? + // Defines for the regsflags field. // _STP_REGS_USER regsflags bit to indicate regs fully from user. o->newline(); o->newline() << "#define _STP_REGS_USER_FLAG 1"; @@ -960,7 +960,9 @@ c_unparser::emit_common_header () o->newline() << "struct kretprobe_instance *pi;"; o->newline() << "int pi_longs;"; // int64_t count in pi->data, the rest is string_t o->newline() << "int regflags;"; // status of pt_regs regs field. + o->newline() << "#ifdef STAP_NEED_REGPARM"; // i386 or x86_64 register.stp o->newline() << "int regparm;"; + o->newline() << "#endif"; o->newline() << "va_list *mark_va_list;"; o->newline() << "const char * marker_name;"; o->newline() << "const char * marker_format;";