1 /* <sys/sdt.h> - Systemtap static probe definition macros. 2 3 This file is dedicated to the public domain, pursuant to CC0 4 (https://creativecommons.org/publicdomain/zero/1.0/) 5 */ 6 7 #ifndef _SYS_SDT_H 8 #define _SYS_SDT_H 1 9 10 /* 11 This file defines a family of macros 12 13 STAP_PROBEn(op1, ..., opn) 14 15 that emit a nop into the instruction stream, and some data into an auxiliary 16 note section. The data in the note section describes the operands, in terms 17 of size and location. Each location is encoded as assembler operand string. 18 Consumer tools such as gdb or systemtap insert breakpoints on top of 19 the nop, and decode the location operand-strings, like an assembler, 20 to find the values being passed. 21 22 The operand strings are selected by the compiler for each operand. 23 They are constrained by gcc inline-assembler codes. The default is: 24 25 #define STAP_SDT_ARG_CONSTRAINT nor 26 27 This is a good default if the operands tend to be integral and 28 moderate in number (smaller than number of registers). In other 29 cases, the compiler may report "'asm' requires impossible reload" or 30 similar. In this case, consider simplifying the macro call (fewer 31 and simpler operands), reduce optimization, or override the default 32 constraints string via: 33 34 #define STAP_SDT_ARG_CONSTRAINT g 35 #include <sys/sdt.h> 36 37 See also: 38 https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation 39 https://gcc.gnu.org/onlinedocs/gcc/Constraints.html 40 */ 41 42 43 44 #ifdef __ASSEMBLER__ 45 # define _SDT_PROBE(provider, name, n, arglist) \ 46 _SDT_ASM_BODY(provider, name, _SDT_ASM_SUBSTR_1, (_SDT_DEPAREN_##n arglist)) \ 47 _SDT_ASM_BASE 48 # define _SDT_ASM_1(x) x; 49 # define _SDT_ASM_2(a, b) a,b; 50 # define _SDT_ASM_3(a, b, c) a,b,c; 51 # define _SDT_ASM_5(a, b, c, d, e) a,b,c,d,e; 52 # define _SDT_ASM_STRING_1(x) .asciz #x; 53 # define _SDT_ASM_SUBSTR_1(x) .ascii #x; 54 # define _SDT_DEPAREN_0() /* empty */ 55 # define _SDT_DEPAREN_1(a) a 56 # define _SDT_DEPAREN_2(a,b) a b 57 # define _SDT_DEPAREN_3(a,b,c) a b c 58 # define _SDT_DEPAREN_4(a,b,c,d) a b c d 59 # define _SDT_DEPAREN_5(a,b,c,d,e) a b c d e 60 # define _SDT_DEPAREN_6(a,b,c,d,e,f) a b c d e f 61 # define _SDT_DEPAREN_7(a,b,c,d,e,f,g) a b c d e f g 62 # define _SDT_DEPAREN_8(a,b,c,d,e,f,g,h) a b c d e f g h 63 # define _SDT_DEPAREN_9(a,b,c,d,e,f,g,h,i) a b c d e f g h i 64 # define _SDT_DEPAREN_10(a,b,c,d,e,f,g,h,i,j) a b c d e f g h i j 65 # 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 66 # 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 67 #else 68 #if defined _SDT_HAS_SEMAPHORES 69 #define _SDT_NOTE_SEMAPHORE_USE(provider, name) \ 70 __asm__ __volatile__ ("" :: "m" (provider##_##name##_semaphore)); 71 #else 72 #define _SDT_NOTE_SEMAPHORE_USE(provider, name) 73 #endif 74 75 # define _SDT_PROBE(provider, name, n, arglist) \ 76 do { \ 77 _SDT_NOTE_SEMAPHORE_USE(provider, name); \ 78 __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \ 79 :: _SDT_ASM_OPERANDS_##n arglist); \ 80 __asm__ __volatile__ (_SDT_ASM_BASE); \ 81 } while (0) 82 # define _SDT_S(x) #x 83 # define _SDT_ASM_1(x) _SDT_S(x) "\n" 84 # define _SDT_ASM_2(a, b) _SDT_S(a) "," _SDT_S(b) "\n" 85 # define _SDT_ASM_3(a, b, c) _SDT_S(a) "," _SDT_S(b) "," \ 86 _SDT_S(c) "\n" 87 # define _SDT_ASM_5(a, b, c, d, e) _SDT_S(a) "," _SDT_S(b) "," \ 88 _SDT_S(c) "," _SDT_S(d) "," \ 89 _SDT_S(e) "\n" 90 # define _SDT_ASM_ARGS(n) _SDT_ASM_TEMPLATE_##n 91 # define _SDT_ASM_STRING_1(x) _SDT_ASM_1(.asciz #x) 92 # define _SDT_ASM_SUBSTR_1(x) _SDT_ASM_1(.ascii #x) 93 94 # define _SDT_ARGFMT(no) _SDT_ASM_1(_SDT_SIGN %n[_SDT_S##no]) \ 95 _SDT_ASM_1(_SDT_SIZE %n[_SDT_S##no]) \ 96 _SDT_ASM_1(_SDT_TYPE %n[_SDT_S##no]) \ 97 _SDT_ASM_SUBSTR(_SDT_ARGTMPL(_SDT_A##no)) 98 99 100 # ifndef STAP_SDT_ARG_CONSTRAINT 101 # if defined __powerpc__ 102 # define STAP_SDT_ARG_CONSTRAINT nZr 103 # elif defined __arm__ 104 # define STAP_SDT_ARG_CONSTRAINT g 105 # elif defined __loongarch__ 106 # define STAP_SDT_ARG_CONSTRAINT nmr 107 # else 108 # define STAP_SDT_ARG_CONSTRAINT nor 109 # endif 110 # endif 111 112 # define _SDT_STRINGIFY(x) #x 113 # define _SDT_ARG_CONSTRAINT_STRING(x) _SDT_STRINGIFY(x) 114 /* _SDT_S encodes the size and type as 0xSSTT which is decoded by the assembler 115 macros _SDT_SIZE and _SDT_TYPE */ 116 # define _SDT_ARG(n, x) \ 117 [_SDT_S##n] "n" ((_SDT_ARGSIGNED (x) ? (int)-1 : 1) * (-(((int) _SDT_ARGSIZE (x)) << 8) + (-(0x7f & __builtin_classify_type (x))))), \ 118 [_SDT_A##n] _SDT_ARG_CONSTRAINT_STRING (STAP_SDT_ARG_CONSTRAINT) (_SDT_ARGVAL (x)) 119 #endif 120 #define _SDT_ASM_STRING(x) _SDT_ASM_STRING_1(x) 121 #define _SDT_ASM_SUBSTR(x) _SDT_ASM_SUBSTR_1(x) 122 123 #define _SDT_ARGARRAY(x) (__builtin_classify_type (x) == 14 \ 124 || __builtin_classify_type (x) == 5) 125 126 #ifdef __cplusplus 127 # define _SDT_ARGSIGNED(x) (!_SDT_ARGARRAY (x) \ 128 && __sdt_type<__typeof (x)>::__sdt_signed) 129 # define _SDT_ARGSIZE(x) (_SDT_ARGARRAY (x) \ 130 ? sizeof (void *) : sizeof (x)) 131 # define _SDT_ARGVAL(x) (x) 132 133 # include <cstddef> 134 135 template<typename __sdt_T> 136 struct __sdt_type 137 { 138 static const bool __sdt_signed = false; 139 }; 140 141 #define __SDT_ALWAYS_SIGNED(T) \ 142 template<> struct __sdt_type<T> { static const bool __sdt_signed = true; }; 143 #define __SDT_COND_SIGNED(T,CT) \ 144 template<> struct __sdt_type<T> { static const bool __sdt_signed = ((CT)(-1) < 1); }; 145 __SDT_ALWAYS_SIGNED(signed char) 146 __SDT_ALWAYS_SIGNED(short) 147 __SDT_ALWAYS_SIGNED(int) 148 __SDT_ALWAYS_SIGNED(long) 149 __SDT_ALWAYS_SIGNED(long long) 150 __SDT_ALWAYS_SIGNED(volatile signed char) 151 __SDT_ALWAYS_SIGNED(volatile short) 152 __SDT_ALWAYS_SIGNED(volatile int) 153 __SDT_ALWAYS_SIGNED(volatile long) 154 __SDT_ALWAYS_SIGNED(volatile long long) 155 __SDT_ALWAYS_SIGNED(const signed char) 156 __SDT_ALWAYS_SIGNED(const short) 157 __SDT_ALWAYS_SIGNED(const int) 158 __SDT_ALWAYS_SIGNED(const long) 159 __SDT_ALWAYS_SIGNED(const long long) 160 __SDT_ALWAYS_SIGNED(const volatile signed char) 161 __SDT_ALWAYS_SIGNED(const volatile short) 162 __SDT_ALWAYS_SIGNED(const volatile int) 163 __SDT_ALWAYS_SIGNED(const volatile long) 164 __SDT_ALWAYS_SIGNED(const volatile long long) 165 __SDT_COND_SIGNED(char, char) 166 __SDT_COND_SIGNED(wchar_t, wchar_t) 167 __SDT_COND_SIGNED(volatile char, char) 168 __SDT_COND_SIGNED(volatile wchar_t, wchar_t) 169 __SDT_COND_SIGNED(const char, char) 170 __SDT_COND_SIGNED(const wchar_t, wchar_t) 171 __SDT_COND_SIGNED(const volatile char, char) 172 __SDT_COND_SIGNED(const volatile wchar_t, wchar_t) 173 #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) 174 /* __SDT_COND_SIGNED(char16_t) */ 175 /* __SDT_COND_SIGNED(char32_t) */ 176 #endif 177 178 template<typename __sdt_E> 179 struct __sdt_type<__sdt_E[]> : public __sdt_type<__sdt_E *> {}; 180 181 template<typename __sdt_E, size_t __sdt_N> 182 struct __sdt_type<__sdt_E[__sdt_N]> : public __sdt_type<__sdt_E *> {}; 183 184 #elif !defined(__ASSEMBLER__) 185 __extension__ extern unsigned long long __sdt_unsp; 186 # define _SDT_ARGINTTYPE(x) \ 187 __typeof (__builtin_choose_expr (((__builtin_classify_type (x) \ 188 + 3) & -4) == 4, (x), 0U)) 189 # define _SDT_ARGSIGNED(x) \ 190 (!__extension__ \ 191 (__builtin_constant_p ((((unsigned long long) \ 192 (_SDT_ARGINTTYPE (x)) __sdt_unsp) \ 193 & ((unsigned long long)1 << (sizeof (unsigned long long) \ 194 * __CHAR_BIT__ - 1))) == 0) \ 195 || (_SDT_ARGINTTYPE (x)) -1 > (_SDT_ARGINTTYPE (x)) 0)) 196 # define _SDT_ARGSIZE(x) \ 197 (_SDT_ARGARRAY (x) ? sizeof (void *) : sizeof (x)) 198 # define _SDT_ARGVAL(x) (x) 199 #endif 200 201 #if defined __powerpc__ || defined __powerpc64__ 202 # define _SDT_ARGTMPL(id) %I[id]%[id] 203 #elif defined __i386__ 204 # define _SDT_ARGTMPL(id) %k[id] /* gcc.gnu.org/PR80115 sourceware.org/PR24541 */ 205 #else 206 # define _SDT_ARGTMPL(id) %[id] 207 #endif 208 209 /* NB: gdb PR24541 highlighted an unspecified corner of the sdt.h 210 operand note format. 211 212 The named register may be a longer or shorter (!) alias for the 213 storage where the value in question is found. For example, on 214 i386, 64-bit value may be put in register pairs, and the register 215 name stored would identify just one of them. Previously, gcc was 216 asked to emit the %w[id] (16-bit alias of some registers holding 217 operands), even when a wider 32-bit value was used. 218 219 Bottom line: the byte-width given before the @ sign governs. If 220 there is a mismatch between that width and that of the named 221 register, then a sys/sdt.h note consumer may need to employ 222 architecture-specific heuristics to figure out where the compiler 223 has actually put the complete value. 224 */ 225 226 #ifdef __LP64__ 227 # define _SDT_ASM_ADDR .8byte 228 #else 229 # define _SDT_ASM_ADDR .4byte 230 #endif 231 232 /* The ia64 and s390 nop instructions take an argument. */ 233 #if defined(__ia64__) || defined(__s390__) || defined(__s390x__) 234 #define _SDT_NOP nop 0 235 #else 236 #define _SDT_NOP nop 237 #endif 238 239 #define _SDT_NOTE_NAME "stapsdt" 240 #define _SDT_NOTE_TYPE 3 241 242 /* If the assembler supports the necessary feature, then we can play 243 nice with code in COMDAT sections, which comes up in C++ code. 244 Without that assembler support, some combinations of probe placements 245 in certain kinds of C++ code may produce link-time errors. */ 246 #include "sdt-config.h" 247 #if _SDT_ASM_SECTION_AUTOGROUP_SUPPORT 248 # define _SDT_ASM_AUTOGROUP "?" 249 #else 250 # define _SDT_ASM_AUTOGROUP "" 251 #endif 252 253 #define _SDT_DEF_MACROS \ 254 _SDT_ASM_1(.altmacro) \ 255 _SDT_ASM_1(.macro _SDT_SIGN x) \ 256 _SDT_ASM_3(.pushsection .note.stapsdt,"","note") \ 257 _SDT_ASM_1(.iflt \\x) \ 258 _SDT_ASM_1(.ascii "-") \ 259 _SDT_ASM_1(.endif) \ 260 _SDT_ASM_1(.popsection) \ 261 _SDT_ASM_1(.endm) \ 262 _SDT_ASM_1(.macro _SDT_SIZE_ x) \ 263 _SDT_ASM_3(.pushsection .note.stapsdt,"","note") \ 264 _SDT_ASM_1(.ascii "\x") \ 265 _SDT_ASM_1(.popsection) \ 266 _SDT_ASM_1(.endm) \ 267 _SDT_ASM_1(.macro _SDT_SIZE x) \ 268 _SDT_ASM_1(_SDT_SIZE_ %%((-(-\\x*((-\\x>0)-(-\\x<0))))>>8)) \ 269 _SDT_ASM_1(.endm) \ 270 _SDT_ASM_1(.macro _SDT_TYPE_ x) \ 271 _SDT_ASM_3(.pushsection .note.stapsdt,"","note") \ 272 _SDT_ASM_2(.ifc 8,\\x) \ 273 _SDT_ASM_1(.ascii "f") \ 274 _SDT_ASM_1(.endif) \ 275 _SDT_ASM_1(.ascii "@") \ 276 _SDT_ASM_1(.popsection) \ 277 _SDT_ASM_1(.endm) \ 278 _SDT_ASM_1(.macro _SDT_TYPE x) \ 279 _SDT_ASM_1(_SDT_TYPE_ %%((\\x)&(0xff))) \ 280 _SDT_ASM_1(.endm) 281 282 #define _SDT_UNDEF_MACROS \ 283 _SDT_ASM_1(.purgem _SDT_SIGN) \ 284 _SDT_ASM_1(.purgem _SDT_SIZE_) \ 285 _SDT_ASM_1(.purgem _SDT_SIZE) \ 286 _SDT_ASM_1(.purgem _SDT_TYPE_) \ 287 _SDT_ASM_1(.purgem _SDT_TYPE) 288 289 #define _SDT_ASM_BODY(provider, name, pack_args, args, ...) \ 290 _SDT_DEF_MACROS \ 291 _SDT_ASM_1(990: _SDT_NOP) \ 292 _SDT_ASM_3( .pushsection .note.stapsdt,_SDT_ASM_AUTOGROUP,"note") \ 293 _SDT_ASM_1( .balign 4) \ 294 _SDT_ASM_3( .4byte 992f-991f, 994f-993f, _SDT_NOTE_TYPE) \ 295 _SDT_ASM_1(991: .asciz _SDT_NOTE_NAME) \ 296 _SDT_ASM_1(992: .balign 4) \ 297 _SDT_ASM_1(993: _SDT_ASM_ADDR 990b) \ 298 _SDT_ASM_1( _SDT_ASM_ADDR _.stapsdt.base) \ 299 _SDT_SEMAPHORE(provider,name) \ 300 _SDT_ASM_STRING(provider) \ 301 _SDT_ASM_STRING(name) \ 302 pack_args args \ 303 _SDT_ASM_SUBSTR(\x00) \ 304 _SDT_UNDEF_MACROS \ 305 _SDT_ASM_1(994: .balign 4) \ 306 _SDT_ASM_1( .popsection) 307 308 #define _SDT_ASM_BASE \ 309 _SDT_ASM_1(.ifndef _.stapsdt.base) \ 310 _SDT_ASM_5( .pushsection .stapsdt.base,"aG","progbits", \ 311 .stapsdt.base,comdat) \ 312 _SDT_ASM_1( .weak _.stapsdt.base) \ 313 _SDT_ASM_1( .hidden _.stapsdt.base) \ 314 _SDT_ASM_1( _.stapsdt.base: .space 1) \ 315 _SDT_ASM_2( .size _.stapsdt.base, 1) \ 316 _SDT_ASM_1( .popsection) \ 317 _SDT_ASM_1(.endif) 318 319 #if defined _SDT_HAS_SEMAPHORES 320 #define _SDT_SEMAPHORE(p,n) \ 321 _SDT_ASM_1( _SDT_ASM_ADDR p##_##n##_semaphore) 322 #else 323 #define _SDT_SEMAPHORE(p,n) _SDT_ASM_1( _SDT_ASM_ADDR 0) 324 #endif 325 326 #define _SDT_ASM_BLANK _SDT_ASM_SUBSTR(\x20) 327 #define _SDT_ASM_TEMPLATE_0 /* no arguments */ 328 #define _SDT_ASM_TEMPLATE_1 _SDT_ARGFMT(1) 329 #define _SDT_ASM_TEMPLATE_2 _SDT_ASM_TEMPLATE_1 _SDT_ASM_BLANK _SDT_ARGFMT(2) 330 #define _SDT_ASM_TEMPLATE_3 _SDT_ASM_TEMPLATE_2 _SDT_ASM_BLANK _SDT_ARGFMT(3) 331 #define _SDT_ASM_TEMPLATE_4 _SDT_ASM_TEMPLATE_3 _SDT_ASM_BLANK _SDT_ARGFMT(4) 332 #define _SDT_ASM_TEMPLATE_5 _SDT_ASM_TEMPLATE_4 _SDT_ASM_BLANK _SDT_ARGFMT(5) 333 #define _SDT_ASM_TEMPLATE_6 _SDT_ASM_TEMPLATE_5 _SDT_ASM_BLANK _SDT_ARGFMT(6) 334 #define _SDT_ASM_TEMPLATE_7 _SDT_ASM_TEMPLATE_6 _SDT_ASM_BLANK _SDT_ARGFMT(7) 335 #define _SDT_ASM_TEMPLATE_8 _SDT_ASM_TEMPLATE_7 _SDT_ASM_BLANK _SDT_ARGFMT(8) 336 #define _SDT_ASM_TEMPLATE_9 _SDT_ASM_TEMPLATE_8 _SDT_ASM_BLANK _SDT_ARGFMT(9) 337 #define _SDT_ASM_TEMPLATE_10 _SDT_ASM_TEMPLATE_9 _SDT_ASM_BLANK _SDT_ARGFMT(10) 338 #define _SDT_ASM_TEMPLATE_11 _SDT_ASM_TEMPLATE_10 _SDT_ASM_BLANK _SDT_ARGFMT(11) 339 #define _SDT_ASM_TEMPLATE_12 _SDT_ASM_TEMPLATE_11 _SDT_ASM_BLANK _SDT_ARGFMT(12) 340 #define _SDT_ASM_OPERANDS_0() [__sdt_dummy] "g" (0) 341 #define _SDT_ASM_OPERANDS_1(arg1) _SDT_ARG(1, arg1) 342 #define _SDT_ASM_OPERANDS_2(arg1, arg2) \ 343 _SDT_ASM_OPERANDS_1(arg1), _SDT_ARG(2, arg2) 344 #define _SDT_ASM_OPERANDS_3(arg1, arg2, arg3) \ 345 _SDT_ASM_OPERANDS_2(arg1, arg2), _SDT_ARG(3, arg3) 346 #define _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4) \ 347 _SDT_ASM_OPERANDS_3(arg1, arg2, arg3), _SDT_ARG(4, arg4) 348 #define _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5) \ 349 _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4), _SDT_ARG(5, arg5) 350 #define _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ 351 _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5), _SDT_ARG(6, arg6) 352 #define _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ 353 _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6), _SDT_ARG(7, arg7) 354 #define _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ 355 _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7), \ 356 _SDT_ARG(8, arg8) 357 #define _SDT_ASM_OPERANDS_9(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \ 358 _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), \ 359 _SDT_ARG(9, arg9) 360 #define _SDT_ASM_OPERANDS_10(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \ 361 _SDT_ASM_OPERANDS_9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), \ 362 _SDT_ARG(10, arg10) 363 #define _SDT_ASM_OPERANDS_11(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \ 364 _SDT_ASM_OPERANDS_10(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), \ 365 _SDT_ARG(11, arg11) 366 #define _SDT_ASM_OPERANDS_12(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) \ 367 _SDT_ASM_OPERANDS_11(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), \ 368 _SDT_ARG(12, arg12) 369 370 /* These macros can be used in C, C++, or assembly code. 371 In assembly code the arguments should use normal assembly operand syntax. */ 372 373 #define STAP_PROBE(provider, name) \ 374 _SDT_PROBE(provider, name, 0, ()) 375 #define STAP_PROBE1(provider, name, arg1) \ 376 _SDT_PROBE(provider, name, 1, (arg1)) 377 #define STAP_PROBE2(provider, name, arg1, arg2) \ 378 _SDT_PROBE(provider, name, 2, (arg1, arg2)) 379 #define STAP_PROBE3(provider, name, arg1, arg2, arg3) \ 380 _SDT_PROBE(provider, name, 3, (arg1, arg2, arg3)) 381 #define STAP_PROBE4(provider, name, arg1, arg2, arg3, arg4) \ 382 _SDT_PROBE(provider, name, 4, (arg1, arg2, arg3, arg4)) 383 #define STAP_PROBE5(provider, name, arg1, arg2, arg3, arg4, arg5) \ 384 _SDT_PROBE(provider, name, 5, (arg1, arg2, arg3, arg4, arg5)) 385 #define STAP_PROBE6(provider, name, arg1, arg2, arg3, arg4, arg5, arg6) \ 386 _SDT_PROBE(provider, name, 6, (arg1, arg2, arg3, arg4, arg5, arg6)) 387 #define STAP_PROBE7(provider, name, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ 388 _SDT_PROBE(provider, name, 7, (arg1, arg2, arg3, arg4, arg5, arg6, arg7)) 389 #define STAP_PROBE8(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \ 390 _SDT_PROBE(provider, name, 8, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) 391 #define STAP_PROBE9(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\ 392 _SDT_PROBE(provider, name, 9, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)) 393 #define STAP_PROBE10(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \ 394 _SDT_PROBE(provider, name, 10, \ 395 (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)) 396 #define STAP_PROBE11(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \ 397 _SDT_PROBE(provider, name, 11, \ 398 (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11)) 399 #define STAP_PROBE12(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) \ 400 _SDT_PROBE(provider, name, 12, \ 401 (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12)) 402 403 /* This STAP_PROBEV macro can be used in variadic scenarios, where the 404 number of probe arguments is not known until compile time. Since 405 variadic macro support may vary with compiler options, you must 406 pre-#define SDT_USE_VARIADIC to enable this type of probe. 407 408 The trick to count __VA_ARGS__ was inspired by this post by 409 Laurent Deniau <laurent.deniau@cern.ch>: 410 http://groups.google.com/group/comp.std.c/msg/346fc464319b1ee5 411 412 Note that our _SDT_NARG is called with an extra 0 arg that's not 413 counted, so we don't have to worry about the behavior of macros 414 called without any arguments. */ 415 416 #define _SDT_NARG(...) __SDT_NARG(__VA_ARGS__, 12,11,10,9,8,7,6,5,4,3,2,1,0) 417 #define __SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, N, ...) N 418 #ifdef SDT_USE_VARIADIC 419 #define _SDT_PROBE_N(provider, name, N, ...) \ 420 _SDT_PROBE(provider, name, N, (__VA_ARGS__)) 421 #define STAP_PROBEV(provider, name, ...) \ 422 _SDT_PROBE_N(provider, name, _SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__) 423 #endif 424 425 /* These macros are for use in asm statements. You must compile 426 with -std=gnu99 or -std=c99 to use the STAP_PROBE_ASM macro. 427 428 The STAP_PROBE_ASM macro generates a quoted string to be used in the 429 template portion of the asm statement, concatenated with strings that 430 contain the actual assembly code around the probe site. 431 432 For example: 433 434 asm ("before\n" 435 STAP_PROBE_ASM(provider, fooprobe, %eax 4(%esi)) 436 "after"); 437 438 emits the assembly code for "before\nafter", with a probe in between. 439 The probe arguments are the %eax register, and the value of the memory 440 word located 4 bytes past the address in the %esi register. Note that 441 because this is a simple asm, not a GNU C extended asm statement, these 442 % characters do not need to be doubled to generate literal %reg names. 443 444 In a GNU C extended asm statement, the probe arguments can be specified 445 using the macro STAP_PROBE_ASM_TEMPLATE(n) for n arguments. The paired 446 macro STAP_PROBE_ASM_OPERANDS gives the C values of these probe arguments, 447 and appears in the input operand list of the asm statement. For example: 448 449 asm ("someinsn %0,%1\n" // %0 is output operand, %1 is input operand 450 STAP_PROBE_ASM(provider, fooprobe, STAP_PROBE_ASM_TEMPLATE(3)) 451 "otherinsn %[namedarg]" 452 : "r" (outvar) 453 : "g" (some_value), [namedarg] "i" (1234), 454 STAP_PROBE_ASM_OPERANDS(3, some_value, some_ptr->field, 1234)); 455 456 This is just like writing: 457 458 STAP_PROBE3(provider, fooprobe, some_value, some_ptr->field, 1234)); 459 460 but the probe site is right between "someinsn" and "otherinsn". 461 462 The probe arguments in STAP_PROBE_ASM can be given as assembly 463 operands instead, even inside a GNU C extended asm statement. 464 Note that these can use operand templates like %0 or %[name], 465 and likewise they must write %%reg for a literal operand of %reg. */ 466 467 #define _SDT_ASM_BODY_1(p,n,...) _SDT_ASM_BODY(p,n,_SDT_ASM_SUBSTR,(__VA_ARGS__)) 468 #define _SDT_ASM_BODY_2(p,n,...) _SDT_ASM_BODY(p,n,/*_SDT_ASM_STRING */,__VA_ARGS__) 469 #define _SDT_ASM_BODY_N2(p,n,no,...) _SDT_ASM_BODY_ ## no(p,n,__VA_ARGS__) 470 #define _SDT_ASM_BODY_N1(p,n,no,...) _SDT_ASM_BODY_N2(p,n,no,__VA_ARGS__) 471 #define _SDT_ASM_BODY_N(p,n,...) _SDT_ASM_BODY_N1(p,n,_SDT_NARG(0, __VA_ARGS__),__VA_ARGS__) 472 473 #if __STDC_VERSION__ >= 199901L 474 # define STAP_PROBE_ASM(provider, name, ...) \ 475 _SDT_ASM_BODY_N(provider, name, __VA_ARGS__) \ 476 _SDT_ASM_BASE 477 # define STAP_PROBE_ASM_OPERANDS(n, ...) _SDT_ASM_OPERANDS_##n(__VA_ARGS__) 478 #else 479 # define STAP_PROBE_ASM(provider, name, args) \ 480 _SDT_ASM_BODY(provider, name, /* _SDT_ASM_STRING */, (args)) \ 481 _SDT_ASM_BASE 482 #endif 483 #define STAP_PROBE_ASM_TEMPLATE(n) _SDT_ASM_TEMPLATE_##n,"use _SDT_ASM_TEMPLATE_" 484 485 486 /* DTrace compatible macro names. */ 487 #define DTRACE_PROBE(provider,probe) \ 488 STAP_PROBE(provider,probe) 489 #define DTRACE_PROBE1(provider,probe,parm1) \ 490 STAP_PROBE1(provider,probe,parm1) 491 #define DTRACE_PROBE2(provider,probe,parm1,parm2) \ 492 STAP_PROBE2(provider,probe,parm1,parm2) 493 #define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \ 494 STAP_PROBE3(provider,probe,parm1,parm2,parm3) 495 #define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \ 496 STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) 497 #define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \ 498 STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) 499 #define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \ 500 STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) 501 #define DTRACE_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ 502 STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) 503 #define DTRACE_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ 504 STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) 505 #define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ 506 STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) 507 #define DTRACE_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ 508 STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) 509 #define DTRACE_PROBE11(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11) \ 510 STAP_PROBE11(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11) 511 #define DTRACE_PROBE12(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11,parm12) \ 512 STAP_PROBE12(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10,parm11,parm12) 513 514 515 #endif /* sys/sdt.h */ 516