Fix: disable use of __builtin_return_address(0) on 32-bit PowerPC
[lttng-ust.git] / include / lttng / ust-tracepoint-event.h
1 /*
2 * Copyright (c) 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <urcu/compiler.h>
26 #include <urcu/rculist.h>
27 #include <lttng/ust-events.h>
28 #include <lttng/ringbuffer-config.h>
29 #include <lttng/ust-compiler.h>
30 #include <lttng/tracepoint.h>
31 #include <string.h>
32
33 #undef tp_list_for_each_entry_rcu
34 #define tp_list_for_each_entry_rcu(pos, head, member) \
35 for (pos = cds_list_entry(tp_rcu_dereference_bp((head)->next), __typeof__(*pos), member); \
36 &pos->member != (head); \
37 pos = cds_list_entry(tp_rcu_dereference_bp(pos->member.next), __typeof__(*pos), member))
38
39 /*
40 * TRACEPOINT_EVENT_CLASS declares a class of tracepoints receiving the
41 * same arguments and having the same field layout.
42 *
43 * TRACEPOINT_EVENT_INSTANCE declares an instance of a tracepoint, with
44 * its own provider and name. It refers to a class (template).
45 *
46 * TRACEPOINT_EVENT declared both a class and an instance and does a
47 * direct mapping from the instance to the class.
48 */
49
50 #undef TRACEPOINT_EVENT
51 #define TRACEPOINT_EVENT(_provider, _name, _args, _fields) \
52 TRACEPOINT_EVENT_CLASS(_provider, _name, \
53 _TP_PARAMS(_args), \
54 _TP_PARAMS(_fields)) \
55 TRACEPOINT_EVENT_INSTANCE(_provider, _name, _name, \
56 _TP_PARAMS(_args))
57
58 /* Helpers */
59 #define _TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
60
61 #define _tp_max_t(type, x, y) \
62 ({ \
63 type __max1 = (x); \
64 type __max2 = (y); \
65 __max1 > __max2 ? __max1: __max2; \
66 })
67
68 /*
69 * Stage 0 of tracepoint event generation.
70 *
71 * Check that each TRACEPOINT_EVENT provider argument match the
72 * TRACEPOINT_PROVIDER by creating dummy callbacks.
73 */
74
75 /* Reset all macros within TRACEPOINT_EVENT */
76 #include <lttng/ust-tracepoint-event-reset.h>
77
78 static inline lttng_ust_notrace
79 void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void);
80 static inline
81 void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(void)
82 {
83 }
84
85 #undef TRACEPOINT_EVENT_CLASS
86 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
87 __tracepoint_provider_mismatch_##_provider();
88
89 #undef TRACEPOINT_EVENT_INSTANCE
90 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
91 __tracepoint_provider_mismatch_##_provider();
92
93 static inline lttng_ust_notrace
94 void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void);
95 static inline
96 void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void)
97 {
98 #include TRACEPOINT_INCLUDE
99 }
100
101 /*
102 * Stage 0.1 of tracepoint event generation.
103 *
104 * Check that each TRACEPOINT_EVENT provider:name does not exceed the
105 * tracepoint name length limit.
106 */
107
108 /* Reset all macros within TRACEPOINT_EVENT */
109 #include <lttng/ust-tracepoint-event-reset.h>
110
111 #undef TRACEPOINT_EVENT_INSTANCE
112 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
113 static const char \
114 __tp_name_len_check##_provider##___##_name[LTTNG_UST_SYM_NAME_LEN] \
115 __attribute__((unused)) = \
116 #_provider ":" #_name;
117
118 #include TRACEPOINT_INCLUDE
119
120 /*
121 * Stage 0.9 of tracepoint event generation
122 *
123 * Unfolding the enums
124 */
125 #include <lttng/ust-tracepoint-event-reset.h>
126
127 /* Enumeration entry (single value) */
128 #undef ctf_enum_value
129 #define ctf_enum_value(_string, _value) \
130 { _value, _value, _string },
131
132 /* Enumeration entry (range) */
133 #undef ctf_enum_range
134 #define ctf_enum_range(_string, _range_start, _range_end) \
135 { _range_start, _range_end, _string },
136
137 #undef TP_ENUM_VALUES
138 #define TP_ENUM_VALUES(...) \
139 __VA_ARGS__
140
141 #undef TRACEPOINT_ENUM
142 #define TRACEPOINT_ENUM(_provider, _name, _values) \
143 const struct lttng_enum_entry __enum_values__##_provider##_##_name[] = { \
144 _values \
145 };
146
147 #include TRACEPOINT_INCLUDE
148
149 /*
150 * Stage 1 of tracepoint event generation.
151 *
152 * Create event field type metadata section.
153 * Each event produce an array of fields.
154 */
155
156 /* Reset all macros within TRACEPOINT_EVENT */
157 #include <lttng/ust-tracepoint-event-reset.h>
158 #include <lttng/ust-tracepoint-event-write.h>
159 #include <lttng/ust-tracepoint-event-nowrite.h>
160
161 #undef _ctf_integer_ext
162 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
163 { \
164 .name = #_item, \
165 .type = __type_integer(_type, _byte_order, _base, none),\
166 .nowrite = _nowrite, \
167 },
168
169 #undef _ctf_float
170 #define _ctf_float(_type, _item, _src, _nowrite) \
171 { \
172 .name = #_item, \
173 .type = __type_float(_type), \
174 .nowrite = _nowrite, \
175 },
176
177 #undef _ctf_array_encoded
178 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
179 { \
180 .name = #_item, \
181 .type = \
182 { \
183 .atype = atype_array, \
184 .u = \
185 { \
186 .array = \
187 { \
188 .elem_type = __type_integer(_type, BYTE_ORDER, 10, _encoding), \
189 .length = _length, \
190 } \
191 } \
192 }, \
193 .nowrite = _nowrite, \
194 },
195
196 #undef _ctf_sequence_encoded
197 #define _ctf_sequence_encoded(_type, _item, _src, \
198 _length_type, _src_length, _encoding, _nowrite, \
199 _elem_type_base) \
200 { \
201 .name = #_item, \
202 .type = \
203 { \
204 .atype = atype_sequence, \
205 .u = \
206 { \
207 .sequence = \
208 { \
209 .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \
210 .elem_type = __type_integer(_type, BYTE_ORDER, _elem_type_base, _encoding), \
211 }, \
212 }, \
213 }, \
214 .nowrite = _nowrite, \
215 },
216
217 #undef _ctf_string
218 #define _ctf_string(_item, _src, _nowrite) \
219 { \
220 .name = #_item, \
221 .type = \
222 { \
223 .atype = atype_string, \
224 .u = \
225 { \
226 .basic = { .string = { .encoding = lttng_encode_UTF8 } } \
227 }, \
228 }, \
229 .nowrite = _nowrite, \
230 },
231
232 #undef _ctf_enum
233 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
234 { \
235 .name = #_item, \
236 .type = { \
237 .atype = atype_enum, \
238 .u = { \
239 .basic = { \
240 .enumeration = { \
241 .desc = &__enum_##_provider##_##_name, \
242 .container_type = { \
243 .size = sizeof(_type) * CHAR_BIT, \
244 .alignment = lttng_alignof(_type) * CHAR_BIT, \
245 .signedness = lttng_is_signed_type(_type), \
246 .reverse_byte_order = 0, \
247 .base = 10, \
248 .encoding = lttng_encode_none, \
249 }, \
250 }, \
251 }, \
252 }, \
253 }, \
254 .nowrite = _nowrite, \
255 },
256
257 #undef TP_FIELDS
258 #define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
259
260 #undef TRACEPOINT_EVENT_CLASS
261 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
262 static const struct lttng_event_field __event_fields___##_provider##___##_name[] = { \
263 _fields \
264 };
265
266 #undef TRACEPOINT_ENUM
267 #define TRACEPOINT_ENUM(_provider, _name, _values) \
268 static const struct lttng_enum_desc __enum_##_provider##_##_name = { \
269 .name = #_provider "_" #_name, \
270 .entries = __enum_values__##_provider##_##_name, \
271 .nr_entries = _TP_ARRAY_SIZE(__enum_values__##_provider##_##_name), \
272 };
273
274 #include TRACEPOINT_INCLUDE
275
276 /*
277 * Stage 2 of tracepoint event generation.
278 *
279 * Create probe callback prototypes.
280 */
281
282 /* Reset all macros within TRACEPOINT_EVENT */
283 #include <lttng/ust-tracepoint-event-reset.h>
284
285 #undef TP_ARGS
286 #define TP_ARGS(...) __VA_ARGS__
287
288 #undef TRACEPOINT_EVENT_CLASS
289 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
290 static void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args));
291
292 #include TRACEPOINT_INCLUDE
293
294 /*
295 * Stage 3.0 of tracepoint event generation.
296 *
297 * Create static inline function that calculates event size.
298 */
299
300 /* Reset all macros within TRACEPOINT_EVENT */
301 #include <lttng/ust-tracepoint-event-reset.h>
302 #include <lttng/ust-tracepoint-event-write.h>
303
304 #undef _ctf_integer_ext
305 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
306 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
307 __event_len += sizeof(_type);
308
309 #undef _ctf_float
310 #define _ctf_float(_type, _item, _src, _nowrite) \
311 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
312 __event_len += sizeof(_type);
313
314 #undef _ctf_array_encoded
315 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
316 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
317 __event_len += sizeof(_type) * (_length);
318
319 #undef _ctf_sequence_encoded
320 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
321 _src_length, _encoding, _nowrite, _elem_type_base) \
322 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_length_type)); \
323 __event_len += sizeof(_length_type); \
324 __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
325 __dynamic_len[__dynamic_len_idx] = (_src_length); \
326 __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \
327 __dynamic_len_idx++;
328
329 #undef _ctf_string
330 #define _ctf_string(_item, _src, _nowrite) \
331 __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1;
332
333 #undef _ctf_enum
334 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
335 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
336
337 #undef TP_ARGS
338 #define TP_ARGS(...) __VA_ARGS__
339
340 #undef TP_FIELDS
341 #define TP_FIELDS(...) __VA_ARGS__
342
343 #undef TRACEPOINT_EVENT_CLASS
344 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
345 static inline lttng_ust_notrace \
346 size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)); \
347 static inline \
348 size_t __event_get_size__##_provider##___##_name(size_t *__dynamic_len, _TP_ARGS_DATA_PROTO(_args)) \
349 { \
350 size_t __event_len = 0; \
351 unsigned int __dynamic_len_idx = 0; \
352 \
353 if (0) \
354 (void) __dynamic_len_idx; /* don't warn if unused */ \
355 _fields \
356 return __event_len; \
357 }
358
359 #include TRACEPOINT_INCLUDE
360
361 /*
362 * Stage 3.1 of tracepoint event generation.
363 *
364 * Create static inline function that layout the filter stack data.
365 * We make both write and nowrite data available to the filter.
366 */
367
368 /* Reset all macros within TRACEPOINT_EVENT */
369 #include <lttng/ust-tracepoint-event-reset.h>
370 #include <lttng/ust-tracepoint-event-write.h>
371 #include <lttng/ust-tracepoint-event-nowrite.h>
372
373 #undef _ctf_integer_ext
374 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
375 if (lttng_is_signed_type(_type)) { \
376 int64_t __ctf_tmp_int64; \
377 switch (sizeof(_type)) { \
378 case 1: \
379 { \
380 union { _type t; int8_t v; } __tmp = { (_type) (_src) }; \
381 __ctf_tmp_int64 = (int64_t) __tmp.v; \
382 break; \
383 } \
384 case 2: \
385 { \
386 union { _type t; int16_t v; } __tmp = { (_type) (_src) }; \
387 __ctf_tmp_int64 = (int64_t) __tmp.v; \
388 break; \
389 } \
390 case 4: \
391 { \
392 union { _type t; int32_t v; } __tmp = { (_type) (_src) }; \
393 __ctf_tmp_int64 = (int64_t) __tmp.v; \
394 break; \
395 } \
396 case 8: \
397 { \
398 union { _type t; int64_t v; } __tmp = { (_type) (_src) }; \
399 __ctf_tmp_int64 = (int64_t) __tmp.v; \
400 break; \
401 } \
402 default: \
403 abort(); \
404 }; \
405 memcpy(__stack_data, &__ctf_tmp_int64, sizeof(int64_t)); \
406 } else { \
407 uint64_t __ctf_tmp_uint64; \
408 switch (sizeof(_type)) { \
409 case 1: \
410 { \
411 union { _type t; uint8_t v; } __tmp = { (_type) (_src) }; \
412 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
413 break; \
414 } \
415 case 2: \
416 { \
417 union { _type t; uint16_t v; } __tmp = { (_type) (_src) }; \
418 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
419 break; \
420 } \
421 case 4: \
422 { \
423 union { _type t; uint32_t v; } __tmp = { (_type) (_src) }; \
424 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
425 break; \
426 } \
427 case 8: \
428 { \
429 union { _type t; uint64_t v; } __tmp = { (_type) (_src) }; \
430 __ctf_tmp_uint64 = (uint64_t) __tmp.v; \
431 break; \
432 } \
433 default: \
434 abort(); \
435 }; \
436 memcpy(__stack_data, &__ctf_tmp_uint64, sizeof(uint64_t)); \
437 } \
438 __stack_data += sizeof(int64_t);
439
440 #undef _ctf_float
441 #define _ctf_float(_type, _item, _src, _nowrite) \
442 { \
443 double __ctf_tmp_double = (double) (_type) (_src); \
444 memcpy(__stack_data, &__ctf_tmp_double, sizeof(double)); \
445 __stack_data += sizeof(double); \
446 }
447
448 #undef _ctf_array_encoded
449 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
450 { \
451 unsigned long __ctf_tmp_ulong = (unsigned long) (_length); \
452 const void *__ctf_tmp_ptr = (_src); \
453 memcpy(__stack_data, &__ctf_tmp_ulong, sizeof(unsigned long)); \
454 __stack_data += sizeof(unsigned long); \
455 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
456 __stack_data += sizeof(void *); \
457 }
458
459 #undef _ctf_sequence_encoded
460 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
461 _src_length, _encoding, _nowrite, _elem_type_base) \
462 { \
463 unsigned long __ctf_tmp_ulong = (unsigned long) (_src_length); \
464 const void *__ctf_tmp_ptr = (_src); \
465 memcpy(__stack_data, &__ctf_tmp_ulong, sizeof(unsigned long)); \
466 __stack_data += sizeof(unsigned long); \
467 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
468 __stack_data += sizeof(void *); \
469 }
470
471 #undef _ctf_string
472 #define _ctf_string(_item, _src, _nowrite) \
473 { \
474 const void *__ctf_tmp_ptr = (_src); \
475 memcpy(__stack_data, &__ctf_tmp_ptr, sizeof(void *)); \
476 __stack_data += sizeof(void *); \
477 }
478
479 #undef _ctf_enum
480 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
481 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
482
483 #undef TP_ARGS
484 #define TP_ARGS(...) __VA_ARGS__
485
486 #undef TP_FIELDS
487 #define TP_FIELDS(...) __VA_ARGS__
488
489 #undef TRACEPOINT_EVENT_CLASS
490 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
491 static inline \
492 void __event_prepare_filter_stack__##_provider##___##_name(char *__stack_data,\
493 _TP_ARGS_DATA_PROTO(_args)) \
494 { \
495 _fields \
496 }
497
498 #include TRACEPOINT_INCLUDE
499
500 /*
501 * Stage 4 of tracepoint event generation.
502 *
503 * Create static inline function that calculates event payload alignment.
504 */
505
506 /* Reset all macros within TRACEPOINT_EVENT */
507 #include <lttng/ust-tracepoint-event-reset.h>
508 #include <lttng/ust-tracepoint-event-write.h>
509
510 #undef _ctf_integer_ext
511 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
512 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
513
514 #undef _ctf_float
515 #define _ctf_float(_type, _item, _src, _nowrite) \
516 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
517
518 #undef _ctf_array_encoded
519 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
520 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
521
522 #undef _ctf_sequence_encoded
523 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
524 _src_length, _encoding, _nowrite, _elem_type_base) \
525 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_length_type)); \
526 __event_align = _tp_max_t(size_t, __event_align, lttng_alignof(_type));
527
528 #undef _ctf_string
529 #define _ctf_string(_item, _src, _nowrite)
530
531 #undef _ctf_enum
532 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
533 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
534
535 #undef TP_ARGS
536 #define TP_ARGS(...) __VA_ARGS__
537
538 #undef TP_FIELDS
539 #define TP_FIELDS(...) __VA_ARGS__
540
541 #undef TRACEPOINT_EVENT_CLASS
542 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
543 static inline lttng_ust_notrace \
544 size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)); \
545 static inline \
546 size_t __event_get_align__##_provider##___##_name(_TP_ARGS_PROTO(_args)) \
547 { \
548 size_t __event_align = 1; \
549 _fields \
550 return __event_align; \
551 }
552
553 #include TRACEPOINT_INCLUDE
554
555
556 /*
557 * Stage 5 of tracepoint event generation.
558 *
559 * Create the probe function. This function calls event size calculation
560 * and writes event data into the buffer.
561 */
562
563 /* Reset all macros within TRACEPOINT_EVENT */
564 #include <lttng/ust-tracepoint-event-reset.h>
565 #include <lttng/ust-tracepoint-event-write.h>
566
567 #undef _ctf_integer_ext
568 #define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _nowrite) \
569 { \
570 _type __tmp = (_src); \
571 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
572 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
573 }
574
575 #undef _ctf_float
576 #define _ctf_float(_type, _item, _src, _nowrite) \
577 { \
578 _type __tmp = (_src); \
579 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
580 __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
581 }
582
583 #undef _ctf_array_encoded
584 #define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _nowrite) \
585 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
586 __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length));
587
588 #undef _ctf_sequence_encoded
589 #define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
590 _src_length, _encoding, _nowrite, _elem_type_base) \
591 { \
592 _length_type __tmpl = __stackvar.__dynamic_len[__dynamic_len_idx]; \
593 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\
594 __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\
595 } \
596 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
597 __chan->ops->event_write(&__ctx, _src, \
598 sizeof(_type) * __get_dynamic_len(dest));
599
600 /*
601 * __chan->ops->u.has_strcpy is a flag letting us know if the LTTng-UST
602 * tracepoint provider ABI implements event_strcpy. This dynamic check
603 * can be removed when the tracepoint provider ABI moves to 2.
604 */
605 #if (LTTNG_UST_PROVIDER_MAJOR > 1)
606 #error "Tracepoint probe provider major version has changed. Please remove dynamic check for has_strcpy."
607 #endif
608
609 #undef _ctf_string
610 #define _ctf_string(_item, _src, _nowrite) \
611 lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(*(_src))); \
612 if (__chan->ops->u.has_strcpy) \
613 __chan->ops->event_strcpy(&__ctx, _src, \
614 __get_dynamic_len(dest)); \
615 else \
616 __chan->ops->event_write(&__ctx, _src, \
617 __get_dynamic_len(dest));
618
619 #undef _ctf_enum
620 #define _ctf_enum(_provider, _name, _type, _item, _src, _nowrite) \
621 _ctf_integer_ext(_type, _item, _src, BYTE_ORDER, 10, _nowrite)
622
623 /* Beware: this get len actually consumes the len value */
624 #undef __get_dynamic_len
625 #define __get_dynamic_len(field) __stackvar.__dynamic_len[__dynamic_len_idx++]
626
627 #undef TP_ARGS
628 #define TP_ARGS(...) __VA_ARGS__
629
630 #undef TP_FIELDS
631 #define TP_FIELDS(...) __VA_ARGS__
632
633 /*
634 * For state dump, check that "session" argument (mandatory) matches the
635 * session this event belongs to. Ensures that we write state dump data only
636 * into the started session, not into all sessions.
637 */
638 #undef _TP_SESSION_CHECK
639 #ifdef TP_SESSION_CHECK
640 #define _TP_SESSION_CHECK(session, csession) (session == csession)
641 #else /* TP_SESSION_CHECK */
642 #define _TP_SESSION_CHECK(session, csession) 1
643 #endif /* TP_SESSION_CHECK */
644
645 /*
646 * Use of __builtin_return_address(0) sometimes seems to cause stack
647 * corruption on 32-bit PowerPC. Disable this feature on that
648 * architecture for now by always using the NULL value for the ip
649 * context.
650 */
651 #undef _TP_IP_PARAM
652 #ifdef TP_IP_PARAM
653 #define _TP_IP_PARAM(x) (x)
654 #else /* TP_IP_PARAM */
655
656 #if defined(__PPC__) && !defined(__PPC64__)
657 #define _TP_IP_PARAM(x) NULL
658 #else /* #if defined(__PPC__) && !defined(__PPC64__) */
659 #define _TP_IP_PARAM(x) __builtin_return_address(0)
660 #endif /* #else #if defined(__PPC__) && !defined(__PPC64__) */
661
662 #endif /* TP_IP_PARAM */
663
664 /*
665 * Using twice size for filter stack data to hold size and pointer for
666 * each field (worse case). For integers, max size required is 64-bit.
667 * Same for double-precision floats. Those fit within
668 * 2*sizeof(unsigned long) for all supported architectures.
669 * Perform UNION (||) of filter runtime list.
670 */
671 #undef TRACEPOINT_EVENT_CLASS
672 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
673 static lttng_ust_notrace \
674 void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)); \
675 static \
676 void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args)) \
677 { \
678 struct lttng_event *__event = (struct lttng_event *) __tp_data; \
679 struct lttng_channel *__chan = __event->chan; \
680 struct lttng_ust_lib_ring_buffer_ctx __ctx; \
681 struct lttng_stack_ctx __lttng_ctx; \
682 size_t __event_len, __event_align; \
683 size_t __dynamic_len_idx = 0; \
684 union { \
685 size_t __dynamic_len[_TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \
686 char __filter_stack_data[2 * sizeof(unsigned long) * _TP_ARRAY_SIZE(__event_fields___##_provider##___##_name)]; \
687 } __stackvar; \
688 int __ret; \
689 \
690 if (0) \
691 (void) __dynamic_len_idx; /* don't warn if unused */ \
692 if (!_TP_SESSION_CHECK(session, __chan->session)) \
693 return; \
694 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->session->active))) \
695 return; \
696 if (caa_unlikely(!CMM_ACCESS_ONCE(__chan->enabled))) \
697 return; \
698 if (caa_unlikely(!CMM_ACCESS_ONCE(__event->enabled))) \
699 return; \
700 if (caa_unlikely(!TP_RCU_LINK_TEST())) \
701 return; \
702 if (caa_unlikely(!cds_list_empty(&__event->bytecode_runtime_head))) { \
703 struct lttng_bytecode_runtime *bc_runtime; \
704 int __filter_record = __event->has_enablers_without_bytecode; \
705 \
706 __event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \
707 _TP_ARGS_DATA_VAR(_args)); \
708 tp_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \
709 if (caa_unlikely(bc_runtime->filter(bc_runtime, \
710 __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) \
711 __filter_record = 1; \
712 } \
713 if (caa_likely(!__filter_record)) \
714 return; \
715 } \
716 __event_len = __event_get_size__##_provider##___##_name(__stackvar.__dynamic_len, \
717 _TP_ARGS_DATA_VAR(_args)); \
718 __event_align = __event_get_align__##_provider##___##_name(_TP_ARGS_VAR(_args)); \
719 memset(&__lttng_ctx, 0, sizeof(__lttng_ctx)); \
720 __lttng_ctx.event = __event; \
721 __lttng_ctx.chan_ctx = tp_rcu_dereference_bp(__chan->ctx); \
722 __lttng_ctx.event_ctx = tp_rcu_dereference_bp(__event->ctx); \
723 lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \
724 __event_align, -1, __chan->handle, &__lttng_ctx); \
725 __ctx.ip = _TP_IP_PARAM(TP_IP_PARAM); \
726 __ret = __chan->ops->event_reserve(&__ctx, __event->id); \
727 if (__ret < 0) \
728 return; \
729 _fields \
730 __chan->ops->event_commit(&__ctx); \
731 }
732
733 #include TRACEPOINT_INCLUDE
734
735 #undef __get_dynamic_len
736
737 /*
738 * Stage 5.1 of tracepoint event generation.
739 *
740 * Create probe signature
741 */
742
743 /* Reset all macros within TRACEPOINT_EVENT */
744 #include <lttng/ust-tracepoint-event-reset.h>
745
746 #undef TP_ARGS
747 #define TP_ARGS(...) __VA_ARGS__
748
749 #define _TP_EXTRACT_STRING2(...) #__VA_ARGS__
750
751 #undef TRACEPOINT_EVENT_CLASS
752 #define TRACEPOINT_EVENT_CLASS(_provider, _name, _args, _fields) \
753 const char __tp_event_signature___##_provider##___##_name[] = \
754 _TP_EXTRACT_STRING2(_args);
755
756 #include TRACEPOINT_INCLUDE
757
758 #undef _TP_EXTRACT_STRING2
759
760 /*
761 * Stage 6 of tracepoint event generation.
762 *
763 * Tracepoint loglevel mapping definition generation. We generate a
764 * symbol for each mapping for a provider/event to ensure at most a 1 to
765 * 1 mapping between events and loglevels. If the symbol is repeated,
766 * the compiler will complain.
767 */
768
769 /* Reset all macros within TRACEPOINT_EVENT */
770 #include <lttng/ust-tracepoint-event-reset.h>
771
772 #undef TRACEPOINT_LOGLEVEL
773 #define TRACEPOINT_LOGLEVEL(__provider, __name, __loglevel) \
774 static const int _loglevel_value___##__provider##___##__name = __loglevel; \
775 static const int *_loglevel___##__provider##___##__name = \
776 &_loglevel_value___##__provider##___##__name;
777
778 #include TRACEPOINT_INCLUDE
779
780 /*
781 * Stage 6.1 of tracepoint event generation.
782 *
783 * Tracepoint UML URI info.
784 */
785
786 /* Reset all macros within TRACEPOINT_EVENT */
787 #include <lttng/ust-tracepoint-event-reset.h>
788
789 #undef TRACEPOINT_MODEL_EMF_URI
790 #define TRACEPOINT_MODEL_EMF_URI(__provider, __name, __uri) \
791 static const char *_model_emf_uri___##__provider##___##__name = __uri;
792
793 #include TRACEPOINT_INCLUDE
794
795 /*
796 * Stage 7.1 of tracepoint event generation.
797 *
798 * Create events description structures. We use a weakref because
799 * loglevels are optional. If not declared, the event will point to the
800 * a loglevel that contains NULL.
801 */
802
803 /* Reset all macros within TRACEPOINT_EVENT */
804 #include <lttng/ust-tracepoint-event-reset.h>
805
806 #undef TRACEPOINT_EVENT_INSTANCE
807 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
808 static const int * \
809 __ref_loglevel___##_provider##___##_name \
810 __attribute__((weakref ("_loglevel___" #_provider "___" #_name))); \
811 static const char * \
812 __ref_model_emf_uri___##_provider##___##_name \
813 __attribute__((weakref ("_model_emf_uri___" #_provider "___" #_name)));\
814 const struct lttng_event_desc __event_desc___##_provider##_##_name = { \
815 .name = #_provider ":" #_name, \
816 .probe_callback = (void (*)(void)) &__event_probe__##_provider##___##_template,\
817 .ctx = NULL, \
818 .fields = __event_fields___##_provider##___##_template, \
819 .nr_fields = _TP_ARRAY_SIZE(__event_fields___##_provider##___##_template), \
820 .loglevel = &__ref_loglevel___##_provider##___##_name, \
821 .signature = __tp_event_signature___##_provider##___##_template, \
822 .u = { \
823 .ext = { \
824 .model_emf_uri = &__ref_model_emf_uri___##_provider##___##_name, \
825 }, \
826 }, \
827 };
828
829 #include TRACEPOINT_INCLUDE
830
831 /*
832 * Stage 7.2 of tracepoint event generation.
833 *
834 * Create array of events.
835 */
836
837 /* Reset all macros within TRACEPOINT_EVENT */
838 #include <lttng/ust-tracepoint-event-reset.h>
839
840 #undef TRACEPOINT_EVENT_INSTANCE
841 #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \
842 &__event_desc___##_provider##_##_name,
843
844 static const struct lttng_event_desc *_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)[] = {
845 #include TRACEPOINT_INCLUDE
846 };
847
848
849 /*
850 * Stage 8 of tracepoint event generation.
851 *
852 * Create a toplevel descriptor for the whole probe.
853 */
854
855 /* non-const because list head will be modified when registered. */
856 static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER) = {
857 .provider = __tp_stringify(TRACEPOINT_PROVIDER),
858 .event_desc = _TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER),
859 .nr_events = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)),
860 .head = { NULL, NULL },
861 .lazy_init_head = { NULL, NULL },
862 .lazy = 0,
863 .major = LTTNG_UST_PROVIDER_MAJOR,
864 .minor = LTTNG_UST_PROVIDER_MINOR,
865 };
866
867 static int _TP_COMBINE_TOKENS(__probe_register_refcount___, TRACEPOINT_PROVIDER);
868
869 /*
870 * Stage 9 of tracepoint event generation.
871 *
872 * Register/unregister probes at module load/unload.
873 *
874 * Generate the constructor as an externally visible symbol for use when
875 * linking the probe statically.
876 *
877 * Register refcount is protected by libc dynamic loader mutex.
878 */
879
880 /* Reset all macros within TRACEPOINT_EVENT */
881 #include <lttng/ust-tracepoint-event-reset.h>
882 static void lttng_ust_notrace __attribute__((constructor))
883 _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void);
884 static void
885 _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void)
886 {
887 int ret;
888
889 if (_TP_COMBINE_TOKENS(__probe_register_refcount___,
890 TRACEPOINT_PROVIDER)++) {
891 return;
892 }
893 /*
894 * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a
895 * static inline function that ensures every probe PROVIDER
896 * argument match the provider within which they appear. It
897 * calls empty static inline functions, and therefore has no
898 * runtime effect. However, if it detects an error, a linker
899 * error will appear.
900 */
901 _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)();
902 ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER));
903 if (ret) {
904 fprintf(stderr, "LTTng-UST: Error (%d) while registering tracepoint probe. Duplicate registration of tracepoint probes having the same name is not allowed.\n", ret);
905 abort();
906 }
907 }
908
909 static void lttng_ust_notrace __attribute__((destructor))
910 _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void);
911 static void
912 _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void)
913 {
914 if (--_TP_COMBINE_TOKENS(__probe_register_refcount___,
915 TRACEPOINT_PROVIDER)) {
916 return;
917 }
918 lttng_probe_unregister(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER));
919 }
920
921 int _TP_COMBINE_TOKENS(__tracepoint_provider_, TRACEPOINT_PROVIDER);
This page took 0.04917 seconds and 5 git commands to generate.