Back to home page

OSCL-LXR

 
 

    


0001 /* <sys/sdt.h> - Systemtap static probe definition macros.
0002 
0003    This file is dedicated to the public domain, pursuant to CC0
0004    (https://creativecommons.org/publicdomain/zero/1.0/)
0005 */
0006 
0007 #ifndef _SYS_SDT_H
0008 #define _SYS_SDT_H    1
0009 
0010 /*
0011   This file defines a family of macros
0012 
0013        STAP_PROBEn(op1, ..., opn)
0014 
0015   that emit a nop into the instruction stream, and some data into an auxiliary
0016   note section.  The data in the note section describes the operands, in terms
0017   of size and location.  Each location is encoded as assembler operand string.
0018   Consumer tools such as gdb or systemtap insert breakpoints on top of
0019   the nop, and decode the location operand-strings, like an assembler,
0020   to find the values being passed.
0021 
0022   The operand strings are selected by the compiler for each operand.
0023   They are constrained by gcc inline-assembler codes.  The default is:
0024 
0025   #define STAP_SDT_ARG_CONSTRAINT nor
0026 
0027   This is a good default if the operands tend to be integral and
0028   moderate in number (smaller than number of registers).  In other
0029   cases, the compiler may report "'asm' requires impossible reload" or
0030   similar.  In this case, consider simplifying the macro call (fewer
0031   and simpler operands), reduce optimization, or override the default
0032   constraints string via:
0033 
0034   #define STAP_SDT_ARG_CONSTRAINT g
0035   #include <sys/sdt.h>
0036 
0037   See also:
0038   https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation
0039   https://gcc.gnu.org/onlinedocs/gcc/Constraints.html
0040  */
0041 
0042 
0043 
0044 #ifdef __ASSEMBLER__
0045 # define _SDT_PROBE(provider, name, n, arglist) \
0046   _SDT_ASM_BODY(provider, name, _SDT_ASM_SUBSTR_1, (_SDT_DEPAREN_##n arglist)) \
0047   _SDT_ASM_BASE
0048 # define _SDT_ASM_1(x)          x;
0049 # define _SDT_ASM_2(a, b)       a,b;
0050 # define _SDT_ASM_3(a, b, c)        a,b,c;
0051 # define _SDT_ASM_5(a, b, c, d, e)  a,b,c,d,e;
0052 # define _SDT_ASM_STRING_1(x)       .asciz #x;
0053 # define _SDT_ASM_SUBSTR_1(x)       .ascii #x;
0054 # define _SDT_DEPAREN_0()               /* empty */
0055 # define _SDT_DEPAREN_1(a)              a
0056 # define _SDT_DEPAREN_2(a,b)                a b
0057 # define _SDT_DEPAREN_3(a,b,c)              a b c
0058 # define _SDT_DEPAREN_4(a,b,c,d)            a b c d
0059 # define _SDT_DEPAREN_5(a,b,c,d,e)          a b c d e
0060 # define _SDT_DEPAREN_6(a,b,c,d,e,f)            a b c d e f
0061 # define _SDT_DEPAREN_7(a,b,c,d,e,f,g)          a b c d e f g
0062 # define _SDT_DEPAREN_8(a,b,c,d,e,f,g,h)        a b c d e f g h
0063 # define _SDT_DEPAREN_9(a,b,c,d,e,f,g,h,i)      a b c d e f g h i
0064 # define _SDT_DEPAREN_10(a,b,c,d,e,f,g,h,i,j)       a b c d e f g h i j
0065 # define _SDT_DEPAREN_11(a,b,c,d,e,f,g,h,i,j,k)     a b c d e f g h i j k
0066 # define _SDT_DEPAREN_12(a,b,c,d,e,f,g,h,i,j,k,l)   a b c d e f g h i j k l
0067 #else
0068 #if defined _SDT_HAS_SEMAPHORES
0069 #define _SDT_NOTE_SEMAPHORE_USE(provider, name) \
0070   __asm__ __volatile__ ("" :: "m" (provider##_##name##_semaphore));
0071 #else
0072 #define _SDT_NOTE_SEMAPHORE_USE(provider, name)
0073 #endif
0074 
0075 # define _SDT_PROBE(provider, name, n, arglist) \
0076   do {                                      \
0077     _SDT_NOTE_SEMAPHORE_USE(provider, name); \
0078     __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \
0079               :: _SDT_ASM_OPERANDS_##n arglist);            \
0080     __asm__ __volatile__ (_SDT_ASM_BASE);                   \
0081   } while (0)
0082 # define _SDT_S(x)          #x
0083 # define _SDT_ASM_1(x)          _SDT_S(x) "\n"
0084 # define _SDT_ASM_2(a, b)       _SDT_S(a) "," _SDT_S(b) "\n"
0085 # define _SDT_ASM_3(a, b, c)        _SDT_S(a) "," _SDT_S(b) "," \
0086                     _SDT_S(c) "\n"
0087 # define _SDT_ASM_5(a, b, c, d, e)  _SDT_S(a) "," _SDT_S(b) "," \
0088                     _SDT_S(c) "," _SDT_S(d) "," \
0089                     _SDT_S(e) "\n"
0090 # define _SDT_ASM_ARGS(n)       _SDT_ASM_TEMPLATE_##n
0091 # define _SDT_ASM_STRING_1(x)       _SDT_ASM_1(.asciz #x)
0092 # define _SDT_ASM_SUBSTR_1(x)       _SDT_ASM_1(.ascii #x)
0093 
0094 # define _SDT_ARGFMT(no)                _SDT_ASM_1(_SDT_SIGN %n[_SDT_S##no]) \
0095                                         _SDT_ASM_1(_SDT_SIZE %n[_SDT_S##no]) \
0096                                         _SDT_ASM_1(_SDT_TYPE %n[_SDT_S##no]) \
0097                                         _SDT_ASM_SUBSTR(_SDT_ARGTMPL(_SDT_A##no))
0098 
0099 
0100 # ifndef STAP_SDT_ARG_CONSTRAINT
0101 # if defined __powerpc__
0102 # define STAP_SDT_ARG_CONSTRAINT        nZr
0103 # elif defined __arm__
0104 # define STAP_SDT_ARG_CONSTRAINT        g
0105 # else
0106 # define STAP_SDT_ARG_CONSTRAINT        nor
0107 # endif
0108 # endif
0109 
0110 # define _SDT_STRINGIFY(x)              #x
0111 # define _SDT_ARG_CONSTRAINT_STRING(x)  _SDT_STRINGIFY(x)
0112 /* _SDT_S encodes the size and type as 0xSSTT which is decoded by the assembler
0113    macros _SDT_SIZE and _SDT_TYPE */
0114 # define _SDT_ARG(n, x)                 \
0115   [_SDT_S##n] "n" ((_SDT_ARGSIGNED (x) ? (int)-1 : 1) * (-(((int) _SDT_ARGSIZE (x)) << 8) + (-(0x7f & __builtin_classify_type (x))))), \
0116   [_SDT_A##n] _SDT_ARG_CONSTRAINT_STRING (STAP_SDT_ARG_CONSTRAINT) (_SDT_ARGVAL (x))
0117 #endif
0118 #define _SDT_ASM_STRING(x)      _SDT_ASM_STRING_1(x)
0119 #define _SDT_ASM_SUBSTR(x)      _SDT_ASM_SUBSTR_1(x)
0120 
0121 #define _SDT_ARGARRAY(x)    (__builtin_classify_type (x) == 14  \
0122                  || __builtin_classify_type (x) == 5)
0123 
0124 #ifdef __cplusplus
0125 # define _SDT_ARGSIGNED(x)  (!_SDT_ARGARRAY (x) \
0126                  && __sdt_type<__typeof (x)>::__sdt_signed)
0127 # define _SDT_ARGSIZE(x)    (_SDT_ARGARRAY (x) \
0128                  ? sizeof (void *) : sizeof (x))
0129 # define _SDT_ARGVAL(x)     (x)
0130 
0131 # include <cstddef>
0132 
0133 template<typename __sdt_T>
0134 struct __sdt_type
0135 {
0136   static const bool __sdt_signed = false;
0137 };
0138   
0139 #define __SDT_ALWAYS_SIGNED(T) \
0140 template<> struct __sdt_type<T> { static const bool __sdt_signed = true; };
0141 #define __SDT_COND_SIGNED(T,CT)                     \
0142 template<> struct __sdt_type<T> { static const bool __sdt_signed = ((CT)(-1) < 1); };
0143 __SDT_ALWAYS_SIGNED(signed char)
0144 __SDT_ALWAYS_SIGNED(short)
0145 __SDT_ALWAYS_SIGNED(int)
0146 __SDT_ALWAYS_SIGNED(long)
0147 __SDT_ALWAYS_SIGNED(long long)
0148 __SDT_ALWAYS_SIGNED(volatile signed char)
0149 __SDT_ALWAYS_SIGNED(volatile short)
0150 __SDT_ALWAYS_SIGNED(volatile int)
0151 __SDT_ALWAYS_SIGNED(volatile long)
0152 __SDT_ALWAYS_SIGNED(volatile long long)
0153 __SDT_ALWAYS_SIGNED(const signed char)
0154 __SDT_ALWAYS_SIGNED(const short)
0155 __SDT_ALWAYS_SIGNED(const int)
0156 __SDT_ALWAYS_SIGNED(const long)
0157 __SDT_ALWAYS_SIGNED(const long long)
0158 __SDT_ALWAYS_SIGNED(const volatile signed char)
0159 __SDT_ALWAYS_SIGNED(const volatile short)
0160 __SDT_ALWAYS_SIGNED(const volatile int)
0161 __SDT_ALWAYS_SIGNED(const volatile long)
0162 __SDT_ALWAYS_SIGNED(const volatile long long)
0163 __SDT_COND_SIGNED(char, char)
0164 __SDT_COND_SIGNED(wchar_t, wchar_t)
0165 __SDT_COND_SIGNED(volatile char, char)
0166 __SDT_COND_SIGNED(volatile wchar_t, wchar_t)
0167 __SDT_COND_SIGNED(const char, char)
0168 __SDT_COND_SIGNED(const wchar_t, wchar_t)
0169 __SDT_COND_SIGNED(const volatile char, char)
0170 __SDT_COND_SIGNED(const volatile wchar_t, wchar_t)
0171 #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
0172 /* __SDT_COND_SIGNED(char16_t) */
0173 /* __SDT_COND_SIGNED(char32_t) */
0174 #endif
0175 
0176 template<typename __sdt_E>
0177 struct __sdt_type<__sdt_E[]> : public __sdt_type<__sdt_E *> {};
0178 
0179 template<typename __sdt_E, size_t __sdt_N>
0180 struct __sdt_type<__sdt_E[__sdt_N]> : public __sdt_type<__sdt_E *> {};
0181 
0182 #elif !defined(__ASSEMBLER__)
0183 __extension__ extern unsigned long long __sdt_unsp;
0184 # define _SDT_ARGINTTYPE(x)                     \
0185   __typeof (__builtin_choose_expr (((__builtin_classify_type (x)    \
0186                      + 3) & -4) == 4, (x), 0U))
0187 # define _SDT_ARGSIGNED(x)                      \
0188   (!__extension__                           \
0189    (__builtin_constant_p ((((unsigned long long)            \
0190                 (_SDT_ARGINTTYPE (x)) __sdt_unsp)       \
0191                & ((unsigned long long)1 << (sizeof (unsigned long long) \
0192                        * __CHAR_BIT__ - 1))) == 0)  \
0193     || (_SDT_ARGINTTYPE (x)) -1 > (_SDT_ARGINTTYPE (x)) 0))
0194 # define _SDT_ARGSIZE(x)    \
0195   (_SDT_ARGARRAY (x) ? sizeof (void *) : sizeof (x))
0196 # define _SDT_ARGVAL(x)     (x)
0197 #endif
0198 
0199 #if defined __powerpc__ || defined __powerpc64__
0200 # define _SDT_ARGTMPL(id)   %I[id]%[id]
0201 #elif defined __i386__
0202 # define _SDT_ARGTMPL(id)   %k[id]  /* gcc.gnu.org/PR80115 sourceware.org/PR24541 */
0203 #else
0204 # define _SDT_ARGTMPL(id)   %[id]
0205 #endif
0206 
0207 /* NB: gdb PR24541 highlighted an unspecified corner of the sdt.h
0208    operand note format.
0209 
0210    The named register may be a longer or shorter (!) alias for the
0211    storage where the value in question is found.  For example, on
0212    i386, 64-bit value may be put in register pairs, and the register
0213    name stored would identify just one of them.  Previously, gcc was
0214    asked to emit the %w[id] (16-bit alias of some registers holding
0215    operands), even when a wider 32-bit value was used.
0216 
0217    Bottom line: the byte-width given before the @ sign governs.  If
0218    there is a mismatch between that width and that of the named
0219    register, then a sys/sdt.h note consumer may need to employ
0220    architecture-specific heuristics to figure out where the compiler
0221    has actually put the complete value.
0222 */
0223 
0224 #ifdef __LP64__
0225 # define _SDT_ASM_ADDR  .8byte
0226 #else
0227 # define _SDT_ASM_ADDR  .4byte
0228 #endif
0229 
0230 /* The ia64 and s390 nop instructions take an argument. */
0231 #if defined(__ia64__) || defined(__s390__) || defined(__s390x__)
0232 #define _SDT_NOP    nop 0
0233 #else
0234 #define _SDT_NOP    nop
0235 #endif
0236 
0237 #define _SDT_NOTE_NAME  "stapsdt"
0238 #define _SDT_NOTE_TYPE  3
0239 
0240 /* If the assembler supports the necessary feature, then we can play
0241    nice with code in COMDAT sections, which comes up in C++ code.
0242    Without that assembler support, some combinations of probe placements
0243    in certain kinds of C++ code may produce link-time errors.  */
0244 #include "sdt-config.h"
0245 #if _SDT_ASM_SECTION_AUTOGROUP_SUPPORT
0246 # define _SDT_ASM_AUTOGROUP "?"
0247 #else
0248 # define _SDT_ASM_AUTOGROUP ""
0249 #endif
0250 
0251 #define _SDT_DEF_MACROS                              \
0252     _SDT_ASM_1(.altmacro)                            \
0253     _SDT_ASM_1(.macro _SDT_SIGN x)                           \
0254     _SDT_ASM_3(.pushsection .note.stapsdt,"","note")             \
0255     _SDT_ASM_1(.iflt \\x)                            \
0256     _SDT_ASM_1(.ascii "-")                           \
0257     _SDT_ASM_1(.endif)                           \
0258     _SDT_ASM_1(.popsection)                          \
0259     _SDT_ASM_1(.endm)                            \
0260     _SDT_ASM_1(.macro _SDT_SIZE_ x)                      \
0261     _SDT_ASM_3(.pushsection .note.stapsdt,"","note")             \
0262     _SDT_ASM_1(.ascii "\x")                          \
0263     _SDT_ASM_1(.popsection)                          \
0264     _SDT_ASM_1(.endm)                            \
0265     _SDT_ASM_1(.macro _SDT_SIZE x)                       \
0266     _SDT_ASM_1(_SDT_SIZE_ %%((-(-\\x*((-\\x>0)-(-\\x<0))))>>8))      \
0267     _SDT_ASM_1(.endm)                            \
0268     _SDT_ASM_1(.macro _SDT_TYPE_ x)                          \
0269     _SDT_ASM_3(.pushsection .note.stapsdt,"","note")             \
0270     _SDT_ASM_2(.ifc 8,\\x)                               \
0271     _SDT_ASM_1(.ascii "f")                           \
0272     _SDT_ASM_1(.endif)                           \
0273     _SDT_ASM_1(.ascii "@")                           \
0274     _SDT_ASM_1(.popsection)                          \
0275     _SDT_ASM_1(.endm)                            \
0276     _SDT_ASM_1(.macro _SDT_TYPE x)                           \
0277     _SDT_ASM_1(_SDT_TYPE_ %%((\\x)&(0xff)))              \
0278     _SDT_ASM_1(.endm)
0279 
0280 #define _SDT_UNDEF_MACROS                             \
0281   _SDT_ASM_1(.purgem _SDT_SIGN)                           \
0282   _SDT_ASM_1(.purgem _SDT_SIZE_)                          \
0283   _SDT_ASM_1(.purgem _SDT_SIZE)                           \
0284   _SDT_ASM_1(.purgem _SDT_TYPE_)                          \
0285   _SDT_ASM_1(.purgem _SDT_TYPE)
0286 
0287 #define _SDT_ASM_BODY(provider, name, pack_args, args, ...)           \
0288   _SDT_DEF_MACROS                                 \
0289   _SDT_ASM_1(990:   _SDT_NOP)                         \
0290   _SDT_ASM_3(       .pushsection .note.stapsdt,_SDT_ASM_AUTOGROUP,"note") \
0291   _SDT_ASM_1(       .balign 4)                        \
0292   _SDT_ASM_3(       .4byte 992f-991f, 994f-993f, _SDT_NOTE_TYPE)          \
0293   _SDT_ASM_1(991:   .asciz _SDT_NOTE_NAME)                    \
0294   _SDT_ASM_1(992:   .balign 4)                        \
0295   _SDT_ASM_1(993:   _SDT_ASM_ADDR 990b)                   \
0296   _SDT_ASM_1(       _SDT_ASM_ADDR _.stapsdt.base)                 \
0297   _SDT_SEMAPHORE(provider,name)                           \
0298   _SDT_ASM_STRING(provider)                           \
0299   _SDT_ASM_STRING(name)                               \
0300   pack_args args                                  \
0301   _SDT_ASM_SUBSTR(\x00)                               \
0302   _SDT_UNDEF_MACROS                               \
0303   _SDT_ASM_1(994:   .balign 4)                        \
0304   _SDT_ASM_1(       .popsection)
0305 
0306 #define _SDT_ASM_BASE                                 \
0307   _SDT_ASM_1(.ifndef _.stapsdt.base)                          \
0308   _SDT_ASM_5(       .pushsection .stapsdt.base,"aG","progbits",       \
0309                             .stapsdt.base,comdat) \
0310   _SDT_ASM_1(       .weak _.stapsdt.base)                     \
0311   _SDT_ASM_1(       .hidden _.stapsdt.base)                   \
0312   _SDT_ASM_1(   _.stapsdt.base: .space 1)                     \
0313   _SDT_ASM_2(       .size _.stapsdt.base, 1)                  \
0314   _SDT_ASM_1(       .popsection)                          \
0315   _SDT_ASM_1(.endif)
0316 
0317 #if defined _SDT_HAS_SEMAPHORES
0318 #define _SDT_SEMAPHORE(p,n) \
0319     _SDT_ASM_1(     _SDT_ASM_ADDR p##_##n##_semaphore)
0320 #else
0321 #define _SDT_SEMAPHORE(p,n) _SDT_ASM_1(     _SDT_ASM_ADDR 0)
0322 #endif
0323 
0324 #define _SDT_ASM_BLANK _SDT_ASM_SUBSTR(\x20)
0325 #define _SDT_ASM_TEMPLATE_0     /* no arguments */
0326 #define _SDT_ASM_TEMPLATE_1     _SDT_ARGFMT(1)
0327 #define _SDT_ASM_TEMPLATE_2     _SDT_ASM_TEMPLATE_1 _SDT_ASM_BLANK _SDT_ARGFMT(2)
0328 #define _SDT_ASM_TEMPLATE_3     _SDT_ASM_TEMPLATE_2 _SDT_ASM_BLANK _SDT_ARGFMT(3)
0329 #define _SDT_ASM_TEMPLATE_4     _SDT_ASM_TEMPLATE_3 _SDT_ASM_BLANK _SDT_ARGFMT(4)
0330 #define _SDT_ASM_TEMPLATE_5     _SDT_ASM_TEMPLATE_4 _SDT_ASM_BLANK _SDT_ARGFMT(5)
0331 #define _SDT_ASM_TEMPLATE_6     _SDT_ASM_TEMPLATE_5 _SDT_ASM_BLANK _SDT_ARGFMT(6)
0332 #define _SDT_ASM_TEMPLATE_7     _SDT_ASM_TEMPLATE_6 _SDT_ASM_BLANK _SDT_ARGFMT(7)
0333 #define _SDT_ASM_TEMPLATE_8     _SDT_ASM_TEMPLATE_7 _SDT_ASM_BLANK _SDT_ARGFMT(8)
0334 #define _SDT_ASM_TEMPLATE_9     _SDT_ASM_TEMPLATE_8 _SDT_ASM_BLANK _SDT_ARGFMT(9)
0335 #define _SDT_ASM_TEMPLATE_10        _SDT_ASM_TEMPLATE_9 _SDT_ASM_BLANK _SDT_ARGFMT(10)
0336 #define _SDT_ASM_TEMPLATE_11        _SDT_ASM_TEMPLATE_10 _SDT_ASM_BLANK _SDT_ARGFMT(11)
0337 #define _SDT_ASM_TEMPLATE_12        _SDT_ASM_TEMPLATE_11 _SDT_ASM_BLANK _SDT_ARGFMT(12)
0338 #define _SDT_ASM_OPERANDS_0()       [__sdt_dummy] "g" (0)
0339 #define _SDT_ASM_OPERANDS_1(arg1)   _SDT_ARG(1, arg1)
0340 #define _SDT_ASM_OPERANDS_2(arg1, arg2) \
0341   _SDT_ASM_OPERANDS_1(arg1), _SDT_ARG(2, arg2)
0342 #define _SDT_ASM_OPERANDS_3(arg1, arg2, arg3) \
0343   _SDT_ASM_OPERANDS_2(arg1, arg2), _SDT_ARG(3, arg3)
0344 #define _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4) \
0345   _SDT_ASM_OPERANDS_3(arg1, arg2, arg3), _SDT_ARG(4, arg4)
0346 #define _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5) \
0347   _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4), _SDT_ARG(5, arg5)
0348 #define _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
0349   _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5), _SDT_ARG(6, arg6)
0350 #define _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
0351   _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6), _SDT_ARG(7, arg7)
0352 #define _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
0353   _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7), \
0354     _SDT_ARG(8, arg8)
0355 #define _SDT_ASM_OPERANDS_9(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \
0356   _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), \
0357     _SDT_ARG(9, arg9)
0358 #define _SDT_ASM_OPERANDS_10(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \
0359   _SDT_ASM_OPERANDS_9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), \
0360     _SDT_ARG(10, arg10)
0361 #define _SDT_ASM_OPERANDS_11(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \
0362   _SDT_ASM_OPERANDS_10(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), \
0363     _SDT_ARG(11, arg11)
0364 #define _SDT_ASM_OPERANDS_12(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) \
0365   _SDT_ASM_OPERANDS_11(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), \
0366     _SDT_ARG(12, arg12)
0367 
0368 /* These macros can be used in C, C++, or assembly code.
0369    In assembly code the arguments should use normal assembly operand syntax.  */
0370 
0371 #define STAP_PROBE(provider, name) \
0372   _SDT_PROBE(provider, name, 0, ())
0373 #define STAP_PROBE1(provider, name, arg1) \
0374   _SDT_PROBE(provider, name, 1, (arg1))
0375 #define STAP_PROBE2(provider, name, arg1, arg2) \
0376   _SDT_PROBE(provider, name, 2, (arg1, arg2))
0377 #define STAP_PROBE3(provider, name, arg1, arg2, arg3) \
0378   _SDT_PROBE(provider, name, 3, (arg1, arg2, arg3))
0379 #define STAP_PROBE4(provider, name, arg1, arg2, arg3, arg4) \
0380   _SDT_PROBE(provider, name, 4, (arg1, arg2, arg3, arg4))
0381 #define STAP_PROBE5(provider, name, arg1, arg2, arg3, arg4, arg5) \
0382   _SDT_PROBE(provider, name, 5, (arg1, arg2, arg3, arg4, arg5))
0383 #define STAP_PROBE6(provider, name, arg1, arg2, arg3, arg4, arg5, arg6) \
0384   _SDT_PROBE(provider, name, 6, (arg1, arg2, arg3, arg4, arg5, arg6))
0385 #define STAP_PROBE7(provider, name, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
0386   _SDT_PROBE(provider, name, 7, (arg1, arg2, arg3, arg4, arg5, arg6, arg7))
0387 #define STAP_PROBE8(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \
0388   _SDT_PROBE(provider, name, 8, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8))
0389 #define STAP_PROBE9(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\
0390   _SDT_PROBE(provider, name, 9, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9))
0391 #define STAP_PROBE10(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \
0392   _SDT_PROBE(provider, name, 10, \
0393          (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10))
0394 #define STAP_PROBE11(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \
0395   _SDT_PROBE(provider, name, 11, \
0396          (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11))
0397 #define STAP_PROBE12(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) \
0398   _SDT_PROBE(provider, name, 12, \
0399          (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12))
0400 
0401 /* This STAP_PROBEV macro can be used in variadic scenarios, where the
0402    number of probe arguments is not known until compile time.  Since
0403    variadic macro support may vary with compiler options, you must
0404    pre-#define SDT_USE_VARIADIC to enable this type of probe.
0405 
0406    The trick to count __VA_ARGS__ was inspired by this post by
0407    Laurent Deniau <laurent.deniau@cern.ch>:
0408        http://groups.google.com/group/comp.std.c/msg/346fc464319b1ee5
0409 
0410    Note that our _SDT_NARG is called with an extra 0 arg that's not
0411    counted, so we don't have to worry about the behavior of macros
0412    called without any arguments.  */
0413 
0414 #define _SDT_NARG(...) __SDT_NARG(__VA_ARGS__, 12,11,10,9,8,7,6,5,4,3,2,1,0)
0415 #define __SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, N, ...) N
0416 #ifdef SDT_USE_VARIADIC
0417 #define _SDT_PROBE_N(provider, name, N, ...) \
0418   _SDT_PROBE(provider, name, N, (__VA_ARGS__))
0419 #define STAP_PROBEV(provider, name, ...) \
0420   _SDT_PROBE_N(provider, name, _SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__)
0421 #endif
0422 
0423 /* These macros are for use in asm statements.  You must compile
0424    with -std=gnu99 or -std=c99 to use the STAP_PROBE_ASM macro.
0425 
0426    The STAP_PROBE_ASM macro generates a quoted string to be used in the
0427    template portion of the asm statement, concatenated with strings that
0428    contain the actual assembly code around the probe site.
0429 
0430    For example:
0431 
0432     asm ("before\n"
0433          STAP_PROBE_ASM(provider, fooprobe, %eax 4(%esi))
0434          "after");
0435 
0436    emits the assembly code for "before\nafter", with a probe in between.
0437    The probe arguments are the %eax register, and the value of the memory
0438    word located 4 bytes past the address in the %esi register.  Note that
0439    because this is a simple asm, not a GNU C extended asm statement, these
0440    % characters do not need to be doubled to generate literal %reg names.
0441 
0442    In a GNU C extended asm statement, the probe arguments can be specified
0443    using the macro STAP_PROBE_ASM_TEMPLATE(n) for n arguments.  The paired
0444    macro STAP_PROBE_ASM_OPERANDS gives the C values of these probe arguments,
0445    and appears in the input operand list of the asm statement.  For example:
0446 
0447     asm ("someinsn %0,%1\n" // %0 is output operand, %1 is input operand
0448          STAP_PROBE_ASM(provider, fooprobe, STAP_PROBE_ASM_TEMPLATE(3))
0449          "otherinsn %[namedarg]"
0450          : "r" (outvar)
0451          : "g" (some_value), [namedarg] "i" (1234),
0452            STAP_PROBE_ASM_OPERANDS(3, some_value, some_ptr->field, 1234));
0453 
0454     This is just like writing:
0455 
0456     STAP_PROBE3(provider, fooprobe, some_value, some_ptr->field, 1234));
0457 
0458     but the probe site is right between "someinsn" and "otherinsn".
0459 
0460     The probe arguments in STAP_PROBE_ASM can be given as assembly
0461     operands instead, even inside a GNU C extended asm statement.
0462     Note that these can use operand templates like %0 or %[name],
0463     and likewise they must write %%reg for a literal operand of %reg.  */
0464 
0465 #define _SDT_ASM_BODY_1(p,n,...) _SDT_ASM_BODY(p,n,_SDT_ASM_SUBSTR,(__VA_ARGS__))
0466 #define _SDT_ASM_BODY_2(p,n,...) _SDT_ASM_BODY(p,n,/*_SDT_ASM_STRING */,__VA_ARGS__)
0467 #define _SDT_ASM_BODY_N2(p,n,no,...) _SDT_ASM_BODY_ ## no(p,n,__VA_ARGS__)
0468 #define _SDT_ASM_BODY_N1(p,n,no,...) _SDT_ASM_BODY_N2(p,n,no,__VA_ARGS__)
0469 #define _SDT_ASM_BODY_N(p,n,...) _SDT_ASM_BODY_N1(p,n,_SDT_NARG(0, __VA_ARGS__),__VA_ARGS__)
0470 
0471 #if __STDC_VERSION__ >= 199901L
0472 # define STAP_PROBE_ASM(provider, name, ...)        \
0473   _SDT_ASM_BODY_N(provider, name, __VA_ARGS__)                  \
0474   _SDT_ASM_BASE
0475 # define STAP_PROBE_ASM_OPERANDS(n, ...) _SDT_ASM_OPERANDS_##n(__VA_ARGS__)
0476 #else
0477 # define STAP_PROBE_ASM(provider, name, args)   \
0478   _SDT_ASM_BODY(provider, name, /* _SDT_ASM_STRING */, (args))  \
0479   _SDT_ASM_BASE
0480 #endif
0481 #define STAP_PROBE_ASM_TEMPLATE(n) _SDT_ASM_TEMPLATE_##n,"use _SDT_ASM_TEMPLATE_"
0482 
0483 
0484 /* DTrace compatible macro names.  */
0485 #define DTRACE_PROBE(provider,probe)        \
0486   STAP_PROBE(provider,probe)
0487 #define DTRACE_PROBE1(provider,probe,parm1) \
0488   STAP_PROBE1(provider,probe,parm1)
0489 #define DTRACE_PROBE2(provider,probe,parm1,parm2)   \
0490   STAP_PROBE2(provider,probe,parm1,parm2)
0491 #define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \
0492   STAP_PROBE3(provider,probe,parm1,parm2,parm3)
0493 #define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4)   \
0494   STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4)
0495 #define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \
0496   STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5)
0497 #define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \
0498   STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6)
0499 #define DTRACE_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \
0500   STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7)
0501 #define DTRACE_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \
0502   STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8)
0503 #define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \
0504   STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9)
0505 #define DTRACE_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \
0506   STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10)
0507 #define DTRACE_PROBE11(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11) \
0508   STAP_PROBE11(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11)
0509 #define DTRACE_PROBE12(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11,parm12) \
0510   STAP_PROBE12(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11,parm12)
0511 
0512 
0513 #endif /* sys/sdt.h */