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