]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/sdt.h
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / sdt.h
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 <[email protected]>:
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 */
This page took 0.055466 seconds and 4 git commands to generate.