]> sourceware.org Git - systemtap.git/blob - includes/sys/sdt.h
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
[systemtap.git] / includes / sys / sdt.h
1 /* <sys/sdt.h> - Systemtap static probe definition macros.
2 Copyright (C) 2010 Red Hat Inc.
3
4 This file is part of systemtap, and is free software in the public domain.
5 */
6
7 #ifndef _SYS_SDT_H
8 #define _SYS_SDT_H 1
9
10 #ifdef __ASSEMBLER__
11 # define _SDT_PROBE(provider, name, n, arglist) \
12 _SDT_ASM_BODY(provider, name, _SDT_ASM_STRING_1, (_SDT_DEPAREN_##n arglist)) \
13 _SDT_ASM_BASE
14 # define _SDT_ASM_1(x) x;
15 # define _SDT_ASM_2(a, b) a,b;
16 # define _SDT_ASM_3(a, b, c) a,b,c;
17 # define _SDT_ASM_5(a, b, c, d, e) a,b,c,d,e;
18 # define _SDT_ASM_STRING_1(x) .asciz #x;
19 # define _SDT_DEPAREN_0() /* empty */
20 # define _SDT_DEPAREN_1(a) a
21 # define _SDT_DEPAREN_2(a,b) a b
22 # define _SDT_DEPAREN_3(a,b,c) a b c
23 # define _SDT_DEPAREN_4(a,b,c,d) a b c d
24 # define _SDT_DEPAREN_5(a,b,c,d,e) a b c d e
25 # define _SDT_DEPAREN_6(a,b,c,d,e,f) a b c d e f
26 # define _SDT_DEPAREN_7(a,b,c,d,e,f,g) a b c d e f g
27 # define _SDT_DEPAREN_8(a,b,c,d,e,f,g,h) a b c d e f g h
28 # define _SDT_DEPAREN_9(a,b,c,d,e,f,g,h,i) a b c d e f g h i
29 # define _SDT_DEPAREN_10(a,b,c,d,e,f,g,h,i,j) a b c d e f g h i j
30 #else
31 # include <stdint.h>
32 # define _SDT_PROBE(provider, name, n, arglist) \
33 do { \
34 __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \
35 :: _SDT_ASM_OPERANDS_##n arglist); \
36 __asm__ __volatile__ (_SDT_ASM_BASE); \
37 } while (0)
38 # define _SDT_S(x) #x
39 # define _SDT_ASM_1(x) _SDT_S(x)"\n"
40 # define _SDT_ASM_2(a, b) _SDT_S(a)","_SDT_S(b)"\n"
41 # define _SDT_ASM_3(a, b, c) _SDT_S(a)","_SDT_S(b)","_SDT_S(c)"\n"
42 # define _SDT_ASM_5(a, b, c, d, e) _SDT_S(a)","_SDT_S(b)","_SDT_S(c)","\
43 _SDT_S(d)","_SDT_S(e)"\n"
44 # define _SDT_ASM_ARGS(n) _SDT_ASM_STRING(_SDT_ASM_TEMPLATE_##n)
45 # define _SDT_ASM_STRING_1(x) _SDT_ASM_1(.asciz #x)
46
47 # define _SDT_ARGFMT(no) %n[_SDT_S##no]@_SDT_ARGTMPL(_SDT_A##no)
48 # define _SDT_ARG(n, x) \
49 [_SDT_S##n] "n" ((_SDT_ARGSIGNED (x) ? 1 : -1) * (int) _SDT_ARGSIZE (x)), \
50 [_SDT_A##n] "nor" (_SDT_ARGVAL (x))
51 #endif
52 #define _SDT_ASM_STRING(x) _SDT_ASM_STRING_1(x)
53
54 #define _SDT_ARGARRAY(x) (__builtin_classify_type (x) == 14 \
55 || __builtin_classify_type (x) == 5)
56
57 #ifdef __cplusplus
58 # define _SDT_ARGSIGNED(x) (!_SDT_ARGARRAY (x) \
59 && __sdt_type<__typeof (x)>::__sdt_signed)
60 # define _SDT_ARGSIZE(x) (_SDT_ARGARRAY (x) \
61 ? sizeof (void *) : sizeof (x))
62 # define _SDT_ARGVAL(x) (x)
63
64 # include <cstddef>
65 # include <limits>
66
67 template<typename __sdt_T>
68 struct __sdt_type
69 {
70 static const bool __sdt_signed
71 = (std::numeric_limits<__sdt_T>::is_signed
72 && std::numeric_limits<__sdt_T>::is_integer);
73 };
74
75 template<typename __sdt_E>
76 struct __sdt_type<__sdt_E[]> : public __sdt_type<__sdt_E *> {};
77
78 template<typename __sdt_E, size_t __sdt_N>
79 struct __sdt_type<__sdt_E[__sdt_N]> : public __sdt_type<__sdt_E *> {};
80
81 #elif !defined(__ASSEMBLER__)
82 __extension__ extern unsigned long long __sdt_unsp;
83 # define _SDT_ARGINTTYPE(x) \
84 __typeof (__builtin_choose_expr (((__builtin_classify_type (x) \
85 + 3) & -4) == 4, (x), 0U))
86 # define _SDT_ARGSIGNED(x) \
87 (!__extension__ \
88 (__builtin_constant_p ((((unsigned long long) \
89 (_SDT_ARGINTTYPE (x)) __sdt_unsp) \
90 & (1ULL << (sizeof (unsigned long long) \
91 * __CHAR_BIT__ - 1))) == 0) \
92 || (_SDT_ARGINTTYPE (x)) -1 > (_SDT_ARGINTTYPE (x)) 0))
93 # define _SDT_ARGSIZE(x) \
94 (_SDT_ARGARRAY (x) ? sizeof (void *) : sizeof (x))
95 # define _SDT_ARGVAL(x) (x)
96 #endif
97
98 #if defined __powerpc__ || defined __powerpc64__
99 # define _SDT_ARGTMPL(id) %I[id]%[id]
100 #else
101 # define _SDT_ARGTMPL(id) %[id]
102 #endif
103
104 #ifdef __LP64__
105 # define _SDT_ASM_ADDR .8byte
106 #else
107 # define _SDT_ASM_ADDR .4byte
108 #endif
109
110 /* The ia64 and s390 nop instructions take an argument. */
111 #if defined(__ia64__) || defined(__s390__) || defined(__s390x__)
112 #define _SDT_NOP nop 0
113 #else
114 #define _SDT_NOP nop
115 #endif
116
117 #define _SDT_NOTE_NAME "stapsdt"
118 #define _SDT_NOTE_TYPE 3
119
120 /* If the assembler supports the necessary feature, then we can play
121 nice with code in COMDAT sections, which comes up in C++ code.
122 Without that assembler support, some combinations of probe placements
123 in certain kinds of C++ code may produce link-time errors. */
124 #include "sdt-config.h"
125 #if _SDT_ASM_SECTION_AUTOGROUP_SUPPORT
126 # define _SDT_ASM_AUTOGROUP "?"
127 #else
128 # define _SDT_ASM_AUTOGROUP ""
129 #endif
130
131 #define _SDT_ASM_BODY(provider, name, pack_args, args) \
132 _SDT_ASM_1(990: _SDT_NOP) \
133 _SDT_ASM_3( .pushsection .note.stapsdt,_SDT_ASM_AUTOGROUP,"note") \
134 _SDT_ASM_1( .balign 4) \
135 _SDT_ASM_3( .4byte 992f-991f, 994f-993f, _SDT_NOTE_TYPE) \
136 _SDT_ASM_1(991: .asciz _SDT_NOTE_NAME) \
137 _SDT_ASM_1(992: .balign 4) \
138 _SDT_ASM_1(993: _SDT_ASM_ADDR 990b) \
139 _SDT_ASM_1( _SDT_ASM_ADDR _.stapsdt.base) \
140 _SDT_SEMAPHORE(provider,name) \
141 _SDT_ASM_STRING(provider) \
142 _SDT_ASM_STRING(name) \
143 pack_args args \
144 _SDT_ASM_1(994: .balign 4) \
145 _SDT_ASM_1( .popsection)
146
147 #define _SDT_ASM_BASE \
148 _SDT_ASM_1(.ifndef _.stapsdt.base) \
149 _SDT_ASM_5( .pushsection .stapsdt.base,"aG","progbits", \
150 .stapsdt.base,comdat) \
151 _SDT_ASM_1( .weak _.stapsdt.base) \
152 _SDT_ASM_1( .hidden _.stapsdt.base) \
153 _SDT_ASM_1( _.stapsdt.base: .space 1) \
154 _SDT_ASM_2( .size _.stapsdt.base, 1) \
155 _SDT_ASM_1( .popsection) \
156 _SDT_ASM_1(.endif)
157
158 #if defined _SDT_HAS_SEMAPHORES
159 #define _SDT_SEMAPHORE(p,n) _SDT_ASM_1( _SDT_ASM_ADDR p##_##n##_semaphore)
160 #else
161 #define _SDT_SEMAPHORE(p,n) _SDT_ASM_1( _SDT_ASM_ADDR 0)
162 #endif
163
164 #define _SDT_ASM_TEMPLATE_0 /* no arguments */
165 #define _SDT_ASM_TEMPLATE_1 _SDT_ARGFMT(1)
166 #define _SDT_ASM_TEMPLATE_2 _SDT_ASM_TEMPLATE_1 _SDT_ARGFMT(2)
167 #define _SDT_ASM_TEMPLATE_3 _SDT_ASM_TEMPLATE_2 _SDT_ARGFMT(3)
168 #define _SDT_ASM_TEMPLATE_4 _SDT_ASM_TEMPLATE_3 _SDT_ARGFMT(4)
169 #define _SDT_ASM_TEMPLATE_5 _SDT_ASM_TEMPLATE_4 _SDT_ARGFMT(5)
170 #define _SDT_ASM_TEMPLATE_6 _SDT_ASM_TEMPLATE_5 _SDT_ARGFMT(6)
171 #define _SDT_ASM_TEMPLATE_7 _SDT_ASM_TEMPLATE_6 _SDT_ARGFMT(7)
172 #define _SDT_ASM_TEMPLATE_8 _SDT_ASM_TEMPLATE_7 _SDT_ARGFMT(8)
173 #define _SDT_ASM_TEMPLATE_9 _SDT_ASM_TEMPLATE_8 _SDT_ARGFMT(9)
174 #define _SDT_ASM_TEMPLATE_10 _SDT_ASM_TEMPLATE_9 _SDT_ARGFMT(10)
175 #define _SDT_ASM_OPERANDS_0() [__sdt_dummy] "g" (0)
176 #define _SDT_ASM_OPERANDS_1(arg1) _SDT_ARG(1, arg1)
177 #define _SDT_ASM_OPERANDS_2(arg1, arg2) \
178 _SDT_ASM_OPERANDS_1(arg1), _SDT_ARG(2, arg2)
179 #define _SDT_ASM_OPERANDS_3(arg1, arg2, arg3) \
180 _SDT_ASM_OPERANDS_2(arg1, arg2), _SDT_ARG(3, arg3)
181 #define _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4) \
182 _SDT_ASM_OPERANDS_3(arg1, arg2, arg3), _SDT_ARG(4, arg4)
183 #define _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5) \
184 _SDT_ASM_OPERANDS_4(arg1, arg2, arg3, arg4), _SDT_ARG(5, arg5)
185 #define _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
186 _SDT_ASM_OPERANDS_5(arg1, arg2, arg3, arg4, arg5), _SDT_ARG(6, arg6)
187 #define _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
188 _SDT_ASM_OPERANDS_6(arg1, arg2, arg3, arg4, arg5, arg6), _SDT_ARG(7, arg7)
189 #define _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
190 _SDT_ASM_OPERANDS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7), \
191 _SDT_ARG(8, arg8)
192 #define _SDT_ASM_OPERANDS_9(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \
193 _SDT_ASM_OPERANDS_8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), \
194 _SDT_ARG(9, arg9)
195 #define _SDT_ASM_OPERANDS_10(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \
196 _SDT_ASM_OPERANDS_9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), \
197 _SDT_ARG(10, arg10)
198
199 /* These macros can be used in C, C++, or assembly code.
200 In assembly code the arguments should use normal assembly operand syntax. */
201
202 #define STAP_PROBE(provider, name) \
203 _SDT_PROBE(provider, name, 0, ())
204 #define STAP_PROBE1(provider, name, arg1) \
205 _SDT_PROBE(provider, name, 1, (arg1))
206 #define STAP_PROBE2(provider, name, arg1, arg2) \
207 _SDT_PROBE(provider, name, 2, (arg1, arg2))
208 #define STAP_PROBE3(provider, name, arg1, arg2, arg3) \
209 _SDT_PROBE(provider, name, 3, (arg1, arg2, arg3))
210 #define STAP_PROBE4(provider, name, arg1, arg2, arg3, arg4) \
211 _SDT_PROBE(provider, name, 4, (arg1, arg2, arg3, arg4))
212 #define STAP_PROBE5(provider, name, arg1, arg2, arg3, arg4, arg5) \
213 _SDT_PROBE(provider, name, 5, (arg1, arg2, arg3, arg4, arg5))
214 #define STAP_PROBE6(provider, name, arg1, arg2, arg3, arg4, arg5, arg6) \
215 _SDT_PROBE(provider, name, 6, (arg1, arg2, arg3, arg4, arg5, arg6))
216 #define STAP_PROBE7(provider, name, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
217 _SDT_PROBE(provider, name, 7, (arg1, arg2, arg3, arg4, arg5, arg6, arg7))
218 #define STAP_PROBE8(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \
219 _SDT_PROBE(provider, name, 8, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8))
220 #define STAP_PROBE9(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\
221 _SDT_PROBE(provider, name, 9, (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9))
222 #define STAP_PROBE10(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) \
223 _SDT_PROBE(provider, name, 10, \
224 (arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10))
225
226 /* These macros are for use in asm statements. You must compile
227 with -std=gnu99 or -std=c99 to use the STAP_PROBE_ASM macro.
228
229 The STAP_PROBE_ASM macro generates a quoted string to be used in the
230 template portion of the asm statement, concatenated with strings that
231 contain the actual assembly code around the probe site.
232
233 For example:
234
235 asm ("before\n"
236 STAP_PROBE_ASM(provider, fooprobe, %eax 4(%esi))
237 "after");
238
239 emits the assembly code for "before\nafter", with a probe in between.
240 The probe arguments are the %eax register, and the value of the memory
241 word located 4 bytes past the address in the %esi register. Note that
242 because this is a simple asm, not a GNU C extended asm statement, these
243 % characters do not need to be doubled to generate literal %reg names.
244
245 In a GNU C extended asm statement, the probe arguments can be specified
246 using the macro STAP_PROBE_ASM_TEMPLATE(n) for n arguments. The paired
247 macro STAP_PROBE_ASM_OPERANDS gives the C values of these probe arguments,
248 and appears in the input operand list of the asm statement. For example:
249
250 asm ("someinsn %0,%1\n" // %0 is output operand, %1 is input operand
251 STAP_PROBE_ASM(provider, fooprobe, STAP_PROBE_ASM_TEMPLATE(3))
252 "otherinsn %[namedarg]"
253 : "r" (outvar)
254 : "g" (some_value), [namedarg] "i" (1234),
255 STAP_PROBE_ASM_OPERANDS(3, some_value, some_ptr->field, 1234));
256
257 This is just like writing:
258
259 STAP_PROBE3(provider, fooprobe, some_value, some_ptr->field, 1234));
260
261 but the probe site is right between "someinsn" and "otherinsn".
262
263 The probe arguments in STAP_PROBE_ASM can be given as assembly
264 operands instead, even inside a GNU C extended asm statement.
265 Note that these can use operand templates like %0 or %[name],
266 and likewise they must write %%reg for a literal operand of %reg. */
267
268 #if __STDC_VERSION__ >= 199901L
269 # define STAP_PROBE_ASM(provider, name, ...) \
270 _SDT_ASM_BODY(provider, name, _SDT_ASM_STRING, (__VA_ARGS__)) \
271 _SDT_ASM_BASE
272 # define STAP_PROBE_ASM_OPERANDS(n, ...) _SDT_ASM_OPERANDS_##n(__VA_ARGS__)
273 #else
274 # define STAP_PROBE_ASM(provider, name, args) \
275 _SDT_ASM_BODY(provider, name, _SDT_ASM_STRING, (args)) \
276 _SDT_ASM_BASE
277 #endif
278 #define STAP_PROBE_ASM_TEMPLATE(n) _SDT_ASM_TEMPLATE_##n
279
280
281 /* DTrace compatible macro names. */
282 #define DTRACE_PROBE(provider,probe) \
283 STAP_PROBE(provider,probe)
284 #define DTRACE_PROBE1(provider,probe,parm1) \
285 STAP_PROBE1(provider,probe,parm1)
286 #define DTRACE_PROBE2(provider,probe,parm1,parm2) \
287 STAP_PROBE2(provider,probe,parm1,parm2)
288 #define DTRACE_PROBE3(provider,probe,parm1,parm2,parm3) \
289 STAP_PROBE3(provider,probe,parm1,parm2,parm3)
290 #define DTRACE_PROBE4(provider,probe,parm1,parm2,parm3,parm4) \
291 STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4)
292 #define DTRACE_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5) \
293 STAP_PROBE5(provider,probe,parm1,parm2,parm3,parm4,parm5)
294 #define DTRACE_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6) \
295 STAP_PROBE6(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6)
296 #define DTRACE_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \
297 STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7)
298 #define DTRACE_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \
299 STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8)
300 #define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \
301 STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9)
302 #define DTRACE_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \
303 STAP_PROBE10(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10)
304
305
306 #endif /* sys/sdt.h */
This page took 0.054851 seconds and 6 git commands to generate.