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