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