/* This wrapper is used by testsuite files that do #include "sys/sdt.h". We get either the current sys/sdt.h, or sdt-compat.h. */ #if defined STAP_SDT_V1 || defined STAP_SDT_V2 #include /* Also defined in "sdt_types.h" Defined here for systemtap-testsuite */ #define UPROBE1_TYPE 0x31425250 /* "PRB1" (little-endian) */ #define UPROBE2_TYPE 0x32425055 /* "UPB2" */ #define KPROBE2_TYPE 0x3242504b /* "KPB2" */ #ifdef __LP64__ #define STAP_PROBE_ADDR(arg) "\t.quad " arg #elif defined (__BIG_ENDIAN__) #define STAP_PROBE_ADDR(arg) "\t.long 0\n\t.long " arg #else #define STAP_PROBE_ADDR(arg) "\t.long " arg #endif /* Allocated section needs to be writable when creating pic shared objects because we store relocatable addresses in them. We used to make this read only for non-pic executables, but the new semaphore support relies on having a writable .probes section to put the enabled variables in. */ #define ALLOCSEC "\"aw\"" /* An allocated section .probes that holds the probe names and addrs. */ #if defined STAP_SDT_V1 #define STAP_UPROBE_GUARD UPROBE1_TYPE #define STAP_TYPE(t) __typeof__((t)) #define STAP_CAST(t) t #define STAP_PROBE_DATA_(provider,probe,guard,arg,arg_format,args,semaphore) \ __asm__ volatile (".section .probes," ALLOCSEC "\n" \ "\t.balign 8\n" \ "1:\n\t.asciz " #probe "\n" \ "\t.balign 4\n" \ "\t.int " #guard "\n" \ "\t.balign 8\n" \ STAP_PROBE_ADDR("1b\n") \ "\t.balign 8\n" \ STAP_PROBE_ADDR(#arg "\n") \ "\t.int 0\n" \ "\t.previous\n") #elif defined STAP_SDT_V2 || ! defined STAP_SDT_V1 #define STAP_UPROBE_GUARD UPROBE2_TYPE #define STAP_TYPE(t) size_t #define STAP_CAST(t) (size_t) (t) #define STAP_PROBE_DATA_(provider,probe,guard,argc,arg_format,args,semaphore) \ __asm__ volatile (".section .probes," ALLOCSEC "\n" \ "\t.balign 8\n" \ "\t.int " #guard "\n" \ "\t.balign 8\n" \ STAP_PROBE_ADDR ("1f\n") \ "\t.balign 8\n" \ STAP_PROBE_ADDR ("2f\n") \ "\t.balign 8\n" \ STAP_PROBE_ADDR (#argc "\n") \ "\t.balign 8\n" \ STAP_PROBE_ADDR("3f\n") \ "\t.balign 8\n" \ STAP_PROBE_ADDR("4f\n") \ "\t.balign 8\n" \ STAP_PROBE_ADDR(semaphore "\n") \ "\t.balign 8\n" \ "3:\n\t.asciz " arg_format "\n" \ "\t.balign 8\n" \ "2:\n\t.asciz " #provider "\n" \ "\t.balign 8\n" \ "1:\n\t.asciz " #probe "\n" \ "\t.previous\n" :: __stap_ ## args) #endif #if defined STAP_HAS_SEMAPHORES #if defined STAP_SDT_V1 #define STAP_PROBE_DATA(provider,probe,guard,argc,arg_format,args) \ STAP_PROBE_DATA_(#provider,#probe,guard,argc,#arg_format,args,#probe "_semaphore") #elif defined STAP_SDT_V2 || ! defined STAP_SDT_V1 #define STAP_PROBE_DATA(provider,probe,guard,argc,arg_format,args) \ STAP_PROBE_DATA_(#provider,#probe,guard,argc,#arg_format,args,#provider "_" #probe "_semaphore") #endif #else #define STAP_PROBE_DATA(provider,probe,guard,argc,arg_format,args) \ STAP_PROBE_DATA_(#provider,#probe,guard,argc,#arg_format,args,"") #endif /* Taking the address of a local label and/or referencing alloca prevents the containing function from being inlined, which keeps the parameters visible. */ #if __GNUC__ == 4 && __GNUC_MINOR__ <= 1 #include #define STAP_UNINLINE alloca((size_t)0) #else #define STAP_UNINLINE #endif /* The ia64 and s390 nop instructions take an argument. */ #if defined(__ia64__) || defined(__s390__) || defined(__s390x__) #define STAP_NOP "\tnop 0 " #else #define STAP_NOP "\tnop " #endif #ifndef STAP_SDT_VOLATILE /* allow users to override */ #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 5 \ || (defined __GNUC_RH_RELEASE__ \ && __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 3 \ && (__GNUC_PATCHLEVEL__ > 3 || __GNUC_RH_RELEASE__ >= 10))) #define STAP_SDT_VOLATILE #else #define STAP_SDT_VOLATILE volatile #endif #endif /* https://bugzilla.redhat.com/show_bug.cgi?id=608768 / http://gcc.gnu.org/PR44707 indicate that "g" is a good general register constraint for these operands, except on AUTO_INC_DEC targets. Let's prefer "g" on fixed compilers and on other architectures. The #if monstrosity was coded by Jakub Jalinek. */ #if defined (__i386__) || defined (__x86_64__) \ || defined (__sparc__) || defined (__s390__) \ || (__GNUC__ > 4) \ || (__GNUC__ == 4 \ && (__GNUC_MINOR__ >= 6 \ || (defined __GNUC_RH_RELEASE__ \ && (__GNUC_MINOR__ > 4 \ || (__GNUC_MINOR__ == 4 \ && (__GNUC_PATCHLEVEL__ > 4 \ || (__GNUC_PATCHLEVEL__ == 4 \ && __GNUC_RH_RELEASE__ >= 9))))))) #define STAP_G_CONSTRAINT "g" #else #define STAP_G_CONSTRAINT "nro" #endif /* variadic macro args not allowed by -ansi -pedantic so... */ /* Use "ron" constraint as "g" constraint sometimes gives an auto increment operand */ #define __stap_arg0 #define __stap_arg1 STAP_G_CONSTRAINT(arg1) #define __stap_arg2 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2) #define __stap_arg3 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3) #define __stap_arg4 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4) #define __stap_arg5 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4), STAP_G_CONSTRAINT(arg5) #define __stap_arg6 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4), STAP_G_CONSTRAINT(arg5), STAP_G_CONSTRAINT(arg6) #define __stap_arg7 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4), STAP_G_CONSTRAINT(arg5), STAP_G_CONSTRAINT(arg6), STAP_G_CONSTRAINT(arg7) #define __stap_arg8 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4), STAP_G_CONSTRAINT(arg5), STAP_G_CONSTRAINT(arg6), STAP_G_CONSTRAINT(arg7), STAP_G_CONSTRAINT(arg8) #define __stap_arg9 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4), STAP_G_CONSTRAINT(arg5), STAP_G_CONSTRAINT(arg6), STAP_G_CONSTRAINT(arg7), STAP_G_CONSTRAINT(arg8), STAP_G_CONSTRAINT(arg9) #define __stap_arg10 STAP_G_CONSTRAINT(arg1), STAP_G_CONSTRAINT(arg2), STAP_G_CONSTRAINT(arg3), STAP_G_CONSTRAINT(arg4), STAP_G_CONSTRAINT(arg5), STAP_G_CONSTRAINT(arg6), STAP_G_CONSTRAINT(arg7), STAP_G_CONSTRAINT(arg8), STAP_G_CONSTRAINT(arg9), STAP_G_CONSTRAINT(arg10) #if defined STAP_SDT_V1 #define STAP_PROBE_POINT(provider,probe,argc,arg_format,args) \ STAP_UNINLINE; \ STAP_PROBE_DATA(provider,probe,STAP_UPROBE_GUARD,2f,nil,nil); \ __asm__ volatile ("2:\n" STAP_NOP "/* " arg_format " */" :: __stap_ ## args); #define STAP_PROBE(provider,probe) \ do { \ STAP_PROBE_DATA(provider,probe,STAP_UPROBE_GUARD,2f,nil,nil); \ __asm__ volatile ("2:\n" STAP_NOP); \ } while (0) #elif defined STAP_SDT_V2 || ! defined STAP_SDT_V1 #define STAP_PROBE_POINT(provider,probe,argc,arg_format,args) \ STAP_UNINLINE; \ STAP_PROBE_DATA(provider,probe,STAP_UPROBE_GUARD,argc,arg_format,args); \ __asm__ volatile ("4:\n" STAP_NOP); #define STAP_PROBE(provider,probe) \ do { \ STAP_PROBE_DATA(provider,probe,STAP_UPROBE_GUARD,0,"",arg0); \ __asm__ volatile ("4:\n" STAP_NOP); \ } while (0) #endif #define STAP_PROBE1(provider,probe,parm1) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_PROBE_POINT(provider,probe, 1, "%0", arg1) \ } while (0) #define STAP_PROBE2(provider,probe,parm1,parm2) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_PROBE_POINT(provider,probe, 2, "%0 %1", arg2); \ } while (0) #define STAP_PROBE3(provider,probe,parm1,parm2,parm3) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_PROBE_POINT(provider,probe, 3, "%0 %1 %2", arg3); \ } while (0) #define STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = STAP_CAST(parm4); \ STAP_PROBE_POINT(provider,probe, 4, "%0 %1 %2 %3", arg4); \ } while (0) #define STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = STAP_CAST(parm4); \ STAP_SDT_VOLATILE STAP_TYPE(parm5) arg5 = STAP_CAST(parm5); \ STAP_PROBE_POINT(provider,probe, 5, "%0 %1 %2 %3 %4", arg5); \ } while (0) #define STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = STAP_CAST(parm4); \ STAP_SDT_VOLATILE STAP_TYPE(parm5) arg5 = STAP_CAST(parm5); \ STAP_SDT_VOLATILE STAP_TYPE(parm6) arg6 = STAP_CAST(parm6); \ STAP_PROBE_POINT(provider,probe, 6, "%0 %1 %2 %3 %4 %5", arg6); \ } while (0) #define STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = STAP_CAST(parm4); \ STAP_SDT_VOLATILE STAP_TYPE(parm5) arg5 = STAP_CAST(parm5); \ STAP_SDT_VOLATILE STAP_TYPE(parm6) arg6 = STAP_CAST(parm6); \ STAP_SDT_VOLATILE STAP_TYPE(parm7) arg7 = STAP_CAST(parm7); \ STAP_PROBE_POINT(provider,probe, 7, "%0 %1 %2 %3 %4 %5 %6", arg7); \ } while (0) #define STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = STAP_CAST(parm4); \ STAP_SDT_VOLATILE STAP_TYPE(parm5) arg5 = STAP_CAST(parm5); \ STAP_SDT_VOLATILE STAP_TYPE(parm6) arg6 = STAP_CAST(parm6); \ STAP_SDT_VOLATILE STAP_TYPE(parm7) arg7 = STAP_CAST(parm7); \ STAP_SDT_VOLATILE STAP_TYPE(parm8) arg8 = STAP_CAST(parm8); \ STAP_PROBE_POINT(provider,probe, 8, "%0 %1 %2 %3 %4 %5 %6 %7", arg8); \ } while (0) #define STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = STAP_CAST(parm1); \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = STAP_CAST(parm2); \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = STAP_CAST(parm3); \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = STAP_CAST(parm4); \ STAP_SDT_VOLATILE STAP_TYPE(parm5) arg5 = STAP_CAST(parm5); \ STAP_SDT_VOLATILE STAP_TYPE(parm6) arg6 = STAP_CAST(parm6); \ STAP_SDT_VOLATILE STAP_TYPE(parm7) arg7 = STAP_CAST(parm7); \ STAP_SDT_VOLATILE STAP_TYPE(parm8) arg8 = STAP_CAST(parm8); \ STAP_SDT_VOLATILE STAP_TYPE(parm9) arg9 = STAP_CAST(parm9); \ STAP_PROBE_POINT(provider,probe, 9, "%0 %1 %2 %3 %4 %5 %6 %7 %8", arg9); \ } while (0) #define STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ do { STAP_SDT_VOLATILE STAP_TYPE(parm1) arg1 = parm1; \ STAP_SDT_VOLATILE STAP_TYPE(parm2) arg2 = parm2; \ STAP_SDT_VOLATILE STAP_TYPE(parm3) arg3 = parm3; \ STAP_SDT_VOLATILE STAP_TYPE(parm4) arg4 = parm4; \ STAP_SDT_VOLATILE STAP_TYPE(parm5) arg5 = parm5; \ STAP_SDT_VOLATILE STAP_TYPE(parm6) arg6 = parm6; \ STAP_SDT_VOLATILE STAP_TYPE(parm7) arg7 = parm7; \ STAP_SDT_VOLATILE STAP_TYPE(parm8) arg8 = parm8; \ STAP_SDT_VOLATILE STAP_TYPE(parm9) arg9 = parm9; \ STAP_SDT_VOLATILE STAP_TYPE(parm10) arg10 = parm10; \ STAP_PROBE_POINT(provider,probe, 10, "%0 %1 %2 %3 %4 %5 %6 %7 %8 %9", arg10); \ } while (0) #define DTRACE_PROBE(provider,probe) \ STAP_PROBE(provider,probe) #define DTRACE_PROBE1(provider,probe,parm1) \ STAP_PROBE1(provider,probe,parm1) #define DTRACE_PROBE2(provider,probe,parm1,parm2) \ STAP_PROBE2(provider,probe,parm1,parm2) #define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \ STAP_PROBE3(provider,probe,parm1,parm2,parm3) #define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) #define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) #define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) #define DTRACE_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) #define DTRACE_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) #define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) #define DTRACE_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) #else # include_next #endif