1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 #include <side/trace.h>
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
,
22 static struct side_tracer_handle
*tracer_handle
;
25 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
27 void tracer_print_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
29 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
31 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
);
33 void tracer_print_array_fixint(const struct side_type
*type_desc
, const struct side_arg
*item
);
35 void tracer_print_vla_fixint(const struct side_type
*type_desc
, const struct side_arg
*item
);
37 void tracer_print_dynamic(const struct side_arg
*dynamic_item
);
39 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
);
41 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
43 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
45 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
);
47 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
);
49 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
);
52 int64_t get_attr_integer_value(const struct side_attr
*attr
)
56 switch (attr
->value
.type
) {
57 case SIDE_ATTR_TYPE_U8
:
58 val
= attr
->value
.u
.integer_value
.side_u8
;
60 case SIDE_ATTR_TYPE_U16
:
61 val
= attr
->value
.u
.integer_value
.side_u16
;
63 case SIDE_ATTR_TYPE_U32
:
64 val
= attr
->value
.u
.integer_value
.side_u32
;
66 case SIDE_ATTR_TYPE_U64
:
67 val
= attr
->value
.u
.integer_value
.side_u64
;
69 case SIDE_ATTR_TYPE_S8
:
70 val
= attr
->value
.u
.integer_value
.side_s8
;
72 case SIDE_ATTR_TYPE_S16
:
73 val
= attr
->value
.u
.integer_value
.side_s16
;
75 case SIDE_ATTR_TYPE_S32
:
76 val
= attr
->value
.u
.integer_value
.side_s32
;
78 case SIDE_ATTR_TYPE_S64
:
79 val
= attr
->value
.u
.integer_value
.side_s64
;
82 fprintf(stderr
, "Unexpected attribute type\n");
89 enum tracer_display_base
get_attr_display_base(const struct side_attr
*_attr
, uint32_t nr_attr
,
90 enum tracer_display_base default_base
)
94 for (i
= 0; i
< nr_attr
; i
++) {
95 const struct side_attr
*attr
= &_attr
[i
];
97 if (!strcmp(attr
->key
, "std.integer.base")) {
98 int64_t val
= get_attr_integer_value(attr
);
102 return TRACER_DISPLAY_BASE_2
;
104 return TRACER_DISPLAY_BASE_8
;
106 return TRACER_DISPLAY_BASE_10
;
108 return TRACER_DISPLAY_BASE_16
;
110 fprintf(stderr
, "Unexpected integer display base: %" PRId64
"\n", val
);
115 return default_base
; /* Default */
119 bool type_to_host_reverse_bo(const struct side_type
*type_desc
)
121 switch (type_desc
->type
) {
132 case SIDE_TYPE_POINTER32
:
133 case SIDE_TYPE_POINTER64
:
134 if (type_desc
->u
.side_integer
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
139 case SIDE_TYPE_FLOAT_BINARY16
:
140 case SIDE_TYPE_FLOAT_BINARY32
:
141 case SIDE_TYPE_FLOAT_BINARY64
:
142 case SIDE_TYPE_FLOAT_BINARY128
:
143 if (type_desc
->u
.side_float
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
149 fprintf(stderr
, "Unexpected type\n");
155 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
157 printf("{ key%s \"%s\", value%s ", separator
, attr
->key
, separator
);
158 switch (attr
->value
.type
) {
159 case SIDE_ATTR_TYPE_BOOL
:
160 printf("%s", attr
->value
.u
.bool_value
? "true" : "false");
162 case SIDE_ATTR_TYPE_U8
:
163 printf("%" PRIu8
, attr
->value
.u
.integer_value
.side_u8
);
165 case SIDE_ATTR_TYPE_U16
:
166 printf("%" PRIu16
, attr
->value
.u
.integer_value
.side_u16
);
168 case SIDE_ATTR_TYPE_U32
:
169 printf("%" PRIu32
, attr
->value
.u
.integer_value
.side_u32
);
171 case SIDE_ATTR_TYPE_U64
:
172 printf("%" PRIu64
, attr
->value
.u
.integer_value
.side_u64
);
174 case SIDE_ATTR_TYPE_S8
:
175 printf("%" PRId8
, attr
->value
.u
.integer_value
.side_s8
);
177 case SIDE_ATTR_TYPE_S16
:
178 printf("%" PRId16
, attr
->value
.u
.integer_value
.side_s16
);
180 case SIDE_ATTR_TYPE_S32
:
181 printf("%" PRId32
, attr
->value
.u
.integer_value
.side_s32
);
183 case SIDE_ATTR_TYPE_S64
:
184 printf("%" PRId64
, attr
->value
.u
.integer_value
.side_s64
);
186 case SIDE_ATTR_TYPE_POINTER32
:
187 printf("0x%" PRIx32
, attr
->value
.u
.integer_value
.side_u32
);
189 case SIDE_ATTR_TYPE_POINTER64
:
190 printf("0x%" PRIx64
, attr
->value
.u
.integer_value
.side_u64
);
192 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
194 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary16
);
197 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
200 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
202 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary32
);
205 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
208 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
210 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary64
);
213 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
216 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
218 printf("%Lg", (long double) attr
->value
.u
.float_value
.side_float_binary128
);
221 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
224 case SIDE_ATTR_TYPE_STRING
:
225 printf("\"%s\"", (const char *)(uintptr_t) attr
->value
.u
.string_value
);
228 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
235 void print_attributes(const char *prefix_str
, const char *separator
,
236 const struct side_attr
*attr
, uint32_t nr_attr
)
242 printf("%s%s [ ", prefix_str
, separator
);
243 for (i
= 0; i
< nr_attr
; i
++) {
244 printf("%s", i
? ", " : "");
245 tracer_print_attr_type(separator
, &attr
[i
]);
251 void print_enum(const struct side_type
*type_desc
, const struct side_arg
*item
)
253 const struct side_enum_mappings
*mappings
= type_desc
->u
.side_enum
.mappings
;
254 const struct side_type
*elem_type
= type_desc
->u
.side_enum
.elem_type
;
255 uint32_t i
, print_count
= 0;
258 if (elem_type
->type
!= item
->type
) {
259 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
262 switch (item
->type
) {
264 value
= (int64_t) item
->u
.side_static
.integer_value
.side_u8
;
270 v
= item
->u
.side_static
.integer_value
.side_u16
;
271 if (type_to_host_reverse_bo(elem_type
))
272 v
= side_bswap_16(v
);
280 v
= item
->u
.side_static
.integer_value
.side_u32
;
281 if (type_to_host_reverse_bo(elem_type
))
282 v
= side_bswap_32(v
);
290 v
= item
->u
.side_static
.integer_value
.side_u64
;
291 if (type_to_host_reverse_bo(elem_type
))
292 v
= side_bswap_64(v
);
297 value
= (int64_t) item
->u
.side_static
.integer_value
.side_s8
;
303 v
= item
->u
.side_static
.integer_value
.side_s16
;
304 if (type_to_host_reverse_bo(elem_type
))
305 v
= side_bswap_16(v
);
313 v
= item
->u
.side_static
.integer_value
.side_s32
;
314 if (type_to_host_reverse_bo(elem_type
))
315 v
= side_bswap_32(v
);
323 v
= item
->u
.side_static
.integer_value
.side_s64
;
324 if (type_to_host_reverse_bo(elem_type
))
325 v
= side_bswap_64(v
);
330 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
333 print_attributes("attr", ":", mappings
->attr
, mappings
->nr_attr
);
334 printf("%s", mappings
->nr_attr
? ", " : "");
335 tracer_print_type(type_desc
->u
.side_enum
.elem_type
, item
);
336 printf(", labels: [ ");
337 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
338 const struct side_enum_mapping
*mapping
= &mappings
->mappings
[i
];
340 if (mapping
->range_end
< mapping
->range_begin
) {
341 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
342 mapping
->range_begin
, mapping
->range_end
);
345 if (value
>= mapping
->range_begin
&& value
<= mapping
->range_end
) {
346 printf("%s", print_count
++ ? ", " : "");
347 printf("\"%s\"", mapping
->label
);
351 printf("<NO LABEL>");
356 uint32_t enum_elem_type_to_stride(const struct side_type
*elem_type
)
360 switch (elem_type
->type
) {
361 case SIDE_TYPE_U8
: /* Fall-through */
375 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
382 void print_enum_bitmap(const struct side_type
*type_desc
,
383 const struct side_arg
*item
)
385 const struct side_type
*elem_type
= type_desc
->u
.side_enum_bitmap
.elem_type
;
386 const struct side_enum_bitmap_mappings
*side_enum_mappings
= type_desc
->u
.side_enum_bitmap
.mappings
;
387 uint32_t i
, print_count
= 0, stride_bit
, nr_items
;
388 bool reverse_byte_order
= false;
389 const struct side_arg
*array_item
;
391 switch (elem_type
->type
) {
392 case SIDE_TYPE_U8
: /* Fall-through */
393 case SIDE_TYPE_BYTE
: /* Fall-through */
394 case SIDE_TYPE_U16
: /* Fall-through */
395 case SIDE_TYPE_U32
: /* Fall-through */
397 stride_bit
= enum_elem_type_to_stride(elem_type
);
398 reverse_byte_order
= type_to_host_reverse_bo(elem_type
);
402 case SIDE_TYPE_ARRAY
:
403 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_array
.elem_type
);
404 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_array
.elem_type
);
405 array_item
= item
->u
.side_static
.side_array
->sav
;
406 nr_items
= type_desc
->u
.side_array
.length
;
409 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_vla
.elem_type
);
410 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_vla
.elem_type
);
411 array_item
= item
->u
.side_static
.side_vla
->sav
;
412 nr_items
= item
->u
.side_static
.side_vla
->len
;
415 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
419 print_attributes("attr", ":", side_enum_mappings
->attr
, side_enum_mappings
->nr_attr
);
420 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
421 printf("labels: [ ");
422 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
423 const struct side_enum_bitmap_mapping
*mapping
= &side_enum_mappings
->mappings
[i
];
427 if (mapping
->range_end
< mapping
->range_begin
) {
428 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
429 mapping
->range_begin
, mapping
->range_end
);
432 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
433 if (bit
> (nr_items
* stride_bit
) - 1)
435 switch (stride_bit
) {
438 uint8_t v
= array_item
[bit
/ 8].u
.side_static
.integer_value
.side_u8
;
439 if (v
& (1ULL << (bit
% 8))) {
447 uint16_t v
= array_item
[bit
/ 16].u
.side_static
.integer_value
.side_u16
;
448 if (reverse_byte_order
)
449 v
= side_bswap_16(v
);
450 if (v
& (1ULL << (bit
% 16))) {
458 uint32_t v
= array_item
[bit
/ 32].u
.side_static
.integer_value
.side_u32
;
459 if (reverse_byte_order
)
460 v
= side_bswap_32(v
);
461 if (v
& (1ULL << (bit
% 32))) {
469 uint64_t v
= array_item
[bit
/ 64].u
.side_static
.integer_value
.side_u64
;
470 if (reverse_byte_order
)
471 v
= side_bswap_64(v
);
472 if (v
& (1ULL << (bit
% 64))) {
484 printf("%s", print_count
++ ? ", " : "");
485 printf("\"%s\"", mapping
->label
);
489 printf("<NO LABEL>");
494 void print_integer_binary(uint64_t v
, int bits
)
500 for (i
= 0; i
< bits
; i
++) {
501 printf("%c", v
& (1ULL << 63) ? '1' : '0');
507 void tracer_print_type_header(const char *separator
,
508 const struct side_attr
*attr
, uint32_t nr_attr
)
510 print_attributes("attr", separator
, attr
, nr_attr
);
511 printf("%s", nr_attr
? ", " : "");
512 printf("value%s ", separator
);
516 void tracer_print_type_integer(const char *separator
,
517 const struct side_type_integer
*type_integer
,
518 const union side_integer_value
*value
,
519 uint16_t offset_bits
,
520 enum tracer_display_base default_base
)
522 enum tracer_display_base base
;
529 if (!type_integer
->len_bits
||
530 type_integer
->len_bits
+ offset_bits
> type_integer
->integer_size_bits
)
532 reverse_bo
= type_integer
->byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
;
533 base
= get_attr_display_base(type_integer
->attr
,
534 type_integer
->nr_attr
,
536 switch (type_integer
->integer_size_bits
) {
538 if (type_integer
->signedness
)
539 v
.v_signed
= value
->side_s8
;
541 v
.v_unsigned
= value
->side_u8
;
544 if (type_integer
->signedness
) {
547 side_s16
= value
->side_s16
;
549 side_s16
= side_bswap_16(side_s16
);
550 v
.v_signed
= side_s16
;
554 side_u16
= value
->side_u16
;
556 side_u16
= side_bswap_16(side_u16
);
557 v
.v_unsigned
= side_u16
;
561 if (type_integer
->signedness
) {
564 side_s32
= value
->side_s32
;
566 side_s32
= side_bswap_32(side_s32
);
567 v
.v_signed
= side_s32
;
571 side_u32
= value
->side_u32
;
573 side_u32
= side_bswap_32(side_u32
);
574 v
.v_unsigned
= side_u32
;
578 if (type_integer
->signedness
) {
581 side_s64
= value
->side_s64
;
583 side_s64
= side_bswap_64(side_s64
);
584 v
.v_signed
= side_s64
;
588 side_u64
= value
->side_u64
;
590 side_u64
= side_bswap_64(side_u64
);
591 v
.v_unsigned
= side_u64
;
597 v
.v_unsigned
>>= offset_bits
;
598 if (type_integer
->len_bits
< 64)
599 v
.v_unsigned
&= (1ULL << type_integer
->len_bits
) - 1;
600 tracer_print_type_header(separator
, type_integer
->attr
, type_integer
->nr_attr
);
602 case TRACER_DISPLAY_BASE_2
:
603 print_integer_binary(v
.v_unsigned
, type_integer
->len_bits
);
605 case TRACER_DISPLAY_BASE_8
:
606 printf("0%" PRIo64
, v
.v_unsigned
);
608 case TRACER_DISPLAY_BASE_10
:
609 if (type_integer
->signedness
) {
611 if (type_integer
->len_bits
< 64) {
612 if (v
.v_unsigned
& (1ULL << (type_integer
->len_bits
- 1)))
613 v
.v_unsigned
|= ~((1ULL << type_integer
->len_bits
) - 1);
615 printf("%" PRId64
, v
.v_signed
);
617 printf("%" PRIu64
, v
.v_unsigned
);
620 case TRACER_DISPLAY_BASE_16
:
621 printf("0x%" PRIx64
, v
.v_unsigned
);
629 void tracer_print_type_float(const char *separator
,
630 const struct side_type_float
*type_float
,
631 const union side_float_value
*value
)
635 reverse_bo
= type_float
->byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
;
636 tracer_print_type_header(separator
, type_float
->attr
, type_float
->nr_attr
);
637 switch (type_float
->float_size_bits
) {
645 .f
= value
->side_float_binary16
,
649 float16
.u
= side_bswap_16(float16
.u
);
650 tracer_print_type_header(":", type_desc
->u
.side_float
.attr
, type_desc
->u
.side_float
.nr_attr
);
651 printf("%g", (double) float16
.f
);
654 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
665 .f
= value
->side_float_binary32
,
669 float32
.u
= side_bswap_32(float32
.u
);
670 printf("%g", (double) float32
.f
);
673 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
684 .f
= value
->side_float_binary64
,
688 float64
.u
= side_bswap_64(float64
.u
);
689 printf("%g", (double) float64
.f
);
692 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
703 .f
= value
->side_float_binary128
,
707 side_bswap_128p(float128
.arr
);
708 printf("%Lg", (long double) float128
.f
);
711 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
716 fprintf(stderr
, "ERROR: Unknown float size\n");
722 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
)
724 enum side_type_label type
;
726 switch (type_desc
->type
) {
727 case SIDE_TYPE_ARRAY
:
728 switch (item
->type
) {
729 case SIDE_TYPE_ARRAY_U8
:
730 case SIDE_TYPE_ARRAY_U16
:
731 case SIDE_TYPE_ARRAY_U32
:
732 case SIDE_TYPE_ARRAY_U64
:
733 case SIDE_TYPE_ARRAY_S8
:
734 case SIDE_TYPE_ARRAY_S16
:
735 case SIDE_TYPE_ARRAY_S32
:
736 case SIDE_TYPE_ARRAY_S64
:
737 case SIDE_TYPE_ARRAY_POINTER32
:
738 case SIDE_TYPE_ARRAY_POINTER64
:
739 case SIDE_TYPE_ARRAY_BYTE
:
740 case SIDE_TYPE_ARRAY
:
743 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
750 switch (item
->type
) {
751 case SIDE_TYPE_VLA_U8
:
752 case SIDE_TYPE_VLA_U16
:
753 case SIDE_TYPE_VLA_U32
:
754 case SIDE_TYPE_VLA_U64
:
755 case SIDE_TYPE_VLA_S8
:
756 case SIDE_TYPE_VLA_S16
:
757 case SIDE_TYPE_VLA_S32
:
758 case SIDE_TYPE_VLA_S64
:
759 case SIDE_TYPE_VLA_BYTE
:
760 case SIDE_TYPE_VLA_POINTER32
:
761 case SIDE_TYPE_VLA_POINTER64
:
765 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
772 switch (item
->type
) {
783 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
789 case SIDE_TYPE_ENUM_BITMAP
:
790 switch (item
->type
) {
796 case SIDE_TYPE_ARRAY
:
800 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
806 case SIDE_TYPE_DYNAMIC
:
807 switch (item
->type
) {
808 case SIDE_TYPE_DYNAMIC_NULL
:
809 case SIDE_TYPE_DYNAMIC_BOOL
:
810 case SIDE_TYPE_DYNAMIC_U8
:
811 case SIDE_TYPE_DYNAMIC_U16
:
812 case SIDE_TYPE_DYNAMIC_U32
:
813 case SIDE_TYPE_DYNAMIC_U64
:
814 case SIDE_TYPE_DYNAMIC_S8
:
815 case SIDE_TYPE_DYNAMIC_S16
:
816 case SIDE_TYPE_DYNAMIC_S32
:
817 case SIDE_TYPE_DYNAMIC_S64
:
818 case SIDE_TYPE_DYNAMIC_BYTE
:
819 case SIDE_TYPE_DYNAMIC_POINTER32
:
820 case SIDE_TYPE_DYNAMIC_POINTER64
:
821 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY16
:
822 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY32
:
823 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY64
:
824 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY128
:
825 case SIDE_TYPE_DYNAMIC_STRING
:
826 case SIDE_TYPE_DYNAMIC_STRUCT
:
827 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
828 case SIDE_TYPE_DYNAMIC_VLA
:
829 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
832 fprintf(stderr
, "ERROR: Unexpected dynamic type\n");
839 if (type_desc
->type
!= item
->type
) {
840 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
846 if (type_desc
->type
== SIDE_TYPE_ENUM
|| type_desc
->type
== SIDE_TYPE_ENUM_BITMAP
)
847 type
= (enum side_type_label
) type_desc
->type
;
849 type
= (enum side_type_label
) item
->type
;
854 tracer_print_type_header(":", type_desc
->u
.side_null
.attr
, type_desc
->u
.side_null
.nr_attr
);
855 printf("<NULL TYPE>");
859 tracer_print_type_header(":", type_desc
->u
.side_bool
.attr
, type_desc
->u
.side_bool
.nr_attr
);
860 printf("%s", item
->u
.side_static
.bool_value
? "true" : "false");
871 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
872 TRACER_DISPLAY_BASE_10
);
875 case SIDE_TYPE_POINTER32
:
876 case SIDE_TYPE_POINTER64
:
877 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
878 TRACER_DISPLAY_BASE_16
);
882 tracer_print_type_header(":", type_desc
->u
.side_byte
.attr
, type_desc
->u
.side_byte
.nr_attr
);
883 printf("0x%" PRIx8
, item
->u
.side_static
.byte_value
);
887 print_enum(type_desc
, item
);
890 case SIDE_TYPE_ENUM_BITMAP
:
891 print_enum_bitmap(type_desc
, item
);
894 case SIDE_TYPE_FLOAT_BINARY16
:
895 case SIDE_TYPE_FLOAT_BINARY32
:
896 case SIDE_TYPE_FLOAT_BINARY64
:
897 case SIDE_TYPE_FLOAT_BINARY128
:
898 tracer_print_type_float(":", &type_desc
->u
.side_float
, &item
->u
.side_static
.float_value
);
901 case SIDE_TYPE_STRING
:
902 tracer_print_type_header(":", type_desc
->u
.side_string
.attr
, type_desc
->u
.side_string
.nr_attr
);
903 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.side_static
.string_value
);
905 case SIDE_TYPE_STRUCT
:
906 tracer_print_struct(type_desc
, item
->u
.side_static
.side_struct
);
908 case SIDE_TYPE_GATHER_STRUCT
:
909 (void) tracer_print_gather_struct(&type_desc
->u
.side_gather
, &item
->u
.side_static
.side_struct_gather_ptr
);
911 case SIDE_TYPE_GATHER_ARRAY
:
912 (void) tracer_print_gather_array(&type_desc
->u
.side_gather
, &item
->u
.side_static
.side_array_gather_ptr
);
914 case SIDE_TYPE_GATHER_UNSIGNED_INT
:
915 case SIDE_TYPE_GATHER_SIGNED_INT
:
916 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
);
918 case SIDE_TYPE_GATHER_FLOAT
:
919 (void) tracer_print_gather_float_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_float_gather_ptr
);
921 case SIDE_TYPE_ARRAY
:
922 tracer_print_array(type_desc
, item
->u
.side_static
.side_array
);
925 tracer_print_vla(type_desc
, item
->u
.side_static
.side_vla
);
927 case SIDE_TYPE_VLA_VISITOR
:
928 tracer_print_vla_visitor(type_desc
, item
->u
.side_static
.side_vla_app_visitor_ctx
);
930 case SIDE_TYPE_ARRAY_U8
:
931 case SIDE_TYPE_ARRAY_U16
:
932 case SIDE_TYPE_ARRAY_U32
:
933 case SIDE_TYPE_ARRAY_U64
:
934 case SIDE_TYPE_ARRAY_S8
:
935 case SIDE_TYPE_ARRAY_S16
:
936 case SIDE_TYPE_ARRAY_S32
:
937 case SIDE_TYPE_ARRAY_S64
:
938 case SIDE_TYPE_ARRAY_BYTE
:
939 case SIDE_TYPE_ARRAY_POINTER32
:
940 case SIDE_TYPE_ARRAY_POINTER64
:
941 tracer_print_array_fixint(type_desc
, item
);
943 case SIDE_TYPE_VLA_U8
:
944 case SIDE_TYPE_VLA_U16
:
945 case SIDE_TYPE_VLA_U32
:
946 case SIDE_TYPE_VLA_U64
:
947 case SIDE_TYPE_VLA_S8
:
948 case SIDE_TYPE_VLA_S16
:
949 case SIDE_TYPE_VLA_S32
:
950 case SIDE_TYPE_VLA_S64
:
951 case SIDE_TYPE_VLA_BYTE
:
952 case SIDE_TYPE_VLA_POINTER32
:
953 case SIDE_TYPE_VLA_POINTER64
:
954 tracer_print_vla_fixint(type_desc
, item
);
958 case SIDE_TYPE_DYNAMIC_NULL
:
959 case SIDE_TYPE_DYNAMIC_BOOL
:
960 case SIDE_TYPE_DYNAMIC_U8
:
961 case SIDE_TYPE_DYNAMIC_U16
:
962 case SIDE_TYPE_DYNAMIC_U32
:
963 case SIDE_TYPE_DYNAMIC_U64
:
964 case SIDE_TYPE_DYNAMIC_S8
:
965 case SIDE_TYPE_DYNAMIC_S16
:
966 case SIDE_TYPE_DYNAMIC_S32
:
967 case SIDE_TYPE_DYNAMIC_S64
:
968 case SIDE_TYPE_DYNAMIC_BYTE
:
969 case SIDE_TYPE_DYNAMIC_POINTER32
:
970 case SIDE_TYPE_DYNAMIC_POINTER64
:
971 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY16
:
972 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY32
:
973 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY64
:
974 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY128
:
975 case SIDE_TYPE_DYNAMIC_STRING
:
976 case SIDE_TYPE_DYNAMIC_STRUCT
:
977 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
978 case SIDE_TYPE_DYNAMIC_VLA
:
979 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
980 tracer_print_dynamic(item
);
982 case SIDE_TYPE_GATHER_VLA
:
983 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
986 fprintf(stderr
, "<UNKNOWN TYPE>");
993 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg
*item
)
995 printf("%s: ", item_desc
->field_name
);
996 tracer_print_type(&item_desc
->side_type
, item
);
1000 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1002 const struct side_arg
*sav
= side_arg_vec
->sav
;
1003 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1005 if (type_desc
->u
.side_struct
->nr_fields
!= side_sav_len
) {
1006 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
1009 print_attributes("attr", ":", type_desc
->u
.side_struct
->attr
, type_desc
->u
.side_struct
->nr_attr
);
1010 printf("%s", type_desc
->u
.side_struct
->nr_attr
? ", " : "");
1011 printf("fields: { ");
1012 for (i
= 0; i
< side_sav_len
; i
++) {
1013 printf("%s", i
? ", " : "");
1014 tracer_print_field(&type_desc
->u
.side_struct
->fields
[i
], &sav
[i
]);
1020 void tracer_print_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1022 const struct side_arg
*sav
= side_arg_vec
->sav
;
1023 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1025 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
1026 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
1029 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1030 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1031 printf("elements: ");
1033 for (i
= 0; i
< side_sav_len
; i
++) {
1034 printf("%s", i
? ", " : "");
1035 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
1041 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1043 const struct side_arg
*sav
= side_arg_vec
->sav
;
1044 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1046 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1047 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1048 printf("elements: ");
1050 for (i
= 0; i
< side_sav_len
; i
++) {
1051 printf("%s", i
? ", " : "");
1052 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
1058 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode
, const char *ptr
)
1060 switch (access_mode
) {
1061 case SIDE_TYPE_GATHER_ACCESS_ADDRESS
:
1063 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1064 /* Dereference pointer */
1065 memcpy(&ptr
, ptr
, sizeof(ptr
));
1073 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode
, uint32_t len
)
1075 switch (access_mode
) {
1076 case SIDE_TYPE_GATHER_ACCESS_ADDRESS
:
1078 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1079 return sizeof(void *);
1086 uint64_t tracer_load_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1088 enum side_type_gather_access_mode access_mode
= type_gather
->u
.side_integer
.access_mode
;
1089 uint32_t integer_size_bytes
= type_gather
->u
.side_integer
.type
.integer_size_bits
>> 3;
1090 const char *ptr
= (const char *) _ptr
;
1091 union side_integer_value value
;
1093 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_integer
.offset
);
1094 memcpy(&value
, ptr
, integer_size_bytes
);
1095 switch (type_gather
->u
.side_integer
.type
.integer_size_bits
) {
1097 return (uint64_t) value
.side_u8
;
1099 return (uint64_t) value
.side_u16
;
1101 return (uint64_t) value
.side_u32
;
1103 return (uint64_t) value
.side_u64
;
1110 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1112 enum side_type_gather_access_mode access_mode
= type_gather
->u
.side_integer
.access_mode
;
1113 uint32_t integer_size_bytes
= type_gather
->u
.side_integer
.type
.integer_size_bits
>> 3;
1114 const char *ptr
= (const char *) _ptr
;
1115 union side_integer_value value
;
1117 switch (type_gather
->u
.side_integer
.type
.integer_size_bits
) {
1126 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_integer
.offset
);
1127 memcpy(&value
, ptr
, integer_size_bytes
);
1128 tracer_print_type_integer(":", &type_gather
->u
.side_integer
.type
, &value
,
1129 type_gather
->u
.side_integer
.offset_bits
, TRACER_DISPLAY_BASE_10
);
1130 return tracer_gather_size(access_mode
, integer_size_bytes
);
1134 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1136 enum side_type_gather_access_mode access_mode
= type_gather
->u
.side_float
.access_mode
;
1137 uint32_t float_size_bytes
= type_gather
->u
.side_float
.type
.float_size_bits
>> 3;
1138 const char *ptr
= (const char *) _ptr
;
1139 union side_float_value value
;
1141 switch (type_gather
->u
.side_float
.type
.float_size_bits
) {
1150 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_float
.offset
);
1151 memcpy(&value
, ptr
, float_size_bytes
);
1152 tracer_print_type_float(":", &type_gather
->u
.side_float
.type
, &value
);
1153 return tracer_gather_size(access_mode
, float_size_bytes
);
1157 uint32_t tracer_print_gather_type(const struct side_type
*type_desc
, const void *ptr
)
1162 switch (type_desc
->type
) {
1163 case SIDE_TYPE_GATHER_UNSIGNED_INT
:
1164 case SIDE_TYPE_GATHER_SIGNED_INT
:
1165 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
);
1167 case SIDE_TYPE_GATHER_FLOAT
:
1168 len
= tracer_print_gather_float_type(&type_desc
->u
.side_gather
, ptr
);
1170 case SIDE_TYPE_GATHER_STRUCT
:
1171 len
= tracer_print_gather_struct(&type_desc
->u
.side_gather
, ptr
);
1173 case SIDE_TYPE_GATHER_ARRAY
:
1174 len
= tracer_print_gather_array(&type_desc
->u
.side_gather
, ptr
);
1176 case SIDE_TYPE_GATHER_VLA
:
1177 len
= tracer_print_gather_vla(&type_desc
->u
.side_gather
, ptr
);
1180 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
1188 void tracer_print_gather_field(const struct side_event_field
*field
, const void *ptr
)
1190 printf("%s: ", field
->field_name
);
1191 (void) tracer_print_gather_type(&field
->side_type
, ptr
);
1195 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
)
1197 enum side_type_gather_access_mode access_mode
= type_gather
->u
.side_struct
.access_mode
;
1198 const char *ptr
= (const char *) _ptr
;
1201 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_struct
.offset
);
1202 print_attributes("attr", ":", type_gather
->u
.side_struct
.type
->attr
, type_gather
->u
.side_struct
.type
->nr_attr
);
1203 printf("%s", type_gather
->u
.side_struct
.type
->nr_attr
? ", " : "");
1204 printf("fields: { ");
1205 for (i
= 0; i
< type_gather
->u
.side_struct
.type
->nr_fields
; i
++) {
1206 printf("%s", i
? ", " : "");
1207 tracer_print_gather_field(&type_gather
->u
.side_struct
.type
->fields
[i
], ptr
);
1210 return tracer_gather_size(access_mode
, type_gather
->u
.side_struct
.size
);
1214 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
)
1216 enum side_type_gather_access_mode access_mode
= type_gather
->u
.side_array
.access_mode
;
1217 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1220 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_array
.offset
);
1222 print_attributes("attr", ":", type_gather
->u
.side_array
.type
.attr
, type_gather
->u
.side_array
.type
.nr_attr
);
1223 printf("%s", type_gather
->u
.side_array
.type
.nr_attr
? ", " : "");
1224 printf("elements: ");
1226 for (i
= 0; i
< type_gather
->u
.side_array
.type
.length
; i
++) {
1227 switch (type_gather
->u
.side_array
.type
.elem_type
->type
) {
1228 case SIDE_TYPE_GATHER_VLA
:
1229 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1234 printf("%s", i
? ", " : "");
1235 ptr
+= tracer_print_gather_type(type_gather
->u
.side_array
.type
.elem_type
, ptr
);
1238 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1242 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
)
1244 enum side_type_gather_access_mode access_mode
= type_gather
->u
.side_vla
.access_mode
;
1245 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1249 switch (type_gather
->u
.side_vla
.length_type
->type
) {
1250 case SIDE_TYPE_GATHER_UNSIGNED_INT
:
1251 case SIDE_TYPE_GATHER_SIGNED_INT
:
1254 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
1257 length
= (uint32_t) tracer_load_gather_integer_type(&type_gather
->u
.side_vla
.length_type
->u
.side_gather
, ptr
);
1258 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_vla
.offset
);
1260 print_attributes("attr", ":", type_gather
->u
.side_vla
.type
.attr
, type_gather
->u
.side_vla
.type
.nr_attr
);
1261 printf("%s", type_gather
->u
.side_vla
.type
.nr_attr
? ", " : "");
1262 printf("elements: ");
1264 for (i
= 0; i
< length
; i
++) {
1265 switch (type_gather
->u
.side_vla
.type
.elem_type
->type
) {
1266 case SIDE_TYPE_GATHER_VLA
:
1267 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1272 printf("%s", i
? ", " : "");
1273 ptr
+= tracer_print_gather_type(type_gather
->u
.side_vla
.type
.elem_type
, ptr
);
1276 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1279 struct tracer_visitor_priv
{
1280 const struct side_type
*elem_type
;
1285 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1286 const struct side_arg
*elem
)
1288 struct tracer_visitor_priv
*tracer_priv
= (struct tracer_visitor_priv
*) tracer_ctx
->priv
;
1290 printf("%s", tracer_priv
->i
++ ? ", " : "");
1291 tracer_print_type(tracer_priv
->elem_type
, elem
);
1292 return SIDE_VISITOR_STATUS_OK
;
1296 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
)
1298 enum side_visitor_status status
;
1299 struct tracer_visitor_priv tracer_priv
= {
1300 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
1303 const struct side_tracer_visitor_ctx tracer_ctx
= {
1304 .write_elem
= tracer_write_elem_cb
,
1305 .priv
= &tracer_priv
,
1308 print_attributes("attr", ":", type_desc
->u
.side_vla_visitor
.attr
, type_desc
->u
.side_vla_visitor
.nr_attr
);
1309 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1310 printf("elements: ");
1312 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1314 case SIDE_VISITOR_STATUS_OK
:
1316 case SIDE_VISITOR_STATUS_ERROR
:
1317 fprintf(stderr
, "ERROR: Visitor error\n");
1323 void tracer_print_array_fixint(const struct side_type
*type_desc
, const struct side_arg
*item
)
1325 const struct side_type
*elem_type
= type_desc
->u
.side_array
.elem_type
;
1326 uint32_t i
, side_sav_len
= type_desc
->u
.side_array
.length
;
1327 void *p
= item
->u
.side_static
.side_array_fixint
;
1328 enum side_type_label side_type
;
1330 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1331 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1332 printf("elements: ");
1333 switch (item
->type
) {
1334 case SIDE_TYPE_ARRAY_U8
:
1335 if (elem_type
->type
!= SIDE_TYPE_U8
)
1338 case SIDE_TYPE_ARRAY_U16
:
1339 if (elem_type
->type
!= SIDE_TYPE_U16
)
1342 case SIDE_TYPE_ARRAY_U32
:
1343 if (elem_type
->type
!= SIDE_TYPE_U32
)
1346 case SIDE_TYPE_ARRAY_U64
:
1347 if (elem_type
->type
!= SIDE_TYPE_U64
)
1350 case SIDE_TYPE_ARRAY_S8
:
1351 if (elem_type
->type
!= SIDE_TYPE_S8
)
1354 case SIDE_TYPE_ARRAY_S16
:
1355 if (elem_type
->type
!= SIDE_TYPE_S16
)
1358 case SIDE_TYPE_ARRAY_S32
:
1359 if (elem_type
->type
!= SIDE_TYPE_S32
)
1362 case SIDE_TYPE_ARRAY_S64
:
1363 if (elem_type
->type
!= SIDE_TYPE_S64
)
1366 case SIDE_TYPE_ARRAY_BYTE
:
1367 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1370 case SIDE_TYPE_ARRAY_POINTER32
:
1371 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1373 case SIDE_TYPE_ARRAY_POINTER64
:
1374 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1380 side_type
= (enum side_type_label
) elem_type
->type
;
1383 for (i
= 0; i
< side_sav_len
; i
++) {
1384 struct side_arg sav_elem
= {
1388 switch (side_type
) {
1390 sav_elem
.u
.side_static
.integer_value
.side_u8
= ((const uint8_t *) p
)[i
];
1393 sav_elem
.u
.side_static
.integer_value
.side_s8
= ((const int8_t *) p
)[i
];
1396 sav_elem
.u
.side_static
.integer_value
.side_u16
= ((const uint16_t *) p
)[i
];
1399 sav_elem
.u
.side_static
.integer_value
.side_s16
= ((const int16_t *) p
)[i
];
1402 sav_elem
.u
.side_static
.integer_value
.side_u32
= ((const uint32_t *) p
)[i
];
1405 sav_elem
.u
.side_static
.integer_value
.side_s32
= ((const int32_t *) p
)[i
];
1408 sav_elem
.u
.side_static
.integer_value
.side_u64
= ((const uint64_t *) p
)[i
];
1411 sav_elem
.u
.side_static
.integer_value
.side_s64
= ((const int64_t *) p
)[i
];
1413 case SIDE_TYPE_BYTE
:
1414 sav_elem
.u
.side_static
.byte_value
= ((const uint8_t *) p
)[i
];
1416 case SIDE_TYPE_POINTER32
:
1417 sav_elem
.u
.side_static
.integer_value
.side_u32
= ((const uint32_t *) p
)[i
];
1419 case SIDE_TYPE_POINTER64
:
1420 sav_elem
.u
.side_static
.integer_value
.side_u64
= ((const uint64_t *) p
)[i
];
1424 fprintf(stderr
, "ERROR: Unexpected type\n");
1428 printf("%s", i
? ", " : "");
1429 tracer_print_type(elem_type
, &sav_elem
);
1435 fprintf(stderr
, "ERROR: type mismatch\n");
1439 void tracer_print_vla_fixint(const struct side_type
*type_desc
, const struct side_arg
*item
)
1441 const struct side_type
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
1442 uint32_t i
, side_sav_len
= item
->u
.side_static
.side_vla_fixint
.length
;
1443 void *p
= item
->u
.side_static
.side_vla_fixint
.p
;
1444 enum side_type_label side_type
;
1446 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1447 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1448 printf("elements: ");
1449 switch (item
->type
) {
1450 case SIDE_TYPE_VLA_U8
:
1451 if (elem_type
->type
!= SIDE_TYPE_U8
)
1454 case SIDE_TYPE_VLA_U16
:
1455 if (elem_type
->type
!= SIDE_TYPE_U16
)
1458 case SIDE_TYPE_VLA_U32
:
1459 if (elem_type
->type
!= SIDE_TYPE_U32
)
1462 case SIDE_TYPE_VLA_U64
:
1463 if (elem_type
->type
!= SIDE_TYPE_U64
)
1466 case SIDE_TYPE_VLA_S8
:
1467 if (elem_type
->type
!= SIDE_TYPE_S8
)
1470 case SIDE_TYPE_VLA_S16
:
1471 if (elem_type
->type
!= SIDE_TYPE_S16
)
1474 case SIDE_TYPE_VLA_S32
:
1475 if (elem_type
->type
!= SIDE_TYPE_S32
)
1478 case SIDE_TYPE_VLA_S64
:
1479 if (elem_type
->type
!= SIDE_TYPE_S64
)
1482 case SIDE_TYPE_VLA_BYTE
:
1483 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1486 case SIDE_TYPE_VLA_POINTER32
:
1487 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1489 case SIDE_TYPE_VLA_POINTER64
:
1490 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1496 side_type
= (enum side_type_label
) elem_type
->type
;
1499 for (i
= 0; i
< side_sav_len
; i
++) {
1500 struct side_arg sav_elem
= {
1504 switch (side_type
) {
1506 sav_elem
.u
.side_static
.integer_value
.side_u8
= ((const uint8_t *) p
)[i
];
1509 sav_elem
.u
.side_static
.integer_value
.side_s8
= ((const int8_t *) p
)[i
];
1512 sav_elem
.u
.side_static
.integer_value
.side_u16
= ((const uint16_t *) p
)[i
];
1515 sav_elem
.u
.side_static
.integer_value
.side_s16
= ((const int16_t *) p
)[i
];
1518 sav_elem
.u
.side_static
.integer_value
.side_u32
= ((const uint32_t *) p
)[i
];
1521 sav_elem
.u
.side_static
.integer_value
.side_s32
= ((const int32_t *) p
)[i
];
1524 sav_elem
.u
.side_static
.integer_value
.side_u64
= ((const uint64_t *) p
)[i
];
1527 sav_elem
.u
.side_static
.integer_value
.side_s64
= ((const int64_t *) p
)[i
];
1529 case SIDE_TYPE_BYTE
:
1530 sav_elem
.u
.side_static
.byte_value
= ((const uint8_t *) p
)[i
];
1532 case SIDE_TYPE_POINTER32
:
1533 sav_elem
.u
.side_static
.integer_value
.side_u32
= ((const uint32_t *) p
)[i
];
1535 case SIDE_TYPE_POINTER64
:
1536 sav_elem
.u
.side_static
.integer_value
.side_u64
= ((const uint64_t *) p
)[i
];
1540 fprintf(stderr
, "ERROR: Unexpected type\n");
1544 printf("%s", i
? ", " : "");
1545 tracer_print_type(elem_type
, &sav_elem
);
1551 fprintf(stderr
, "ERROR: type mismatch\n");
1556 void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
)
1558 const struct side_arg_dynamic_field
*fields
= dynamic_struct
->fields
;
1559 uint32_t i
, len
= dynamic_struct
->len
;
1561 print_attributes("attr", "::", dynamic_struct
->attr
, dynamic_struct
->nr_attr
);
1562 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1563 printf("fields:: ");
1565 for (i
= 0; i
< len
; i
++) {
1566 printf("%s", i
? ", " : "");
1567 printf("%s:: ", fields
[i
].field_name
);
1568 tracer_print_dynamic(&fields
[i
].elem
);
1573 struct tracer_dynamic_struct_visitor_priv
{
1578 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1579 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1580 const struct side_arg_dynamic_field
*dynamic_field
)
1582 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
=
1583 (struct tracer_dynamic_struct_visitor_priv
*) tracer_ctx
->priv
;
1585 printf("%s", tracer_priv
->i
++ ? ", " : "");
1586 printf("%s:: ", dynamic_field
->field_name
);
1587 tracer_print_dynamic(&dynamic_field
->elem
);
1588 return SIDE_VISITOR_STATUS_OK
;
1592 void tracer_print_dynamic_struct_visitor(const struct side_arg
*item
)
1594 enum side_visitor_status status
;
1595 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1598 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1599 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1600 .priv
= &tracer_priv
,
1602 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.app_ctx
;
1604 print_attributes("attr", "::", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.attr
, item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
);
1605 printf("%s", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1606 printf("fields:: ");
1608 status
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1610 case SIDE_VISITOR_STATUS_OK
:
1612 case SIDE_VISITOR_STATUS_ERROR
:
1613 fprintf(stderr
, "ERROR: Visitor error\n");
1620 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla
*vla
)
1622 const struct side_arg
*sav
= vla
->sav
;
1623 uint32_t i
, side_sav_len
= vla
->len
;
1625 print_attributes("attr", "::", vla
->attr
, vla
->nr_attr
);
1626 printf("%s", vla
->nr_attr
? ", " : "");
1627 printf("elements:: ");
1629 for (i
= 0; i
< side_sav_len
; i
++) {
1630 printf("%s", i
? ", " : "");
1631 tracer_print_dynamic(&sav
[i
]);
1636 struct tracer_dynamic_vla_visitor_priv
{
1641 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1642 const struct side_tracer_visitor_ctx
*tracer_ctx
,
1643 const struct side_arg
*elem
)
1645 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
=
1646 (struct tracer_dynamic_vla_visitor_priv
*) tracer_ctx
->priv
;
1648 printf("%s", tracer_priv
->i
++ ? ", " : "");
1649 tracer_print_dynamic(elem
);
1650 return SIDE_VISITOR_STATUS_OK
;
1654 void tracer_print_dynamic_vla_visitor(const struct side_arg
*item
)
1656 enum side_visitor_status status
;
1657 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1660 const struct side_tracer_visitor_ctx tracer_ctx
= {
1661 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1662 .priv
= &tracer_priv
,
1664 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.app_ctx
;
1666 print_attributes("attr", "::", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.attr
, item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
);
1667 printf("%s", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1668 printf("elements:: ");
1670 status
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1672 case SIDE_VISITOR_STATUS_OK
:
1674 case SIDE_VISITOR_STATUS_ERROR
:
1675 fprintf(stderr
, "ERROR: Visitor error\n");
1682 void tracer_print_dynamic(const struct side_arg
*item
)
1685 switch (item
->type
) {
1686 case SIDE_TYPE_DYNAMIC_NULL
:
1687 tracer_print_type_header("::", item
->u
.side_dynamic
.side_null
.attr
, item
->u
.side_dynamic
.side_null
.nr_attr
);
1688 printf("<NULL TYPE>");
1690 case SIDE_TYPE_DYNAMIC_BOOL
:
1691 tracer_print_type_header("::", item
->u
.side_dynamic
.side_bool
.type
.attr
, item
->u
.side_dynamic
.side_bool
.type
.nr_attr
);
1692 printf("%s", item
->u
.side_dynamic
.side_bool
.value
? "true" : "false");
1694 case SIDE_TYPE_DYNAMIC_U8
:
1695 case SIDE_TYPE_DYNAMIC_U16
:
1696 case SIDE_TYPE_DYNAMIC_U32
:
1697 case SIDE_TYPE_DYNAMIC_U64
:
1698 case SIDE_TYPE_DYNAMIC_S8
:
1699 case SIDE_TYPE_DYNAMIC_S16
:
1700 case SIDE_TYPE_DYNAMIC_S32
:
1701 case SIDE_TYPE_DYNAMIC_S64
:
1702 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1703 TRACER_DISPLAY_BASE_10
);
1705 case SIDE_TYPE_DYNAMIC_BYTE
:
1706 tracer_print_type_header("::", item
->u
.side_dynamic
.side_byte
.type
.attr
, item
->u
.side_dynamic
.side_byte
.type
.nr_attr
);
1707 printf("0x%" PRIx8
, item
->u
.side_dynamic
.side_byte
.value
);
1710 case SIDE_TYPE_DYNAMIC_POINTER32
:
1711 case SIDE_TYPE_DYNAMIC_POINTER64
:
1712 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1713 TRACER_DISPLAY_BASE_16
);
1716 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY16
:
1717 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY32
:
1718 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY64
:
1719 case SIDE_TYPE_DYNAMIC_FLOAT_BINARY128
:
1720 tracer_print_type_float("::", &item
->u
.side_dynamic
.side_float
.type
,
1721 &item
->u
.side_dynamic
.side_float
.value
);
1724 case SIDE_TYPE_DYNAMIC_STRING
:
1725 tracer_print_type_header("::", item
->u
.side_dynamic
.side_string
.type
.attr
, item
->u
.side_dynamic
.side_string
.type
.nr_attr
);
1726 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.side_dynamic
.side_string
.value
);
1728 case SIDE_TYPE_DYNAMIC_STRUCT
:
1729 tracer_print_dynamic_struct(item
->u
.side_dynamic
.side_dynamic_struct
);
1731 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1732 tracer_print_dynamic_struct_visitor(item
);
1734 case SIDE_TYPE_DYNAMIC_VLA
:
1735 tracer_print_dynamic_vla(item
->u
.side_dynamic
.side_dynamic_vla
);
1737 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1738 tracer_print_dynamic_vla_visitor(item
);
1741 fprintf(stderr
, "<UNKNOWN TYPE>");
1748 void tracer_print_static_fields(const struct side_event_description
*desc
,
1749 const struct side_arg_vec
*side_arg_vec
,
1752 const struct side_arg
*sav
= side_arg_vec
->sav
;
1753 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1755 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
1756 if (desc
->nr_fields
!= side_sav_len
) {
1757 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1760 print_attributes(", attr", ":", desc
->attr
, desc
->nr_attr
);
1761 printf("%s", side_sav_len
? ", fields: [ " : "");
1762 for (i
= 0; i
< side_sav_len
; i
++) {
1763 printf("%s", i
? ", " : "");
1764 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
1772 void tracer_call(const struct side_event_description
*desc
,
1773 const struct side_arg_vec
*side_arg_vec
,
1774 void *priv
__attribute__((unused
)))
1776 uint32_t nr_fields
= 0;
1778 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1782 void tracer_call_variadic(const struct side_event_description
*desc
,
1783 const struct side_arg_vec
*side_arg_vec
,
1784 const struct side_arg_dynamic_struct
*var_struct
,
1785 void *priv
__attribute__((unused
)))
1787 uint32_t nr_fields
= 0, i
, var_struct_len
= var_struct
->len
;
1789 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1791 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1792 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1795 print_attributes(", attr ", "::", var_struct
->attr
, var_struct
->nr_attr
);
1796 printf("%s", var_struct_len
? ", fields:: [ " : "");
1797 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1798 printf("%s", i
? ", " : "");
1799 printf("%s:: ", var_struct
->fields
[i
].field_name
);
1800 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
1807 void tracer_event_notification(enum side_tracer_notification notif
,
1808 struct side_event_description
**events
, uint32_t nr_events
, void *priv
)
1813 printf("----------------------------------------------------------\n");
1814 printf("Tracer notified of events %s\n",
1815 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1816 for (i
= 0; i
< nr_events
; i
++) {
1817 struct side_event_description
*event
= events
[i
];
1819 /* Skip NULL pointers */
1822 printf("provider: %s, event: %s\n",
1823 event
->provider_name
, event
->event_name
);
1824 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1825 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1826 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1830 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1835 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1836 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1840 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1846 printf("----------------------------------------------------------\n");
1849 static __attribute__((constructor
))
1850 void tracer_init(void);
1852 void tracer_init(void)
1854 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1859 static __attribute__((destructor
))
1860 void tracer_exit(void);
1862 void tracer_exit(void)
1864 side_tracer_event_notification_unregister(tracer_handle
);