Linux Audio

Check our new training course

Loading...
v6.13.7
  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
135template<typename __sdt_T>
136struct __sdt_type
137{
138  static const bool __sdt_signed = false;
139};
140  
141#define __SDT_ALWAYS_SIGNED(T) \
142template<> struct __sdt_type<T> { static const bool __sdt_signed = true; };
143#define __SDT_COND_SIGNED(T,CT)						\
144template<> 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
178template<typename __sdt_E>
179struct __sdt_type<__sdt_E[]> : public __sdt_type<__sdt_E *> {};
180
181template<typename __sdt_E, size_t __sdt_N>
182struct __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 */
v6.8
  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
133template<typename __sdt_T>
134struct __sdt_type
135{
136  static const bool __sdt_signed = false;
137};
138  
139#define __SDT_ALWAYS_SIGNED(T) \
140template<> struct __sdt_type<T> { static const bool __sdt_signed = true; };
141#define __SDT_COND_SIGNED(T,CT)						\
142template<> 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
176template<typename __sdt_E>
177struct __sdt_type<__sdt_E[]> : public __sdt_type<__sdt_E *> {};
178
179template<typename __sdt_E, size_t __sdt_N>
180struct __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 */