fc97e4dfb2510a72e86097e6bd28b7b57884149d
[libside.git] / src / tracer.c
1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include <string.h>
12
13 #include <side/trace.h>
14
15 enum tracer_display_base {
16 TRACER_DISPLAY_BASE_2,
17 TRACER_DISPLAY_BASE_8,
18 TRACER_DISPLAY_BASE_10,
19 TRACER_DISPLAY_BASE_16,
20 };
21
22 static struct side_tracer_handle *tracer_handle;
23
24 static
25 void tracer_print_struct(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec);
26 static
27 void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec);
28 static
29 void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec);
30 static
31 void tracer_print_vla_visitor(const struct side_type *type_desc, void *app_ctx);
32 static
33 void tracer_print_array_fixint(const struct side_type *type_desc, const struct side_arg *item);
34 static
35 void tracer_print_vla_fixint(const struct side_type *type_desc, const struct side_arg *item);
36 static
37 void tracer_print_dynamic(const struct side_arg *dynamic_item);
38 static
39 uint32_t tracer_print_gather_byte_type(const struct side_type_gather *type_gather, const void *_ptr);
40 static
41 uint32_t tracer_print_gather_integer_type(const struct side_type_gather *type_gather, const void *_ptr);
42 static
43 uint32_t tracer_print_gather_float_type(const struct side_type_gather *type_gather, const void *_ptr);
44 static
45 uint32_t tracer_print_gather_struct(const struct side_type_gather *type_gather, const void *_ptr);
46 static
47 uint32_t tracer_print_gather_array(const struct side_type_gather *type_gather, const void *_ptr);
48 static
49 uint32_t tracer_print_gather_vla(const struct side_type_gather *type_gather, const void *_ptr,
50 const void *_length_ptr);
51 static
52 void tracer_print_type(const struct side_type *type_desc, const struct side_arg *item);
53
54 static
55 int64_t get_attr_integer_value(const struct side_attr *attr)
56 {
57 int64_t val;
58
59 switch (attr->value.type) {
60 case SIDE_ATTR_TYPE_U8:
61 val = attr->value.u.integer_value.side_u8;
62 break;
63 case SIDE_ATTR_TYPE_U16:
64 val = attr->value.u.integer_value.side_u16;
65 break;
66 case SIDE_ATTR_TYPE_U32:
67 val = attr->value.u.integer_value.side_u32;
68 break;
69 case SIDE_ATTR_TYPE_U64:
70 val = attr->value.u.integer_value.side_u64;
71 break;
72 case SIDE_ATTR_TYPE_S8:
73 val = attr->value.u.integer_value.side_s8;
74 break;
75 case SIDE_ATTR_TYPE_S16:
76 val = attr->value.u.integer_value.side_s16;
77 break;
78 case SIDE_ATTR_TYPE_S32:
79 val = attr->value.u.integer_value.side_s32;
80 break;
81 case SIDE_ATTR_TYPE_S64:
82 val = attr->value.u.integer_value.side_s64;
83 break;
84 default:
85 fprintf(stderr, "Unexpected attribute type\n");
86 abort();
87 }
88 return val;
89 }
90
91 static
92 enum tracer_display_base get_attr_display_base(const struct side_attr *_attr, uint32_t nr_attr,
93 enum tracer_display_base default_base)
94 {
95 uint32_t i;
96
97 for (i = 0; i < nr_attr; i++) {
98 const struct side_attr *attr = &_attr[i];
99
100 if (!strcmp(attr->key, "std.integer.base")) {
101 int64_t val = get_attr_integer_value(attr);
102
103 switch (val) {
104 case 2:
105 return TRACER_DISPLAY_BASE_2;
106 case 8:
107 return TRACER_DISPLAY_BASE_8;
108 case 10:
109 return TRACER_DISPLAY_BASE_10;
110 case 16:
111 return TRACER_DISPLAY_BASE_16;
112 default:
113 fprintf(stderr, "Unexpected integer display base: %" PRId64 "\n", val);
114 abort();
115 }
116 }
117 }
118 return default_base; /* Default */
119 }
120
121 static
122 bool type_to_host_reverse_bo(const struct side_type *type_desc)
123 {
124 switch (type_desc->type) {
125 case SIDE_TYPE_U8:
126 case SIDE_TYPE_S8:
127 case SIDE_TYPE_BYTE:
128 return false;
129 case SIDE_TYPE_U16:
130 case SIDE_TYPE_U32:
131 case SIDE_TYPE_U64:
132 case SIDE_TYPE_S16:
133 case SIDE_TYPE_S32:
134 case SIDE_TYPE_S64:
135 case SIDE_TYPE_POINTER32:
136 case SIDE_TYPE_POINTER64:
137 if (type_desc->u.side_integer.byte_order != SIDE_TYPE_BYTE_ORDER_HOST)
138 return true;
139 else
140 return false;
141 break;
142 case SIDE_TYPE_FLOAT_BINARY16:
143 case SIDE_TYPE_FLOAT_BINARY32:
144 case SIDE_TYPE_FLOAT_BINARY64:
145 case SIDE_TYPE_FLOAT_BINARY128:
146 if (type_desc->u.side_float.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST)
147 return true;
148 else
149 return false;
150 break;
151 default:
152 fprintf(stderr, "Unexpected type\n");
153 abort();
154 }
155 }
156
157 static
158 void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
159 {
160 printf("{ key%s \"%s\", value%s ", separator, attr->key, separator);
161 switch (attr->value.type) {
162 case SIDE_ATTR_TYPE_BOOL:
163 printf("%s", attr->value.u.bool_value ? "true" : "false");
164 break;
165 case SIDE_ATTR_TYPE_U8:
166 printf("%" PRIu8, attr->value.u.integer_value.side_u8);
167 break;
168 case SIDE_ATTR_TYPE_U16:
169 printf("%" PRIu16, attr->value.u.integer_value.side_u16);
170 break;
171 case SIDE_ATTR_TYPE_U32:
172 printf("%" PRIu32, attr->value.u.integer_value.side_u32);
173 break;
174 case SIDE_ATTR_TYPE_U64:
175 printf("%" PRIu64, attr->value.u.integer_value.side_u64);
176 break;
177 case SIDE_ATTR_TYPE_S8:
178 printf("%" PRId8, attr->value.u.integer_value.side_s8);
179 break;
180 case SIDE_ATTR_TYPE_S16:
181 printf("%" PRId16, attr->value.u.integer_value.side_s16);
182 break;
183 case SIDE_ATTR_TYPE_S32:
184 printf("%" PRId32, attr->value.u.integer_value.side_s32);
185 break;
186 case SIDE_ATTR_TYPE_S64:
187 printf("%" PRId64, attr->value.u.integer_value.side_s64);
188 break;
189 case SIDE_ATTR_TYPE_POINTER32:
190 printf("0x%" PRIx32, attr->value.u.integer_value.side_u32);
191 break;
192 case SIDE_ATTR_TYPE_POINTER64:
193 printf("0x%" PRIx64, attr->value.u.integer_value.side_u64);
194 break;
195 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
196 #if __HAVE_FLOAT16
197 printf("%g", (double) attr->value.u.float_value.side_float_binary16);
198 break;
199 #else
200 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
201 abort();
202 #endif
203 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
204 #if __HAVE_FLOAT32
205 printf("%g", (double) attr->value.u.float_value.side_float_binary32);
206 break;
207 #else
208 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
209 abort();
210 #endif
211 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
212 #if __HAVE_FLOAT64
213 printf("%g", (double) attr->value.u.float_value.side_float_binary64);
214 break;
215 #else
216 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
217 abort();
218 #endif
219 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
220 #if __HAVE_FLOAT128
221 printf("%Lg", (long double) attr->value.u.float_value.side_float_binary128);
222 break;
223 #else
224 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
225 abort();
226 #endif
227 case SIDE_ATTR_TYPE_STRING:
228 printf("\"%s\"", (const char *)(uintptr_t) attr->value.u.string_value);
229 break;
230 default:
231 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
232 abort();
233 }
234 printf(" }");
235 }
236
237 static
238 void print_attributes(const char *prefix_str, const char *separator,
239 const struct side_attr *attr, uint32_t nr_attr)
240 {
241 uint32_t i;
242
243 if (!nr_attr)
244 return;
245 printf("%s%s [ ", prefix_str, separator);
246 for (i = 0; i < nr_attr; i++) {
247 printf("%s", i ? ", " : "");
248 tracer_print_attr_type(separator, &attr[i]);
249 }
250 printf(" ]");
251 }
252
253 static
254 void print_enum(const struct side_type *type_desc, const struct side_arg *item)
255 {
256 const struct side_enum_mappings *mappings = type_desc->u.side_enum.mappings;
257 const struct side_type *elem_type = type_desc->u.side_enum.elem_type;
258 uint32_t i, print_count = 0;
259 int64_t value;
260
261 if (elem_type->type != item->type) {
262 fprintf(stderr, "ERROR: Unexpected enum element type\n");
263 abort();
264 }
265 switch (item->type) {
266 case SIDE_TYPE_U8:
267 value = (int64_t) item->u.side_static.integer_value.side_u8;
268 break;
269 case SIDE_TYPE_U16:
270 {
271 uint16_t v;
272
273 v = item->u.side_static.integer_value.side_u16;
274 if (type_to_host_reverse_bo(elem_type))
275 v = side_bswap_16(v);
276 value = (int64_t) v;
277 break;
278 }
279 case SIDE_TYPE_U32:
280 {
281 uint32_t v;
282
283 v = item->u.side_static.integer_value.side_u32;
284 if (type_to_host_reverse_bo(elem_type))
285 v = side_bswap_32(v);
286 value = (int64_t) v;
287 break;
288 }
289 case SIDE_TYPE_U64:
290 {
291 uint64_t v;
292
293 v = item->u.side_static.integer_value.side_u64;
294 if (type_to_host_reverse_bo(elem_type))
295 v = side_bswap_64(v);
296 value = (int64_t) v;
297 break;
298 }
299 case SIDE_TYPE_S8:
300 value = (int64_t) item->u.side_static.integer_value.side_s8;
301 break;
302 case SIDE_TYPE_S16:
303 {
304 int16_t v;
305
306 v = item->u.side_static.integer_value.side_s16;
307 if (type_to_host_reverse_bo(elem_type))
308 v = side_bswap_16(v);
309 value = (int64_t) v;
310 break;
311 }
312 case SIDE_TYPE_S32:
313 {
314 int32_t v;
315
316 v = item->u.side_static.integer_value.side_s32;
317 if (type_to_host_reverse_bo(elem_type))
318 v = side_bswap_32(v);
319 value = (int64_t) v;
320 break;
321 }
322 case SIDE_TYPE_S64:
323 {
324 int64_t v;
325
326 v = item->u.side_static.integer_value.side_s64;
327 if (type_to_host_reverse_bo(elem_type))
328 v = side_bswap_64(v);
329 value = v;
330 break;
331 }
332 default:
333 fprintf(stderr, "ERROR: Unexpected enum element type\n");
334 abort();
335 }
336 print_attributes("attr", ":", mappings->attr, mappings->nr_attr);
337 printf("%s", mappings->nr_attr ? ", " : "");
338 tracer_print_type(type_desc->u.side_enum.elem_type, item);
339 printf(", labels: [ ");
340 for (i = 0; i < mappings->nr_mappings; i++) {
341 const struct side_enum_mapping *mapping = &mappings->mappings[i];
342
343 if (mapping->range_end < mapping->range_begin) {
344 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
345 mapping->range_begin, mapping->range_end);
346 abort();
347 }
348 if (value >= mapping->range_begin && value <= mapping->range_end) {
349 printf("%s", print_count++ ? ", " : "");
350 printf("\"%s\"", mapping->label);
351 }
352 }
353 if (!print_count)
354 printf("<NO LABEL>");
355 printf(" ]");
356 }
357
358 static
359 uint32_t enum_elem_type_to_stride(const struct side_type *elem_type)
360 {
361 uint32_t stride_bit;
362
363 switch (elem_type->type) {
364 case SIDE_TYPE_U8: /* Fall-through */
365 case SIDE_TYPE_BYTE:
366 stride_bit = 8;
367 break;
368 case SIDE_TYPE_U16:
369 stride_bit = 16;
370 break;
371 case SIDE_TYPE_U32:
372 stride_bit = 32;
373 break;
374 case SIDE_TYPE_U64:
375 stride_bit = 64;
376 break;
377 default:
378 fprintf(stderr, "ERROR: Unexpected enum element type\n");
379 abort();
380 }
381 return stride_bit;
382 }
383
384 static
385 void print_enum_bitmap(const struct side_type *type_desc,
386 const struct side_arg *item)
387 {
388 const struct side_type *elem_type = type_desc->u.side_enum_bitmap.elem_type;
389 const struct side_enum_bitmap_mappings *side_enum_mappings = type_desc->u.side_enum_bitmap.mappings;
390 uint32_t i, print_count = 0, stride_bit, nr_items;
391 bool reverse_byte_order = false;
392 const struct side_arg *array_item;
393
394 switch (elem_type->type) {
395 case SIDE_TYPE_U8: /* Fall-through */
396 case SIDE_TYPE_BYTE: /* Fall-through */
397 case SIDE_TYPE_U16: /* Fall-through */
398 case SIDE_TYPE_U32: /* Fall-through */
399 case SIDE_TYPE_U64:
400 stride_bit = enum_elem_type_to_stride(elem_type);
401 reverse_byte_order = type_to_host_reverse_bo(elem_type);
402 array_item = item;
403 nr_items = 1;
404 break;
405 case SIDE_TYPE_ARRAY:
406 stride_bit = enum_elem_type_to_stride(elem_type->u.side_array.elem_type);
407 reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_array.elem_type);
408 array_item = item->u.side_static.side_array->sav;
409 nr_items = type_desc->u.side_array.length;
410 break;
411 case SIDE_TYPE_VLA:
412 stride_bit = enum_elem_type_to_stride(elem_type->u.side_vla.elem_type);
413 reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_vla.elem_type);
414 array_item = item->u.side_static.side_vla->sav;
415 nr_items = item->u.side_static.side_vla->len;
416 break;
417 default:
418 fprintf(stderr, "ERROR: Unexpected enum element type\n");
419 abort();
420 }
421
422 print_attributes("attr", ":", side_enum_mappings->attr, side_enum_mappings->nr_attr);
423 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
424 printf("labels: [ ");
425 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
426 const struct side_enum_bitmap_mapping *mapping = &side_enum_mappings->mappings[i];
427 bool match = false;
428 uint64_t bit;
429
430 if (mapping->range_end < mapping->range_begin) {
431 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
432 mapping->range_begin, mapping->range_end);
433 abort();
434 }
435 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
436 if (bit > (nr_items * stride_bit) - 1)
437 break;
438 switch (stride_bit) {
439 case 8:
440 {
441 uint8_t v = array_item[bit / 8].u.side_static.integer_value.side_u8;
442 if (v & (1ULL << (bit % 8))) {
443 match = true;
444 goto match;
445 }
446 break;
447 }
448 case 16:
449 {
450 uint16_t v = array_item[bit / 16].u.side_static.integer_value.side_u16;
451 if (reverse_byte_order)
452 v = side_bswap_16(v);
453 if (v & (1ULL << (bit % 16))) {
454 match = true;
455 goto match;
456 }
457 break;
458 }
459 case 32:
460 {
461 uint32_t v = array_item[bit / 32].u.side_static.integer_value.side_u32;
462 if (reverse_byte_order)
463 v = side_bswap_32(v);
464 if (v & (1ULL << (bit % 32))) {
465 match = true;
466 goto match;
467 }
468 break;
469 }
470 case 64:
471 {
472 uint64_t v = array_item[bit / 64].u.side_static.integer_value.side_u64;
473 if (reverse_byte_order)
474 v = side_bswap_64(v);
475 if (v & (1ULL << (bit % 64))) {
476 match = true;
477 goto match;
478 }
479 break;
480 }
481 default:
482 abort();
483 }
484 }
485 match:
486 if (match) {
487 printf("%s", print_count++ ? ", " : "");
488 printf("\"%s\"", mapping->label);
489 }
490 }
491 if (!print_count)
492 printf("<NO LABEL>");
493 printf(" ]");
494 }
495
496 static
497 void print_integer_binary(uint64_t v, int bits)
498 {
499 int i;
500
501 printf("0b");
502 v <<= 64 - bits;
503 for (i = 0; i < bits; i++) {
504 printf("%c", v & (1ULL << 63) ? '1' : '0');
505 v <<= 1;
506 }
507 }
508
509 static
510 void tracer_print_type_header(const char *separator,
511 const struct side_attr *attr, uint32_t nr_attr)
512 {
513 print_attributes("attr", separator, attr, nr_attr);
514 printf("%s", nr_attr ? ", " : "");
515 printf("value%s ", separator);
516 }
517
518 static
519 void tracer_print_type_integer(const char *separator,
520 const struct side_type_integer *type_integer,
521 const union side_integer_value *value,
522 uint16_t offset_bits,
523 enum tracer_display_base default_base)
524 {
525 enum tracer_display_base base;
526 bool reverse_bo;
527 union {
528 uint64_t v_unsigned;
529 int64_t v_signed;
530 } v;
531
532 if (!type_integer->len_bits ||
533 type_integer->len_bits + offset_bits > type_integer->integer_size_bits)
534 abort();
535 reverse_bo = type_integer->byte_order != SIDE_TYPE_BYTE_ORDER_HOST;
536 base = get_attr_display_base(type_integer->attr,
537 type_integer->nr_attr,
538 default_base);
539 switch (type_integer->integer_size_bits) {
540 case 8:
541 if (type_integer->signedness)
542 v.v_signed = value->side_s8;
543 else
544 v.v_unsigned = value->side_u8;
545 break;
546 case 16:
547 if (type_integer->signedness) {
548 int16_t side_s16;
549
550 side_s16 = value->side_s16;
551 if (reverse_bo)
552 side_s16 = side_bswap_16(side_s16);
553 v.v_signed = side_s16;
554 } else {
555 uint16_t side_u16;
556
557 side_u16 = value->side_u16;
558 if (reverse_bo)
559 side_u16 = side_bswap_16(side_u16);
560 v.v_unsigned = side_u16;
561 }
562 break;
563 case 32:
564 if (type_integer->signedness) {
565 int32_t side_s32;
566
567 side_s32 = value->side_s32;
568 if (reverse_bo)
569 side_s32 = side_bswap_32(side_s32);
570 v.v_signed = side_s32;
571 } else {
572 uint32_t side_u32;
573
574 side_u32 = value->side_u32;
575 if (reverse_bo)
576 side_u32 = side_bswap_32(side_u32);
577 v.v_unsigned = side_u32;
578 }
579 break;
580 case 64:
581 if (type_integer->signedness) {
582 int64_t side_s64;
583
584 side_s64 = value->side_s64;
585 if (reverse_bo)
586 side_s64 = side_bswap_64(side_s64);
587 v.v_signed = side_s64;
588 } else {
589 uint64_t side_u64;
590
591 side_u64 = value->side_u64;
592 if (reverse_bo)
593 side_u64 = side_bswap_64(side_u64);
594 v.v_unsigned = side_u64;
595 }
596 break;
597 default:
598 abort();
599 }
600 v.v_unsigned >>= offset_bits;
601 if (type_integer->len_bits < 64)
602 v.v_unsigned &= (1ULL << type_integer->len_bits) - 1;
603 tracer_print_type_header(separator, type_integer->attr, type_integer->nr_attr);
604 switch (base) {
605 case TRACER_DISPLAY_BASE_2:
606 print_integer_binary(v.v_unsigned, type_integer->len_bits);
607 break;
608 case TRACER_DISPLAY_BASE_8:
609 printf("0%" PRIo64, v.v_unsigned);
610 break;
611 case TRACER_DISPLAY_BASE_10:
612 if (type_integer->signedness) {
613 /* Sign-extend. */
614 if (type_integer->len_bits < 64) {
615 if (v.v_unsigned & (1ULL << (type_integer->len_bits - 1)))
616 v.v_unsigned |= ~((1ULL << type_integer->len_bits) - 1);
617 }
618 printf("%" PRId64, v.v_signed);
619 } else {
620 printf("%" PRIu64, v.v_unsigned);
621 }
622 break;
623 case TRACER_DISPLAY_BASE_16:
624 printf("0x%" PRIx64, v.v_unsigned);
625 break;
626 default:
627 abort();
628 }
629 }
630
631 static
632 void tracer_print_type_float(const char *separator,
633 const struct side_type_float *type_float,
634 const union side_float_value *value)
635 {
636 bool reverse_bo;
637
638 reverse_bo = type_float->byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST;
639 tracer_print_type_header(separator, type_float->attr, type_float->nr_attr);
640 switch (type_float->float_size_bits) {
641 case 16:
642 {
643 #if __HAVE_FLOAT16
644 union {
645 _Float16 f;
646 uint16_t u;
647 } float16 = {
648 .f = value->side_float_binary16,
649 };
650
651 if (reverse_bo)
652 float16.u = side_bswap_16(float16.u);
653 tracer_print_type_header(":", type_desc->u.side_float.attr, type_desc->u.side_float.nr_attr);
654 printf("%g", (double) float16.f);
655 break;
656 #else
657 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
658 abort();
659 #endif
660 }
661 case 32:
662 {
663 #if __HAVE_FLOAT32
664 union {
665 _Float32 f;
666 uint32_t u;
667 } float32 = {
668 .f = value->side_float_binary32,
669 };
670
671 if (reverse_bo)
672 float32.u = side_bswap_32(float32.u);
673 printf("%g", (double) float32.f);
674 break;
675 #else
676 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
677 abort();
678 #endif
679 }
680 case 64:
681 {
682 #if __HAVE_FLOAT64
683 union {
684 _Float64 f;
685 uint64_t u;
686 } float64 = {
687 .f = value->side_float_binary64,
688 };
689
690 if (reverse_bo)
691 float64.u = side_bswap_64(float64.u);
692 printf("%g", (double) float64.f);
693 break;
694 #else
695 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
696 abort();
697 #endif
698 }
699 case 128:
700 {
701 #if __HAVE_FLOAT128
702 union {
703 _Float128 f;
704 char arr[16];
705 } float128 = {
706 .f = value->side_float_binary128,
707 };
708
709 if (reverse_bo)
710 side_bswap_128p(float128.arr);
711 printf("%Lg", (long double) float128.f);
712 break;
713 #else
714 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
715 abort();
716 #endif
717 }
718 default:
719 fprintf(stderr, "ERROR: Unknown float size\n");
720 abort();
721 }
722 }
723
724 static
725 void tracer_print_type(const struct side_type *type_desc, const struct side_arg *item)
726 {
727 enum side_type_label type;
728
729 switch (type_desc->type) {
730 case SIDE_TYPE_ARRAY:
731 switch (item->type) {
732 case SIDE_TYPE_ARRAY_U8:
733 case SIDE_TYPE_ARRAY_U16:
734 case SIDE_TYPE_ARRAY_U32:
735 case SIDE_TYPE_ARRAY_U64:
736 case SIDE_TYPE_ARRAY_S8:
737 case SIDE_TYPE_ARRAY_S16:
738 case SIDE_TYPE_ARRAY_S32:
739 case SIDE_TYPE_ARRAY_S64:
740 case SIDE_TYPE_ARRAY_POINTER32:
741 case SIDE_TYPE_ARRAY_POINTER64:
742 case SIDE_TYPE_ARRAY_BYTE:
743 case SIDE_TYPE_ARRAY:
744 break;
745 default:
746 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
747 abort();
748 break;
749 }
750 break;
751
752 case SIDE_TYPE_VLA:
753 switch (item->type) {
754 case SIDE_TYPE_VLA_U8:
755 case SIDE_TYPE_VLA_U16:
756 case SIDE_TYPE_VLA_U32:
757 case SIDE_TYPE_VLA_U64:
758 case SIDE_TYPE_VLA_S8:
759 case SIDE_TYPE_VLA_S16:
760 case SIDE_TYPE_VLA_S32:
761 case SIDE_TYPE_VLA_S64:
762 case SIDE_TYPE_VLA_BYTE:
763 case SIDE_TYPE_VLA_POINTER32:
764 case SIDE_TYPE_VLA_POINTER64:
765 case SIDE_TYPE_VLA:
766 break;
767 default:
768 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
769 abort();
770 break;
771 }
772 break;
773
774 case SIDE_TYPE_ENUM:
775 switch (item->type) {
776 case SIDE_TYPE_U8:
777 case SIDE_TYPE_U16:
778 case SIDE_TYPE_U32:
779 case SIDE_TYPE_U64:
780 case SIDE_TYPE_S8:
781 case SIDE_TYPE_S16:
782 case SIDE_TYPE_S32:
783 case SIDE_TYPE_S64:
784 break;
785 default:
786 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
787 abort();
788 break;
789 }
790 break;
791
792 case SIDE_TYPE_ENUM_BITMAP:
793 switch (item->type) {
794 case SIDE_TYPE_U8:
795 case SIDE_TYPE_BYTE:
796 case SIDE_TYPE_U16:
797 case SIDE_TYPE_U32:
798 case SIDE_TYPE_U64:
799 case SIDE_TYPE_ARRAY:
800 case SIDE_TYPE_VLA:
801 break;
802 default:
803 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
804 abort();
805 break;
806 }
807 break;
808
809 case SIDE_TYPE_DYNAMIC:
810 switch (item->type) {
811 case SIDE_TYPE_DYNAMIC_NULL:
812 case SIDE_TYPE_DYNAMIC_BOOL:
813 case SIDE_TYPE_DYNAMIC_U8:
814 case SIDE_TYPE_DYNAMIC_U16:
815 case SIDE_TYPE_DYNAMIC_U32:
816 case SIDE_TYPE_DYNAMIC_U64:
817 case SIDE_TYPE_DYNAMIC_S8:
818 case SIDE_TYPE_DYNAMIC_S16:
819 case SIDE_TYPE_DYNAMIC_S32:
820 case SIDE_TYPE_DYNAMIC_S64:
821 case SIDE_TYPE_DYNAMIC_BYTE:
822 case SIDE_TYPE_DYNAMIC_POINTER32:
823 case SIDE_TYPE_DYNAMIC_POINTER64:
824 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY16:
825 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY32:
826 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY64:
827 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY128:
828 case SIDE_TYPE_DYNAMIC_STRING:
829 case SIDE_TYPE_DYNAMIC_STRUCT:
830 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
831 case SIDE_TYPE_DYNAMIC_VLA:
832 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
833 break;
834 default:
835 fprintf(stderr, "ERROR: Unexpected dynamic type\n");
836 abort();
837 break;
838 }
839 break;
840
841 default:
842 if (type_desc->type != item->type) {
843 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
844 abort();
845 }
846 break;
847 }
848
849 if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP)
850 type = (enum side_type_label) type_desc->type;
851 else
852 type = (enum side_type_label) item->type;
853
854 printf("{ ");
855 switch (type) {
856 case SIDE_TYPE_NULL:
857 tracer_print_type_header(":", type_desc->u.side_null.attr, type_desc->u.side_null.nr_attr);
858 printf("<NULL TYPE>");
859 break;
860
861 case SIDE_TYPE_BOOL:
862 tracer_print_type_header(":", type_desc->u.side_bool.attr, type_desc->u.side_bool.nr_attr);
863 printf("%s", item->u.side_static.bool_value ? "true" : "false");
864 break;
865
866 case SIDE_TYPE_U8:
867 case SIDE_TYPE_U16:
868 case SIDE_TYPE_U32:
869 case SIDE_TYPE_U64:
870 case SIDE_TYPE_S8:
871 case SIDE_TYPE_S16:
872 case SIDE_TYPE_S32:
873 case SIDE_TYPE_S64:
874 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0,
875 TRACER_DISPLAY_BASE_10);
876 break;
877
878 case SIDE_TYPE_POINTER32:
879 case SIDE_TYPE_POINTER64:
880 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0,
881 TRACER_DISPLAY_BASE_16);
882 break;
883
884 case SIDE_TYPE_BYTE:
885 tracer_print_type_header(":", type_desc->u.side_byte.attr, type_desc->u.side_byte.nr_attr);
886 printf("0x%" PRIx8, item->u.side_static.byte_value);
887 break;
888
889 case SIDE_TYPE_ENUM:
890 print_enum(type_desc, item);
891 break;
892
893 case SIDE_TYPE_ENUM_BITMAP:
894 print_enum_bitmap(type_desc, item);
895 break;
896
897 case SIDE_TYPE_FLOAT_BINARY16:
898 case SIDE_TYPE_FLOAT_BINARY32:
899 case SIDE_TYPE_FLOAT_BINARY64:
900 case SIDE_TYPE_FLOAT_BINARY128:
901 tracer_print_type_float(":", &type_desc->u.side_float, &item->u.side_static.float_value);
902 break;
903
904 case SIDE_TYPE_STRING:
905 tracer_print_type_header(":", type_desc->u.side_string.attr, type_desc->u.side_string.nr_attr);
906 printf("\"%s\"", (const char *)(uintptr_t) item->u.side_static.string_value);
907 break;
908 case SIDE_TYPE_STRUCT:
909 tracer_print_struct(type_desc, item->u.side_static.side_struct);
910 break;
911 case SIDE_TYPE_GATHER_STRUCT:
912 (void) tracer_print_gather_struct(&type_desc->u.side_gather, item->u.side_static.side_struct_gather_ptr);
913 break;
914 case SIDE_TYPE_GATHER_ARRAY:
915 (void) tracer_print_gather_array(&type_desc->u.side_gather, item->u.side_static.side_array_gather_ptr);
916 break;
917 case SIDE_TYPE_GATHER_VLA:
918 (void) tracer_print_gather_vla(&type_desc->u.side_gather, item->u.side_static.side_vla_gather.ptr,
919 item->u.side_static.side_vla_gather.length_ptr);
920 break;
921 case SIDE_TYPE_GATHER_BYTE:
922 (void) tracer_print_gather_byte_type(&type_desc->u.side_gather, item->u.side_static.side_byte_gather_ptr);
923 break;
924 case SIDE_TYPE_GATHER_UNSIGNED_INT:
925 case SIDE_TYPE_GATHER_SIGNED_INT:
926 (void) tracer_print_gather_integer_type(&type_desc->u.side_gather, item->u.side_static.side_integer_gather_ptr);
927 break;
928 case SIDE_TYPE_GATHER_FLOAT:
929 (void) tracer_print_gather_float_type(&type_desc->u.side_gather, item->u.side_static.side_float_gather_ptr);
930 break;
931 case SIDE_TYPE_ARRAY:
932 tracer_print_array(type_desc, item->u.side_static.side_array);
933 break;
934 case SIDE_TYPE_VLA:
935 tracer_print_vla(type_desc, item->u.side_static.side_vla);
936 break;
937 case SIDE_TYPE_VLA_VISITOR:
938 tracer_print_vla_visitor(type_desc, item->u.side_static.side_vla_app_visitor_ctx);
939 break;
940 case SIDE_TYPE_ARRAY_U8:
941 case SIDE_TYPE_ARRAY_U16:
942 case SIDE_TYPE_ARRAY_U32:
943 case SIDE_TYPE_ARRAY_U64:
944 case SIDE_TYPE_ARRAY_S8:
945 case SIDE_TYPE_ARRAY_S16:
946 case SIDE_TYPE_ARRAY_S32:
947 case SIDE_TYPE_ARRAY_S64:
948 case SIDE_TYPE_ARRAY_BYTE:
949 case SIDE_TYPE_ARRAY_POINTER32:
950 case SIDE_TYPE_ARRAY_POINTER64:
951 tracer_print_array_fixint(type_desc, item);
952 break;
953 case SIDE_TYPE_VLA_U8:
954 case SIDE_TYPE_VLA_U16:
955 case SIDE_TYPE_VLA_U32:
956 case SIDE_TYPE_VLA_U64:
957 case SIDE_TYPE_VLA_S8:
958 case SIDE_TYPE_VLA_S16:
959 case SIDE_TYPE_VLA_S32:
960 case SIDE_TYPE_VLA_S64:
961 case SIDE_TYPE_VLA_BYTE:
962 case SIDE_TYPE_VLA_POINTER32:
963 case SIDE_TYPE_VLA_POINTER64:
964 tracer_print_vla_fixint(type_desc, item);
965 break;
966
967 /* Dynamic types */
968 case SIDE_TYPE_DYNAMIC_NULL:
969 case SIDE_TYPE_DYNAMIC_BOOL:
970 case SIDE_TYPE_DYNAMIC_U8:
971 case SIDE_TYPE_DYNAMIC_U16:
972 case SIDE_TYPE_DYNAMIC_U32:
973 case SIDE_TYPE_DYNAMIC_U64:
974 case SIDE_TYPE_DYNAMIC_S8:
975 case SIDE_TYPE_DYNAMIC_S16:
976 case SIDE_TYPE_DYNAMIC_S32:
977 case SIDE_TYPE_DYNAMIC_S64:
978 case SIDE_TYPE_DYNAMIC_BYTE:
979 case SIDE_TYPE_DYNAMIC_POINTER32:
980 case SIDE_TYPE_DYNAMIC_POINTER64:
981 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY16:
982 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY32:
983 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY64:
984 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY128:
985 case SIDE_TYPE_DYNAMIC_STRING:
986 case SIDE_TYPE_DYNAMIC_STRUCT:
987 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
988 case SIDE_TYPE_DYNAMIC_VLA:
989 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
990 tracer_print_dynamic(item);
991 break;
992 default:
993 fprintf(stderr, "<UNKNOWN TYPE>");
994 abort();
995 }
996 printf(" }");
997 }
998
999 static
1000 void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg *item)
1001 {
1002 printf("%s: ", item_desc->field_name);
1003 tracer_print_type(&item_desc->side_type, item);
1004 }
1005
1006 static
1007 void tracer_print_struct(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
1008 {
1009 const struct side_arg *sav = side_arg_vec->sav;
1010 uint32_t i, side_sav_len = side_arg_vec->len;
1011
1012 if (type_desc->u.side_struct->nr_fields != side_sav_len) {
1013 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n");
1014 abort();
1015 }
1016 print_attributes("attr", ":", type_desc->u.side_struct->attr, type_desc->u.side_struct->nr_attr);
1017 printf("%s", type_desc->u.side_struct->nr_attr ? ", " : "");
1018 printf("fields: { ");
1019 for (i = 0; i < side_sav_len; i++) {
1020 printf("%s", i ? ", " : "");
1021 tracer_print_field(&type_desc->u.side_struct->fields[i], &sav[i]);
1022 }
1023 printf(" }");
1024 }
1025
1026 static
1027 void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
1028 {
1029 const struct side_arg *sav = side_arg_vec->sav;
1030 uint32_t i, side_sav_len = side_arg_vec->len;
1031
1032 if (type_desc->u.side_array.length != side_sav_len) {
1033 fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n");
1034 abort();
1035 }
1036 print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
1037 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
1038 printf("elements: ");
1039 printf("[ ");
1040 for (i = 0; i < side_sav_len; i++) {
1041 printf("%s", i ? ", " : "");
1042 tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]);
1043 }
1044 printf(" ]");
1045 }
1046
1047 static
1048 void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
1049 {
1050 const struct side_arg *sav = side_arg_vec->sav;
1051 uint32_t i, side_sav_len = side_arg_vec->len;
1052
1053 print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
1054 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
1055 printf("elements: ");
1056 printf("[ ");
1057 for (i = 0; i < side_sav_len; i++) {
1058 printf("%s", i ? ", " : "");
1059 tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]);
1060 }
1061 printf(" ]");
1062 }
1063
1064 static
1065 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode, const char *ptr)
1066 {
1067 switch (access_mode) {
1068 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
1069 return ptr;
1070 case SIDE_TYPE_GATHER_ACCESS_POINTER:
1071 /* Dereference pointer */
1072 memcpy(&ptr, ptr, sizeof(ptr));
1073 return ptr;
1074 default:
1075 abort();
1076 }
1077 }
1078
1079 static
1080 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode, uint32_t len)
1081 {
1082 switch (access_mode) {
1083 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
1084 return len;
1085 case SIDE_TYPE_GATHER_ACCESS_POINTER:
1086 return sizeof(void *);
1087 default:
1088 abort();
1089 }
1090 }
1091
1092 static
1093 uint64_t tracer_load_gather_integer_type(const struct side_type_gather *type_gather, const void *_ptr)
1094 {
1095 enum side_type_gather_access_mode access_mode = type_gather->u.side_integer.access_mode;
1096 uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size_bits >> 3;
1097 const char *ptr = (const char *) _ptr;
1098 union side_integer_value value;
1099
1100 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset);
1101 memcpy(&value, ptr, integer_size_bytes);
1102 switch (type_gather->u.side_integer.type.integer_size_bits) {
1103 case 8:
1104 return (uint64_t) value.side_u8;
1105 case 16:
1106 return (uint64_t) value.side_u16;
1107 case 32:
1108 return (uint64_t) value.side_u32;
1109 case 64:
1110 return (uint64_t) value.side_u64;
1111 default:
1112 abort();
1113 }
1114 }
1115
1116 static
1117 uint32_t tracer_print_gather_byte_type(const struct side_type_gather *type_gather, const void *_ptr)
1118 {
1119 enum side_type_gather_access_mode access_mode = type_gather->u.side_byte.access_mode;
1120 const char *ptr = (const char *) _ptr;
1121 uint8_t value;
1122
1123 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_byte.offset);
1124 memcpy(&value, ptr, 1);
1125 tracer_print_type_header(":", type_gather->u.side_byte.type.attr,
1126 type_gather->u.side_byte.type.nr_attr);
1127 printf("0x%" PRIx8, value);
1128 return tracer_gather_size(access_mode, 1);
1129 }
1130
1131 static
1132 uint32_t tracer_print_gather_integer_type(const struct side_type_gather *type_gather, const void *_ptr)
1133 {
1134 enum side_type_gather_access_mode access_mode = type_gather->u.side_integer.access_mode;
1135 uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size_bits >> 3;
1136 const char *ptr = (const char *) _ptr;
1137 union side_integer_value value;
1138
1139 switch (type_gather->u.side_integer.type.integer_size_bits) {
1140 case 8:
1141 case 16:
1142 case 32:
1143 case 64:
1144 break;
1145 default:
1146 abort();
1147 }
1148 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset);
1149 memcpy(&value, ptr, integer_size_bytes);
1150 tracer_print_type_integer(":", &type_gather->u.side_integer.type, &value,
1151 type_gather->u.side_integer.offset_bits, TRACER_DISPLAY_BASE_10);
1152 return tracer_gather_size(access_mode, integer_size_bytes);
1153 }
1154
1155 static
1156 uint32_t tracer_print_gather_float_type(const struct side_type_gather *type_gather, const void *_ptr)
1157 {
1158 enum side_type_gather_access_mode access_mode = type_gather->u.side_float.access_mode;
1159 uint32_t float_size_bytes = type_gather->u.side_float.type.float_size_bits >> 3;
1160 const char *ptr = (const char *) _ptr;
1161 union side_float_value value;
1162
1163 switch (type_gather->u.side_float.type.float_size_bits) {
1164 case 16:
1165 case 32:
1166 case 64:
1167 case 128:
1168 break;
1169 default:
1170 abort();
1171 }
1172 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_float.offset);
1173 memcpy(&value, ptr, float_size_bytes);
1174 tracer_print_type_float(":", &type_gather->u.side_float.type, &value);
1175 return tracer_gather_size(access_mode, float_size_bytes);
1176 }
1177
1178 static
1179 uint32_t tracer_print_gather_type(const struct side_type *type_desc, const void *ptr)
1180 {
1181 uint32_t len;
1182
1183 printf("{ ");
1184 switch (type_desc->type) {
1185 case SIDE_TYPE_GATHER_BYTE:
1186 len = tracer_print_gather_byte_type(&type_desc->u.side_gather, ptr);
1187 break;
1188 case SIDE_TYPE_GATHER_UNSIGNED_INT:
1189 case SIDE_TYPE_GATHER_SIGNED_INT:
1190 len = tracer_print_gather_integer_type(&type_desc->u.side_gather, ptr);
1191 break;
1192 case SIDE_TYPE_GATHER_FLOAT:
1193 len = tracer_print_gather_float_type(&type_desc->u.side_gather, ptr);
1194 break;
1195 case SIDE_TYPE_GATHER_STRUCT:
1196 len = tracer_print_gather_struct(&type_desc->u.side_gather, ptr);
1197 break;
1198 case SIDE_TYPE_GATHER_ARRAY:
1199 len = tracer_print_gather_array(&type_desc->u.side_gather, ptr);
1200 break;
1201 case SIDE_TYPE_GATHER_VLA:
1202 len = tracer_print_gather_vla(&type_desc->u.side_gather, ptr, ptr);
1203 break;
1204 default:
1205 fprintf(stderr, "<UNKNOWN GATHER TYPE>");
1206 abort();
1207 }
1208 printf(" }");
1209 return len;
1210 }
1211
1212 static
1213 void tracer_print_gather_field(const struct side_event_field *field, const void *ptr)
1214 {
1215 printf("%s: ", field->field_name);
1216 (void) tracer_print_gather_type(&field->side_type, ptr);
1217 }
1218
1219 static
1220 uint32_t tracer_print_gather_struct(const struct side_type_gather *type_gather, const void *_ptr)
1221 {
1222 enum side_type_gather_access_mode access_mode = type_gather->u.side_struct.access_mode;
1223 const char *ptr = (const char *) _ptr;
1224 uint32_t i;
1225
1226 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_struct.offset);
1227 print_attributes("attr", ":", type_gather->u.side_struct.type->attr, type_gather->u.side_struct.type->nr_attr);
1228 printf("%s", type_gather->u.side_struct.type->nr_attr ? ", " : "");
1229 printf("fields: { ");
1230 for (i = 0; i < type_gather->u.side_struct.type->nr_fields; i++) {
1231 printf("%s", i ? ", " : "");
1232 tracer_print_gather_field(&type_gather->u.side_struct.type->fields[i], ptr);
1233 }
1234 printf(" }");
1235 return tracer_gather_size(access_mode, type_gather->u.side_struct.size);
1236 }
1237
1238 static
1239 uint32_t tracer_print_gather_array(const struct side_type_gather *type_gather, const void *_ptr)
1240 {
1241 enum side_type_gather_access_mode access_mode = type_gather->u.side_array.access_mode;
1242 const char *ptr = (const char *) _ptr, *orig_ptr;
1243 uint32_t i;
1244
1245 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_array.offset);
1246 orig_ptr = ptr;
1247 print_attributes("attr", ":", type_gather->u.side_array.type.attr, type_gather->u.side_array.type.nr_attr);
1248 printf("%s", type_gather->u.side_array.type.nr_attr ? ", " : "");
1249 printf("elements: ");
1250 printf("[ ");
1251 for (i = 0; i < type_gather->u.side_array.type.length; i++) {
1252 switch (type_gather->u.side_array.type.elem_type->type) {
1253 case SIDE_TYPE_GATHER_VLA:
1254 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
1255 abort();
1256 default:
1257 break;
1258 }
1259 printf("%s", i ? ", " : "");
1260 ptr += tracer_print_gather_type(type_gather->u.side_array.type.elem_type, ptr);
1261 }
1262 printf(" ]");
1263 return tracer_gather_size(access_mode, ptr - orig_ptr);
1264 }
1265
1266 static
1267 uint32_t tracer_print_gather_vla(const struct side_type_gather *type_gather, const void *_ptr,
1268 const void *_length_ptr)
1269 {
1270 enum side_type_gather_access_mode access_mode = type_gather->u.side_vla.access_mode;
1271 const char *ptr = (const char *) _ptr, *orig_ptr;
1272 const char *length_ptr = (const char *) _length_ptr;
1273 uint32_t i, length;
1274
1275 /* Access length */
1276 switch (type_gather->u.side_vla.length_type->type) {
1277 case SIDE_TYPE_GATHER_UNSIGNED_INT:
1278 case SIDE_TYPE_GATHER_SIGNED_INT:
1279 break;
1280 default:
1281 fprintf(stderr, "<gather VLA expects integer gather length type>\n");
1282 abort();
1283 }
1284 length = (uint32_t) tracer_load_gather_integer_type(&type_gather->u.side_vla.length_type->u.side_gather, length_ptr);
1285 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_vla.offset);
1286 orig_ptr = ptr;
1287 print_attributes("attr", ":", type_gather->u.side_vla.type.attr, type_gather->u.side_vla.type.nr_attr);
1288 printf("%s", type_gather->u.side_vla.type.nr_attr ? ", " : "");
1289 printf("elements: ");
1290 printf("[ ");
1291 for (i = 0; i < length; i++) {
1292 switch (type_gather->u.side_vla.type.elem_type->type) {
1293 case SIDE_TYPE_GATHER_VLA:
1294 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
1295 abort();
1296 default:
1297 break;
1298 }
1299 printf("%s", i ? ", " : "");
1300 ptr += tracer_print_gather_type(type_gather->u.side_vla.type.elem_type, ptr);
1301 }
1302 printf(" ]");
1303 return tracer_gather_size(access_mode, ptr - orig_ptr);
1304 }
1305
1306 struct tracer_visitor_priv {
1307 const struct side_type *elem_type;
1308 int i;
1309 };
1310
1311 static
1312 enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
1313 const struct side_arg *elem)
1314 {
1315 struct tracer_visitor_priv *tracer_priv = (struct tracer_visitor_priv *) tracer_ctx->priv;
1316
1317 printf("%s", tracer_priv->i++ ? ", " : "");
1318 tracer_print_type(tracer_priv->elem_type, elem);
1319 return SIDE_VISITOR_STATUS_OK;
1320 }
1321
1322 static
1323 void tracer_print_vla_visitor(const struct side_type *type_desc, void *app_ctx)
1324 {
1325 enum side_visitor_status status;
1326 struct tracer_visitor_priv tracer_priv = {
1327 .elem_type = type_desc->u.side_vla_visitor.elem_type,
1328 .i = 0,
1329 };
1330 const struct side_tracer_visitor_ctx tracer_ctx = {
1331 .write_elem = tracer_write_elem_cb,
1332 .priv = &tracer_priv,
1333 };
1334
1335 print_attributes("attr", ":", type_desc->u.side_vla_visitor.attr, type_desc->u.side_vla_visitor.nr_attr);
1336 printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : "");
1337 printf("elements: ");
1338 printf("[ ");
1339 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
1340 switch (status) {
1341 case SIDE_VISITOR_STATUS_OK:
1342 break;
1343 case SIDE_VISITOR_STATUS_ERROR:
1344 fprintf(stderr, "ERROR: Visitor error\n");
1345 abort();
1346 }
1347 printf(" ]");
1348 }
1349
1350 void tracer_print_array_fixint(const struct side_type *type_desc, const struct side_arg *item)
1351 {
1352 const struct side_type *elem_type = type_desc->u.side_array.elem_type;
1353 uint32_t i, side_sav_len = type_desc->u.side_array.length;
1354 void *p = item->u.side_static.side_array_fixint;
1355 enum side_type_label side_type;
1356
1357 print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
1358 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
1359 printf("elements: ");
1360 switch (item->type) {
1361 case SIDE_TYPE_ARRAY_U8:
1362 if (elem_type->type != SIDE_TYPE_U8)
1363 goto type_error;
1364 break;
1365 case SIDE_TYPE_ARRAY_U16:
1366 if (elem_type->type != SIDE_TYPE_U16)
1367 goto type_error;
1368 break;
1369 case SIDE_TYPE_ARRAY_U32:
1370 if (elem_type->type != SIDE_TYPE_U32)
1371 goto type_error;
1372 break;
1373 case SIDE_TYPE_ARRAY_U64:
1374 if (elem_type->type != SIDE_TYPE_U64)
1375 goto type_error;
1376 break;
1377 case SIDE_TYPE_ARRAY_S8:
1378 if (elem_type->type != SIDE_TYPE_S8)
1379 goto type_error;
1380 break;
1381 case SIDE_TYPE_ARRAY_S16:
1382 if (elem_type->type != SIDE_TYPE_S16)
1383 goto type_error;
1384 break;
1385 case SIDE_TYPE_ARRAY_S32:
1386 if (elem_type->type != SIDE_TYPE_S32)
1387 goto type_error;
1388 break;
1389 case SIDE_TYPE_ARRAY_S64:
1390 if (elem_type->type != SIDE_TYPE_S64)
1391 goto type_error;
1392 break;
1393 case SIDE_TYPE_ARRAY_BYTE:
1394 if (elem_type->type != SIDE_TYPE_BYTE)
1395 goto type_error;
1396 break;
1397 case SIDE_TYPE_ARRAY_POINTER32:
1398 if (elem_type->type != SIDE_TYPE_POINTER32)
1399 goto type_error;
1400 case SIDE_TYPE_ARRAY_POINTER64:
1401 if (elem_type->type != SIDE_TYPE_POINTER64)
1402 goto type_error;
1403 break;
1404 default:
1405 goto type_error;
1406 }
1407 side_type = (enum side_type_label) elem_type->type;
1408
1409 printf("[ ");
1410 for (i = 0; i < side_sav_len; i++) {
1411 struct side_arg sav_elem = {
1412 .type = side_type,
1413 };
1414
1415 switch (side_type) {
1416 case SIDE_TYPE_U8:
1417 sav_elem.u.side_static.integer_value.side_u8 = ((const uint8_t *) p)[i];
1418 break;
1419 case SIDE_TYPE_S8:
1420 sav_elem.u.side_static.integer_value.side_s8 = ((const int8_t *) p)[i];
1421 break;
1422 case SIDE_TYPE_U16:
1423 sav_elem.u.side_static.integer_value.side_u16 = ((const uint16_t *) p)[i];
1424 break;
1425 case SIDE_TYPE_S16:
1426 sav_elem.u.side_static.integer_value.side_s16 = ((const int16_t *) p)[i];
1427 break;
1428 case SIDE_TYPE_U32:
1429 sav_elem.u.side_static.integer_value.side_u32 = ((const uint32_t *) p)[i];
1430 break;
1431 case SIDE_TYPE_S32:
1432 sav_elem.u.side_static.integer_value.side_s32 = ((const int32_t *) p)[i];
1433 break;
1434 case SIDE_TYPE_U64:
1435 sav_elem.u.side_static.integer_value.side_u64 = ((const uint64_t *) p)[i];
1436 break;
1437 case SIDE_TYPE_S64:
1438 sav_elem.u.side_static.integer_value.side_s64 = ((const int64_t *) p)[i];
1439 break;
1440 case SIDE_TYPE_BYTE:
1441 sav_elem.u.side_static.byte_value = ((const uint8_t *) p)[i];
1442 break;
1443 case SIDE_TYPE_POINTER32:
1444 sav_elem.u.side_static.integer_value.side_u32 = ((const uint32_t *) p)[i];
1445 break;
1446 case SIDE_TYPE_POINTER64:
1447 sav_elem.u.side_static.integer_value.side_u64 = ((const uint64_t *) p)[i];
1448 break;
1449
1450 default:
1451 fprintf(stderr, "ERROR: Unexpected type\n");
1452 abort();
1453 }
1454
1455 printf("%s", i ? ", " : "");
1456 tracer_print_type(elem_type, &sav_elem);
1457 }
1458 printf(" ]");
1459 return;
1460
1461 type_error:
1462 fprintf(stderr, "ERROR: type mismatch\n");
1463 abort();
1464 }
1465
1466 void tracer_print_vla_fixint(const struct side_type *type_desc, const struct side_arg *item)
1467 {
1468 const struct side_type *elem_type = type_desc->u.side_vla.elem_type;
1469 uint32_t i, side_sav_len = item->u.side_static.side_vla_fixint.length;
1470 void *p = item->u.side_static.side_vla_fixint.p;
1471 enum side_type_label side_type;
1472
1473 print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
1474 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
1475 printf("elements: ");
1476 switch (item->type) {
1477 case SIDE_TYPE_VLA_U8:
1478 if (elem_type->type != SIDE_TYPE_U8)
1479 goto type_error;
1480 break;
1481 case SIDE_TYPE_VLA_U16:
1482 if (elem_type->type != SIDE_TYPE_U16)
1483 goto type_error;
1484 break;
1485 case SIDE_TYPE_VLA_U32:
1486 if (elem_type->type != SIDE_TYPE_U32)
1487 goto type_error;
1488 break;
1489 case SIDE_TYPE_VLA_U64:
1490 if (elem_type->type != SIDE_TYPE_U64)
1491 goto type_error;
1492 break;
1493 case SIDE_TYPE_VLA_S8:
1494 if (elem_type->type != SIDE_TYPE_S8)
1495 goto type_error;
1496 break;
1497 case SIDE_TYPE_VLA_S16:
1498 if (elem_type->type != SIDE_TYPE_S16)
1499 goto type_error;
1500 break;
1501 case SIDE_TYPE_VLA_S32:
1502 if (elem_type->type != SIDE_TYPE_S32)
1503 goto type_error;
1504 break;
1505 case SIDE_TYPE_VLA_S64:
1506 if (elem_type->type != SIDE_TYPE_S64)
1507 goto type_error;
1508 break;
1509 case SIDE_TYPE_VLA_BYTE:
1510 if (elem_type->type != SIDE_TYPE_BYTE)
1511 goto type_error;
1512 break;
1513 case SIDE_TYPE_VLA_POINTER32:
1514 if (elem_type->type != SIDE_TYPE_POINTER32)
1515 goto type_error;
1516 case SIDE_TYPE_VLA_POINTER64:
1517 if (elem_type->type != SIDE_TYPE_POINTER64)
1518 goto type_error;
1519 break;
1520 default:
1521 goto type_error;
1522 }
1523 side_type = (enum side_type_label) elem_type->type;
1524
1525 printf("[ ");
1526 for (i = 0; i < side_sav_len; i++) {
1527 struct side_arg sav_elem = {
1528 .type = side_type,
1529 };
1530
1531 switch (side_type) {
1532 case SIDE_TYPE_U8:
1533 sav_elem.u.side_static.integer_value.side_u8 = ((const uint8_t *) p)[i];
1534 break;
1535 case SIDE_TYPE_S8:
1536 sav_elem.u.side_static.integer_value.side_s8 = ((const int8_t *) p)[i];
1537 break;
1538 case SIDE_TYPE_U16:
1539 sav_elem.u.side_static.integer_value.side_u16 = ((const uint16_t *) p)[i];
1540 break;
1541 case SIDE_TYPE_S16:
1542 sav_elem.u.side_static.integer_value.side_s16 = ((const int16_t *) p)[i];
1543 break;
1544 case SIDE_TYPE_U32:
1545 sav_elem.u.side_static.integer_value.side_u32 = ((const uint32_t *) p)[i];
1546 break;
1547 case SIDE_TYPE_S32:
1548 sav_elem.u.side_static.integer_value.side_s32 = ((const int32_t *) p)[i];
1549 break;
1550 case SIDE_TYPE_U64:
1551 sav_elem.u.side_static.integer_value.side_u64 = ((const uint64_t *) p)[i];
1552 break;
1553 case SIDE_TYPE_S64:
1554 sav_elem.u.side_static.integer_value.side_s64 = ((const int64_t *) p)[i];
1555 break;
1556 case SIDE_TYPE_BYTE:
1557 sav_elem.u.side_static.byte_value = ((const uint8_t *) p)[i];
1558 break;
1559 case SIDE_TYPE_POINTER32:
1560 sav_elem.u.side_static.integer_value.side_u32 = ((const uint32_t *) p)[i];
1561 break;
1562 case SIDE_TYPE_POINTER64:
1563 sav_elem.u.side_static.integer_value.side_u64 = ((const uint64_t *) p)[i];
1564 break;
1565
1566 default:
1567 fprintf(stderr, "ERROR: Unexpected type\n");
1568 abort();
1569 }
1570
1571 printf("%s", i ? ", " : "");
1572 tracer_print_type(elem_type, &sav_elem);
1573 }
1574 printf(" ]");
1575 return;
1576
1577 type_error:
1578 fprintf(stderr, "ERROR: type mismatch\n");
1579 abort();
1580 }
1581
1582 static
1583 void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct)
1584 {
1585 const struct side_arg_dynamic_field *fields = dynamic_struct->fields;
1586 uint32_t i, len = dynamic_struct->len;
1587
1588 print_attributes("attr", "::", dynamic_struct->attr, dynamic_struct->nr_attr);
1589 printf("%s", dynamic_struct->nr_attr ? ", " : "");
1590 printf("fields:: ");
1591 printf("[ ");
1592 for (i = 0; i < len; i++) {
1593 printf("%s", i ? ", " : "");
1594 printf("%s:: ", fields[i].field_name);
1595 tracer_print_dynamic(&fields[i].elem);
1596 }
1597 printf(" ]");
1598 }
1599
1600 struct tracer_dynamic_struct_visitor_priv {
1601 int i;
1602 };
1603
1604 static
1605 enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
1606 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
1607 const struct side_arg_dynamic_field *dynamic_field)
1608 {
1609 struct tracer_dynamic_struct_visitor_priv *tracer_priv =
1610 (struct tracer_dynamic_struct_visitor_priv *) tracer_ctx->priv;
1611
1612 printf("%s", tracer_priv->i++ ? ", " : "");
1613 printf("%s:: ", dynamic_field->field_name);
1614 tracer_print_dynamic(&dynamic_field->elem);
1615 return SIDE_VISITOR_STATUS_OK;
1616 }
1617
1618 static
1619 void tracer_print_dynamic_struct_visitor(const struct side_arg *item)
1620 {
1621 enum side_visitor_status status;
1622 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
1623 .i = 0,
1624 };
1625 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
1626 .write_field = tracer_dynamic_struct_write_elem_cb,
1627 .priv = &tracer_priv,
1628 };
1629 void *app_ctx = item->u.side_dynamic.side_dynamic_struct_visitor.app_ctx;
1630
1631 print_attributes("attr", "::", item->u.side_dynamic.side_dynamic_struct_visitor.attr, item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr);
1632 printf("%s", item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr ? ", " : "");
1633 printf("fields:: ");
1634 printf("[ ");
1635 status = item->u.side_dynamic.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
1636 switch (status) {
1637 case SIDE_VISITOR_STATUS_OK:
1638 break;
1639 case SIDE_VISITOR_STATUS_ERROR:
1640 fprintf(stderr, "ERROR: Visitor error\n");
1641 abort();
1642 }
1643 printf(" ]");
1644 }
1645
1646 static
1647 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla *vla)
1648 {
1649 const struct side_arg *sav = vla->sav;
1650 uint32_t i, side_sav_len = vla->len;
1651
1652 print_attributes("attr", "::", vla->attr, vla->nr_attr);
1653 printf("%s", vla->nr_attr ? ", " : "");
1654 printf("elements:: ");
1655 printf("[ ");
1656 for (i = 0; i < side_sav_len; i++) {
1657 printf("%s", i ? ", " : "");
1658 tracer_print_dynamic(&sav[i]);
1659 }
1660 printf(" ]");
1661 }
1662
1663 struct tracer_dynamic_vla_visitor_priv {
1664 int i;
1665 };
1666
1667 static
1668 enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
1669 const struct side_tracer_visitor_ctx *tracer_ctx,
1670 const struct side_arg *elem)
1671 {
1672 struct tracer_dynamic_vla_visitor_priv *tracer_priv =
1673 (struct tracer_dynamic_vla_visitor_priv *) tracer_ctx->priv;
1674
1675 printf("%s", tracer_priv->i++ ? ", " : "");
1676 tracer_print_dynamic(elem);
1677 return SIDE_VISITOR_STATUS_OK;
1678 }
1679
1680 static
1681 void tracer_print_dynamic_vla_visitor(const struct side_arg *item)
1682 {
1683 enum side_visitor_status status;
1684 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
1685 .i = 0,
1686 };
1687 const struct side_tracer_visitor_ctx tracer_ctx = {
1688 .write_elem = tracer_dynamic_vla_write_elem_cb,
1689 .priv = &tracer_priv,
1690 };
1691 void *app_ctx = item->u.side_dynamic.side_dynamic_vla_visitor.app_ctx;
1692
1693 print_attributes("attr", "::", item->u.side_dynamic.side_dynamic_vla_visitor.attr, item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr);
1694 printf("%s", item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr ? ", " : "");
1695 printf("elements:: ");
1696 printf("[ ");
1697 status = item->u.side_dynamic.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
1698 switch (status) {
1699 case SIDE_VISITOR_STATUS_OK:
1700 break;
1701 case SIDE_VISITOR_STATUS_ERROR:
1702 fprintf(stderr, "ERROR: Visitor error\n");
1703 abort();
1704 }
1705 printf(" ]");
1706 }
1707
1708 static
1709 void tracer_print_dynamic(const struct side_arg *item)
1710 {
1711 printf("{ ");
1712 switch (item->type) {
1713 case SIDE_TYPE_DYNAMIC_NULL:
1714 tracer_print_type_header("::", item->u.side_dynamic.side_null.attr, item->u.side_dynamic.side_null.nr_attr);
1715 printf("<NULL TYPE>");
1716 break;
1717 case SIDE_TYPE_DYNAMIC_BOOL:
1718 tracer_print_type_header("::", item->u.side_dynamic.side_bool.type.attr, item->u.side_dynamic.side_bool.type.nr_attr);
1719 printf("%s", item->u.side_dynamic.side_bool.value ? "true" : "false");
1720 break;
1721 case SIDE_TYPE_DYNAMIC_U8:
1722 case SIDE_TYPE_DYNAMIC_U16:
1723 case SIDE_TYPE_DYNAMIC_U32:
1724 case SIDE_TYPE_DYNAMIC_U64:
1725 case SIDE_TYPE_DYNAMIC_S8:
1726 case SIDE_TYPE_DYNAMIC_S16:
1727 case SIDE_TYPE_DYNAMIC_S32:
1728 case SIDE_TYPE_DYNAMIC_S64:
1729 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
1730 TRACER_DISPLAY_BASE_10);
1731 break;
1732 case SIDE_TYPE_DYNAMIC_BYTE:
1733 tracer_print_type_header("::", item->u.side_dynamic.side_byte.type.attr, item->u.side_dynamic.side_byte.type.nr_attr);
1734 printf("0x%" PRIx8, item->u.side_dynamic.side_byte.value);
1735 break;
1736
1737 case SIDE_TYPE_DYNAMIC_POINTER32:
1738 case SIDE_TYPE_DYNAMIC_POINTER64:
1739 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
1740 TRACER_DISPLAY_BASE_16);
1741 break;
1742
1743 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY16:
1744 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY32:
1745 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY64:
1746 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY128:
1747 tracer_print_type_float("::", &item->u.side_dynamic.side_float.type,
1748 &item->u.side_dynamic.side_float.value);
1749 break;
1750
1751 case SIDE_TYPE_DYNAMIC_STRING:
1752 tracer_print_type_header("::", item->u.side_dynamic.side_string.type.attr, item->u.side_dynamic.side_string.type.nr_attr);
1753 printf("\"%s\"", (const char *)(uintptr_t) item->u.side_dynamic.side_string.value);
1754 break;
1755 case SIDE_TYPE_DYNAMIC_STRUCT:
1756 tracer_print_dynamic_struct(item->u.side_dynamic.side_dynamic_struct);
1757 break;
1758 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
1759 tracer_print_dynamic_struct_visitor(item);
1760 break;
1761 case SIDE_TYPE_DYNAMIC_VLA:
1762 tracer_print_dynamic_vla(item->u.side_dynamic.side_dynamic_vla);
1763 break;
1764 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
1765 tracer_print_dynamic_vla_visitor(item);
1766 break;
1767 default:
1768 fprintf(stderr, "<UNKNOWN TYPE>");
1769 abort();
1770 }
1771 printf(" }");
1772 }
1773
1774 static
1775 void tracer_print_static_fields(const struct side_event_description *desc,
1776 const struct side_arg_vec *side_arg_vec,
1777 uint32_t *nr_items)
1778 {
1779 const struct side_arg *sav = side_arg_vec->sav;
1780 uint32_t i, side_sav_len = side_arg_vec->len;
1781
1782 printf("provider: %s, event: %s", desc->provider_name, desc->event_name);
1783 if (desc->nr_fields != side_sav_len) {
1784 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1785 abort();
1786 }
1787 print_attributes(", attr", ":", desc->attr, desc->nr_attr);
1788 printf("%s", side_sav_len ? ", fields: [ " : "");
1789 for (i = 0; i < side_sav_len; i++) {
1790 printf("%s", i ? ", " : "");
1791 tracer_print_field(&desc->fields[i], &sav[i]);
1792 }
1793 if (nr_items)
1794 *nr_items = i;
1795 if (side_sav_len)
1796 printf(" ]");
1797 }
1798
1799 void tracer_call(const struct side_event_description *desc,
1800 const struct side_arg_vec *side_arg_vec,
1801 void *priv __attribute__((unused)))
1802 {
1803 uint32_t nr_fields = 0;
1804
1805 tracer_print_static_fields(desc, side_arg_vec, &nr_fields);
1806 printf("\n");
1807 }
1808
1809 void tracer_call_variadic(const struct side_event_description *desc,
1810 const struct side_arg_vec *side_arg_vec,
1811 const struct side_arg_dynamic_struct *var_struct,
1812 void *priv __attribute__((unused)))
1813 {
1814 uint32_t nr_fields = 0, i, var_struct_len = var_struct->len;
1815
1816 tracer_print_static_fields(desc, side_arg_vec, &nr_fields);
1817
1818 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
1819 fprintf(stderr, "ERROR: unexpected non-variadic event description\n");
1820 abort();
1821 }
1822 print_attributes(", attr ", "::", var_struct->attr, var_struct->nr_attr);
1823 printf("%s", var_struct_len ? ", fields:: [ " : "");
1824 for (i = 0; i < var_struct_len; i++, nr_fields++) {
1825 printf("%s", i ? ", " : "");
1826 printf("%s:: ", var_struct->fields[i].field_name);
1827 tracer_print_dynamic(&var_struct->fields[i].elem);
1828 }
1829 if (i)
1830 printf(" ]");
1831 printf("\n");
1832 }
1833
1834 void tracer_event_notification(enum side_tracer_notification notif,
1835 struct side_event_description **events, uint32_t nr_events, void *priv)
1836 {
1837 uint32_t i;
1838 int ret;
1839
1840 printf("----------------------------------------------------------\n");
1841 printf("Tracer notified of events %s\n",
1842 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1843 for (i = 0; i < nr_events; i++) {
1844 struct side_event_description *event = events[i];
1845
1846 /* Skip NULL pointers */
1847 if (!event)
1848 continue;
1849 printf("provider: %s, event: %s\n",
1850 event->provider_name, event->event_name);
1851 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
1852 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1853 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL);
1854 if (ret)
1855 abort();
1856 } else {
1857 ret = side_tracer_callback_register(event, tracer_call, NULL);
1858 if (ret)
1859 abort();
1860 }
1861 } else {
1862 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1863 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL);
1864 if (ret)
1865 abort();
1866 } else {
1867 ret = side_tracer_callback_unregister(event, tracer_call, NULL);
1868 if (ret)
1869 abort();
1870 }
1871 }
1872 }
1873 printf("----------------------------------------------------------\n");
1874 }
1875
1876 static __attribute__((constructor))
1877 void tracer_init(void);
1878 static
1879 void tracer_init(void)
1880 {
1881 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1882 if (!tracer_handle)
1883 abort();
1884 }
1885
1886 static __attribute__((destructor))
1887 void tracer_exit(void);
1888 static
1889 void tracer_exit(void)
1890 {
1891 side_tracer_event_notification_unregister(tracer_handle);
1892 }
This page took 0.065546 seconds and 4 git commands to generate.