1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
14 #include <side/trace.h>
16 enum tracer_display_base
{
17 TRACER_DISPLAY_BASE_2
,
18 TRACER_DISPLAY_BASE_8
,
19 TRACER_DISPLAY_BASE_10
,
20 TRACER_DISPLAY_BASE_16
,
28 static struct side_tracer_handle
*tracer_handle
;
31 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
33 void tracer_print_variant(const struct side_type
*type_desc
, const struct side_arg_variant
*side_arg_variant
);
35 void tracer_print_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
37 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
39 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
);
41 void tracer_print_dynamic(const struct side_arg
*dynamic_item
);
43 uint32_t tracer_print_gather_bool_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
45 uint32_t tracer_print_gather_byte_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
47 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
,
48 enum tracer_display_base default_base
);
50 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
52 uint32_t tracer_print_gather_string_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
54 uint32_t tracer_print_gather_enum_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
56 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
);
58 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
);
60 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
,
61 const void *_length_ptr
);
63 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
);
66 void tracer_convert_string_to_utf8(const void *p
, uint8_t unit_size
, enum side_type_label_byte_order byte_order
,
67 size_t *strlen_with_null
,
70 size_t ret
, inbytesleft
= 0, outbytesleft
, bufsize
;
71 const char *str
= p
, *fromcode
;
72 char *inbuf
= (char *) p
, *outbuf
, *buf
;
78 *strlen_with_null
= strlen(str
) + 1;
79 *output_str
= (char *) str
;
83 const uint16_t *p16
= p
;
86 case SIDE_TYPE_BYTE_ORDER_LE
:
88 fromcode
= "UTF-16LE";
91 case SIDE_TYPE_BYTE_ORDER_BE
:
93 fromcode
= "UTF-16BE";
97 fprintf(stderr
, "Unknown byte order\n");
103 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
104 * { ef, bf, bf } UTF-8 (3 bytes).
106 bufsize
= inbytesleft
/ 2 * 3 + 1;
111 const uint32_t *p32
= p
;
113 switch (byte_order
) {
114 case SIDE_TYPE_BYTE_ORDER_LE
:
116 fromcode
= "UTF-32LE";
119 case SIDE_TYPE_BYTE_ORDER_BE
:
121 fromcode
= "UTF-32BE";
125 fprintf(stderr
, "Unknown byte order\n");
131 * Each 4-byte UTF-32 character converts to at most a
132 * 4-byte UTF-8 character.
134 bufsize
= inbytesleft
+ 1;
138 fprintf(stderr
, "Unknown string unit size %" PRIu8
"\n", unit_size
);
142 cd
= iconv_open("UTF8", fromcode
);
143 if (cd
== (iconv_t
) -1) {
144 perror("iconv_open");
147 buf
= malloc(bufsize
);
151 outbuf
= (char *) buf
;
152 outbytesleft
= bufsize
;
153 ret
= iconv(cd
, &inbuf
, &inbytesleft
, &outbuf
, &outbytesleft
);
154 if (ret
== (size_t) -1) {
159 fprintf(stderr
, "Buffer too small to convert string input\n");
163 if (iconv_close(cd
) == -1) {
164 perror("iconv_close");
167 if (strlen_with_null
)
168 *strlen_with_null
= outbuf
- buf
;
173 void tracer_print_string(const void *p
, uint8_t unit_size
, enum side_type_label_byte_order byte_order
,
174 size_t *strlen_with_null
)
176 char *output_str
= NULL
;
178 tracer_convert_string_to_utf8(p
, unit_size
, byte_order
, strlen_with_null
, &output_str
);
179 printf("\"%s\"", output_str
);
185 int64_t get_attr_integer_value(const struct side_attr
*attr
)
189 switch (attr
->value
.type
) {
190 case SIDE_ATTR_TYPE_U8
:
191 val
= attr
->value
.u
.integer_value
.side_u8
;
193 case SIDE_ATTR_TYPE_U16
:
194 val
= attr
->value
.u
.integer_value
.side_u16
;
196 case SIDE_ATTR_TYPE_U32
:
197 val
= attr
->value
.u
.integer_value
.side_u32
;
199 case SIDE_ATTR_TYPE_U64
:
200 val
= attr
->value
.u
.integer_value
.side_u64
;
202 case SIDE_ATTR_TYPE_S8
:
203 val
= attr
->value
.u
.integer_value
.side_s8
;
205 case SIDE_ATTR_TYPE_S16
:
206 val
= attr
->value
.u
.integer_value
.side_s16
;
208 case SIDE_ATTR_TYPE_S32
:
209 val
= attr
->value
.u
.integer_value
.side_s32
;
211 case SIDE_ATTR_TYPE_S64
:
212 val
= attr
->value
.u
.integer_value
.side_s64
;
215 fprintf(stderr
, "Unexpected attribute type\n");
222 enum tracer_display_base
get_attr_display_base(const struct side_attr
*_attr
, uint32_t nr_attr
,
223 enum tracer_display_base default_base
)
227 for (i
= 0; i
< nr_attr
; i
++) {
228 const struct side_attr
*attr
= &_attr
[i
];
229 char *utf8_str
= NULL
;
232 tracer_convert_string_to_utf8(side_ptr_get(attr
->key
.p
), attr
->key
.unit_size
,
233 attr
->key
.byte_order
, NULL
, &utf8_str
);
234 cmp
= strcmp(utf8_str
, "std.integer.base");
235 if (utf8_str
!= side_ptr_get(attr
->key
.p
))
238 int64_t val
= get_attr_integer_value(attr
);
242 return TRACER_DISPLAY_BASE_2
;
244 return TRACER_DISPLAY_BASE_8
;
246 return TRACER_DISPLAY_BASE_10
;
248 return TRACER_DISPLAY_BASE_16
;
250 fprintf(stderr
, "Unexpected integer display base: %" PRId64
"\n", val
);
255 return default_base
; /* Default */
259 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
261 char *utf8_str
= NULL
;
263 tracer_convert_string_to_utf8(side_ptr_get(attr
->key
.p
), attr
->key
.unit_size
,
264 attr
->key
.byte_order
, NULL
, &utf8_str
);
265 printf("{ key%s \"%s\", value%s ", separator
, utf8_str
, separator
);
266 if (utf8_str
!= side_ptr_get(attr
->key
.p
))
268 switch (attr
->value
.type
) {
269 case SIDE_ATTR_TYPE_BOOL
:
270 printf("%s", attr
->value
.u
.bool_value
? "true" : "false");
272 case SIDE_ATTR_TYPE_U8
:
273 printf("%" PRIu8
, attr
->value
.u
.integer_value
.side_u8
);
275 case SIDE_ATTR_TYPE_U16
:
276 printf("%" PRIu16
, attr
->value
.u
.integer_value
.side_u16
);
278 case SIDE_ATTR_TYPE_U32
:
279 printf("%" PRIu32
, attr
->value
.u
.integer_value
.side_u32
);
281 case SIDE_ATTR_TYPE_U64
:
282 printf("%" PRIu64
, attr
->value
.u
.integer_value
.side_u64
);
284 case SIDE_ATTR_TYPE_S8
:
285 printf("%" PRId8
, attr
->value
.u
.integer_value
.side_s8
);
287 case SIDE_ATTR_TYPE_S16
:
288 printf("%" PRId16
, attr
->value
.u
.integer_value
.side_s16
);
290 case SIDE_ATTR_TYPE_S32
:
291 printf("%" PRId32
, attr
->value
.u
.integer_value
.side_s32
);
293 case SIDE_ATTR_TYPE_S64
:
294 printf("%" PRId64
, attr
->value
.u
.integer_value
.side_s64
);
296 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
298 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary16
);
301 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
304 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
306 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary32
);
309 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
312 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
314 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary64
);
317 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
320 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
322 printf("%Lg", (long double) attr
->value
.u
.float_value
.side_float_binary128
);
325 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
328 case SIDE_ATTR_TYPE_STRING
:
329 tracer_print_string(side_ptr_get(attr
->value
.u
.string_value
.p
),
330 attr
->value
.u
.string_value
.unit_size
,
331 attr
->value
.u
.string_value
.byte_order
, NULL
);
334 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
341 void print_attributes(const char *prefix_str
, const char *separator
,
342 const struct side_attr
*attr
, uint32_t nr_attr
)
348 printf("%s%s [ ", prefix_str
, separator
);
349 for (i
= 0; i
< nr_attr
; i
++) {
350 printf("%s", i
? ", " : "");
351 tracer_print_attr_type(separator
, &attr
[i
]);
357 union int64_value
tracer_load_integer_value(const struct side_type_integer
*type_integer
,
358 const union side_integer_value
*value
,
359 uint16_t offset_bits
, uint16_t *_len_bits
)
361 union int64_value v64
;
365 if (!type_integer
->len_bits
)
366 len_bits
= type_integer
->integer_size
* CHAR_BIT
;
368 len_bits
= type_integer
->len_bits
;
369 if (len_bits
+ offset_bits
> type_integer
->integer_size
* CHAR_BIT
)
371 reverse_bo
= type_integer
->byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
;
372 switch (type_integer
->integer_size
) {
374 if (type_integer
->signedness
)
375 v64
.s
= value
->side_s8
;
377 v64
.u
= value
->side_u8
;
380 if (type_integer
->signedness
) {
383 side_s16
= value
->side_s16
;
385 side_s16
= side_bswap_16(side_s16
);
390 side_u16
= value
->side_u16
;
392 side_u16
= side_bswap_16(side_u16
);
397 if (type_integer
->signedness
) {
400 side_s32
= value
->side_s32
;
402 side_s32
= side_bswap_32(side_s32
);
407 side_u32
= value
->side_u32
;
409 side_u32
= side_bswap_32(side_u32
);
414 if (type_integer
->signedness
) {
417 side_s64
= value
->side_s64
;
419 side_s64
= side_bswap_64(side_s64
);
424 side_u64
= value
->side_u64
;
426 side_u64
= side_bswap_64(side_u64
);
433 v64
.u
>>= offset_bits
;
435 v64
.u
&= (1ULL << len_bits
) - 1;
436 if (type_integer
->signedness
) {
438 if (v64
.u
& (1ULL << (len_bits
- 1)))
439 v64
.u
|= ~((1ULL << len_bits
) - 1);
443 *_len_bits
= len_bits
;
448 void print_enum_labels(const struct side_enum_mappings
*mappings
, union int64_value v64
)
450 uint32_t i
, print_count
= 0;
452 printf(", labels: [ ");
453 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
454 const struct side_enum_mapping
*mapping
= &mappings
->mappings
[i
];
456 if (mapping
->range_end
< mapping
->range_begin
) {
457 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
458 mapping
->range_begin
, mapping
->range_end
);
461 if (v64
.s
>= mapping
->range_begin
&& v64
.s
<= mapping
->range_end
) {
462 printf("%s", print_count
++ ? ", " : "");
463 tracer_print_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
, mapping
->label
.byte_order
, NULL
);
467 printf("<NO LABEL>");
472 void tracer_print_enum(const struct side_type
*type_desc
, const struct side_arg
*item
)
474 const struct side_enum_mappings
*mappings
= type_desc
->u
.side_enum
.mappings
;
475 const struct side_type
*elem_type
= type_desc
->u
.side_enum
.elem_type
;
476 union int64_value v64
;
478 if (elem_type
->type
!= item
->type
) {
479 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
482 v64
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
483 &item
->u
.side_static
.integer_value
, 0, NULL
);
484 print_attributes("attr", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
485 printf("%s", mappings
->nr_attr
? ", " : "");
486 tracer_print_type(elem_type
, item
);
487 print_enum_labels(mappings
, v64
);
491 uint32_t elem_type_to_stride(const struct side_type
*elem_type
)
495 switch (elem_type
->type
) {
508 return elem_type
->u
.side_integer
.integer_size
* CHAR_BIT
;
510 fprintf(stderr
, "ERROR: Unexpected enum bitmap element type\n");
517 void tracer_print_enum_bitmap(const struct side_type
*type_desc
,
518 const struct side_arg
*item
)
520 const struct side_enum_bitmap_mappings
*side_enum_mappings
= type_desc
->u
.side_enum_bitmap
.mappings
;
521 const struct side_type
*enum_elem_type
= type_desc
->u
.side_enum_bitmap
.elem_type
, *elem_type
;
522 uint32_t i
, print_count
= 0, stride_bit
, nr_items
;
523 const struct side_arg
*array_item
;
525 switch (enum_elem_type
->type
) {
526 case SIDE_TYPE_U8
: /* Fall-through */
527 case SIDE_TYPE_BYTE
: /* Fall-through */
528 case SIDE_TYPE_U16
: /* Fall-through */
529 case SIDE_TYPE_U32
: /* Fall-through */
530 case SIDE_TYPE_U64
: /* Fall-through */
531 case SIDE_TYPE_S8
: /* Fall-through */
532 case SIDE_TYPE_S16
: /* Fall-through */
533 case SIDE_TYPE_S32
: /* Fall-through */
535 elem_type
= enum_elem_type
;
539 case SIDE_TYPE_ARRAY
:
540 elem_type
= enum_elem_type
->u
.side_array
.elem_type
;
541 array_item
= item
->u
.side_static
.side_array
->sav
;
542 nr_items
= type_desc
->u
.side_array
.length
;
545 elem_type
= enum_elem_type
->u
.side_vla
.elem_type
;
546 array_item
= item
->u
.side_static
.side_vla
->sav
;
547 nr_items
= item
->u
.side_static
.side_vla
->len
;
550 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
553 stride_bit
= elem_type_to_stride(elem_type
);
555 print_attributes("attr", ":", side_ptr_get(side_enum_mappings
->attr
), side_enum_mappings
->nr_attr
);
556 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
557 printf("labels: [ ");
558 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
559 const struct side_enum_bitmap_mapping
*mapping
= &side_enum_mappings
->mappings
[i
];
563 if (mapping
->range_end
< mapping
->range_begin
) {
564 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
565 mapping
->range_begin
, mapping
->range_end
);
568 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
569 if (bit
> (nr_items
* stride_bit
) - 1)
571 if (elem_type
->type
== SIDE_TYPE_BYTE
) {
572 uint8_t v
= array_item
[bit
/ 8].u
.side_static
.byte_value
;
573 if (v
& (1ULL << (bit
% 8))) {
578 union int64_value v64
;
580 v64
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
581 &array_item
[bit
/ stride_bit
].u
.side_static
.integer_value
,
583 if (v64
.u
& (1ULL << (bit
% stride_bit
))) {
591 printf("%s", print_count
++ ? ", " : "");
592 tracer_print_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
, mapping
->label
.byte_order
, NULL
);
596 printf("<NO LABEL>");
601 void print_integer_binary(uint64_t v
, int bits
)
607 for (i
= 0; i
< bits
; i
++) {
608 printf("%c", v
& (1ULL << 63) ? '1' : '0');
614 void tracer_print_type_header(const char *separator
,
615 const struct side_attr
*attr
, uint32_t nr_attr
)
617 print_attributes("attr", separator
, attr
, nr_attr
);
618 printf("%s", nr_attr
? ", " : "");
619 printf("value%s ", separator
);
623 void tracer_print_type_bool(const char *separator
,
624 const struct side_type_bool
*type_bool
,
625 const union side_bool_value
*value
,
626 uint16_t offset_bits
)
632 if (!type_bool
->len_bits
)
633 len_bits
= type_bool
->bool_size
* CHAR_BIT
;
635 len_bits
= type_bool
->len_bits
;
636 if (len_bits
+ offset_bits
> type_bool
->bool_size
* CHAR_BIT
)
638 reverse_bo
= type_bool
->byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
;
639 switch (type_bool
->bool_size
) {
641 v
= value
->side_bool8
;
647 side_u16
= value
->side_bool16
;
649 side_u16
= side_bswap_16(side_u16
);
657 side_u32
= value
->side_bool32
;
659 side_u32
= side_bswap_32(side_u32
);
667 side_u64
= value
->side_bool64
;
669 side_u64
= side_bswap_64(side_u64
);
678 v
&= (1ULL << len_bits
) - 1;
679 tracer_print_type_header(separator
, side_ptr_get(type_bool
->attr
), type_bool
->nr_attr
);
680 printf("%s", v
? "true" : "false");
684 void tracer_print_type_integer(const char *separator
,
685 const struct side_type_integer
*type_integer
,
686 const union side_integer_value
*value
,
687 uint16_t offset_bits
,
688 enum tracer_display_base default_base
)
690 enum tracer_display_base base
;
691 union int64_value v64
;
694 v64
= tracer_load_integer_value(type_integer
, value
, offset_bits
, &len_bits
);
695 tracer_print_type_header(separator
, side_ptr_get(type_integer
->attr
), type_integer
->nr_attr
);
696 base
= get_attr_display_base(side_ptr_get(type_integer
->attr
), type_integer
->nr_attr
, default_base
);
698 case TRACER_DISPLAY_BASE_2
:
699 print_integer_binary(v64
.u
, len_bits
);
701 case TRACER_DISPLAY_BASE_8
:
702 /* Clear sign bits beyond len_bits */
704 v64
.u
&= (1ULL << len_bits
) - 1;
705 printf("0%" PRIo64
, v64
.u
);
707 case TRACER_DISPLAY_BASE_10
:
708 if (type_integer
->signedness
)
709 printf("%" PRId64
, v64
.s
);
711 printf("%" PRIu64
, v64
.u
);
713 case TRACER_DISPLAY_BASE_16
:
714 /* Clear sign bits beyond len_bits */
716 v64
.u
&= (1ULL << len_bits
) - 1;
717 printf("0x%" PRIx64
, v64
.u
);
725 void tracer_print_type_float(const char *separator
,
726 const struct side_type_float
*type_float
,
727 const union side_float_value
*value
)
731 tracer_print_type_header(separator
, side_ptr_get(type_float
->attr
), type_float
->nr_attr
);
732 reverse_bo
= type_float
->byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
;
733 switch (type_float
->float_size
) {
741 .f
= value
->side_float_binary16
,
745 float16
.u
= side_bswap_16(float16
.u
);
746 printf("%g", (double) float16
.f
);
749 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
760 .f
= value
->side_float_binary32
,
764 float32
.u
= side_bswap_32(float32
.u
);
765 printf("%g", (double) float32
.f
);
768 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
779 .f
= value
->side_float_binary64
,
783 float64
.u
= side_bswap_64(float64
.u
);
784 printf("%g", (double) float64
.f
);
787 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
798 .f
= value
->side_float_binary128
,
802 side_bswap_128p(float128
.arr
);
803 printf("%Lg", (long double) float128
.f
);
806 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
811 fprintf(stderr
, "ERROR: Unknown float size\n");
817 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
)
819 enum side_type_label type
;
821 switch (type_desc
->type
) {
823 switch (item
->type
) {
834 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
840 case SIDE_TYPE_ENUM_BITMAP
:
841 switch (item
->type
) {
847 case SIDE_TYPE_ARRAY
:
851 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
857 case SIDE_TYPE_GATHER_ENUM
:
858 switch (item
->type
) {
859 case SIDE_TYPE_GATHER_INTEGER
:
862 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
868 case SIDE_TYPE_DYNAMIC
:
869 switch (item
->type
) {
870 case SIDE_TYPE_DYNAMIC_NULL
:
871 case SIDE_TYPE_DYNAMIC_BOOL
:
872 case SIDE_TYPE_DYNAMIC_INTEGER
:
873 case SIDE_TYPE_DYNAMIC_BYTE
:
874 case SIDE_TYPE_DYNAMIC_POINTER
:
875 case SIDE_TYPE_DYNAMIC_FLOAT
:
876 case SIDE_TYPE_DYNAMIC_STRING
:
877 case SIDE_TYPE_DYNAMIC_STRUCT
:
878 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
879 case SIDE_TYPE_DYNAMIC_VLA
:
880 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
883 fprintf(stderr
, "ERROR: Unexpected dynamic type\n");
890 if (type_desc
->type
!= item
->type
) {
891 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
897 if (type_desc
->type
== SIDE_TYPE_ENUM
|| type_desc
->type
== SIDE_TYPE_ENUM_BITMAP
||
898 type_desc
->type
== SIDE_TYPE_GATHER_ENUM
)
899 type
= (enum side_type_label
) type_desc
->type
;
901 type
= (enum side_type_label
) item
->type
;
905 /* Stack-copy basic types */
907 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_null
.attr
),
908 type_desc
->u
.side_null
.nr_attr
);
909 printf("<NULL TYPE>");
913 tracer_print_type_bool(":", &type_desc
->u
.side_bool
, &item
->u
.side_static
.bool_value
, 0);
924 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
925 TRACER_DISPLAY_BASE_10
);
929 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_byte
.attr
), type_desc
->u
.side_byte
.nr_attr
);
930 printf("0x%" PRIx8
, item
->u
.side_static
.byte_value
);
933 case SIDE_TYPE_POINTER
:
934 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
935 TRACER_DISPLAY_BASE_16
);
938 case SIDE_TYPE_FLOAT_BINARY16
:
939 case SIDE_TYPE_FLOAT_BINARY32
:
940 case SIDE_TYPE_FLOAT_BINARY64
:
941 case SIDE_TYPE_FLOAT_BINARY128
:
942 tracer_print_type_float(":", &type_desc
->u
.side_float
, &item
->u
.side_static
.float_value
);
945 case SIDE_TYPE_STRING_UTF8
:
946 case SIDE_TYPE_STRING_UTF16
:
947 case SIDE_TYPE_STRING_UTF32
:
948 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_string
.attr
), type_desc
->u
.side_string
.nr_attr
);
949 tracer_print_string((const void *)(uintptr_t) item
->u
.side_static
.string_value
,
950 type_desc
->u
.side_string
.unit_size
, type_desc
->u
.side_string
.byte_order
, NULL
);
953 /* Stack-copy compound types */
954 case SIDE_TYPE_STRUCT
:
955 tracer_print_struct(type_desc
, item
->u
.side_static
.side_struct
);
957 case SIDE_TYPE_VARIANT
:
958 tracer_print_variant(type_desc
, item
->u
.side_static
.side_variant
);
960 case SIDE_TYPE_ARRAY
:
961 tracer_print_array(type_desc
, item
->u
.side_static
.side_array
);
964 tracer_print_vla(type_desc
, item
->u
.side_static
.side_vla
);
966 case SIDE_TYPE_VLA_VISITOR
:
967 tracer_print_vla_visitor(type_desc
, item
->u
.side_static
.side_vla_app_visitor_ctx
);
970 /* Stack-copy enumeration types */
972 tracer_print_enum(type_desc
, item
);
974 case SIDE_TYPE_ENUM_BITMAP
:
975 tracer_print_enum_bitmap(type_desc
, item
);
978 /* Gather basic types */
979 case SIDE_TYPE_GATHER_BOOL
:
980 (void) tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_bool_gather_ptr
);
982 case SIDE_TYPE_GATHER_INTEGER
:
983 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
,
984 TRACER_DISPLAY_BASE_10
);
986 case SIDE_TYPE_GATHER_BYTE
:
987 (void) tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_byte_gather_ptr
);
989 case SIDE_TYPE_GATHER_POINTER
:
990 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
,
991 TRACER_DISPLAY_BASE_16
);
993 case SIDE_TYPE_GATHER_FLOAT
:
994 (void) tracer_print_gather_float_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_float_gather_ptr
);
996 case SIDE_TYPE_GATHER_STRING
:
997 (void) tracer_print_gather_string_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_string_gather_ptr
);
1000 /* Gather compound type */
1001 case SIDE_TYPE_GATHER_STRUCT
:
1002 (void) tracer_print_gather_struct(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_struct_gather_ptr
);
1004 case SIDE_TYPE_GATHER_ARRAY
:
1005 (void) tracer_print_gather_array(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_array_gather_ptr
);
1007 case SIDE_TYPE_GATHER_VLA
:
1008 (void) tracer_print_gather_vla(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_vla_gather
.ptr
,
1009 item
->u
.side_static
.side_vla_gather
.length_ptr
);
1012 /* Gather enumeration types */
1013 case SIDE_TYPE_GATHER_ENUM
:
1014 (void) tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
);
1017 /* Dynamic basic types */
1018 case SIDE_TYPE_DYNAMIC_NULL
:
1019 case SIDE_TYPE_DYNAMIC_BOOL
:
1020 case SIDE_TYPE_DYNAMIC_INTEGER
:
1021 case SIDE_TYPE_DYNAMIC_BYTE
:
1022 case SIDE_TYPE_DYNAMIC_POINTER
:
1023 case SIDE_TYPE_DYNAMIC_FLOAT
:
1024 case SIDE_TYPE_DYNAMIC_STRING
:
1026 /* Dynamic compound types */
1027 case SIDE_TYPE_DYNAMIC_STRUCT
:
1028 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1029 case SIDE_TYPE_DYNAMIC_VLA
:
1030 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1031 tracer_print_dynamic(item
);
1034 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1041 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg
*item
)
1043 printf("%s: ", item_desc
->field_name
);
1044 tracer_print_type(&item_desc
->side_type
, item
);
1048 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1050 const struct side_arg
*sav
= side_arg_vec
->sav
;
1051 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1053 if (type_desc
->u
.side_struct
->nr_fields
!= side_sav_len
) {
1054 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
1057 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_struct
->attr
), type_desc
->u
.side_struct
->nr_attr
);
1058 printf("%s", type_desc
->u
.side_struct
->nr_attr
? ", " : "");
1059 printf("fields: { ");
1060 for (i
= 0; i
< side_sav_len
; i
++) {
1061 printf("%s", i
? ", " : "");
1062 tracer_print_field(&type_desc
->u
.side_struct
->fields
[i
], &sav
[i
]);
1068 void tracer_print_variant(const struct side_type
*type_desc
, const struct side_arg_variant
*side_arg_variant
)
1070 const struct side_type_variant
*side_type_variant
= type_desc
->u
.side_variant
;
1071 const struct side_type
*selector_type
= &side_type_variant
->selector
;
1072 union int64_value v64
;
1075 if (selector_type
->type
!= side_arg_variant
->selector
.type
) {
1076 fprintf(stderr
, "ERROR: Unexpected variant selector type\n");
1079 switch (selector_type
->type
) {
1090 fprintf(stderr
, "ERROR: Expecting integer variant selector type\n");
1093 v64
= tracer_load_integer_value(&selector_type
->u
.side_integer
,
1094 &side_arg_variant
->selector
.u
.side_static
.integer_value
, 0, NULL
);
1095 for (i
= 0; i
< side_type_variant
->nr_options
; i
++) {
1096 const struct side_variant_option
*option
= &side_type_variant
->options
[i
];
1098 if (v64
.s
>= option
->range_begin
&& v64
.s
<= option
->range_end
) {
1099 tracer_print_type(&option
->side_type
, &side_arg_variant
->option
);
1103 fprintf(stderr
, "ERROR: Variant selector value unknown %" PRId64
"\n", v64
.s
);
1108 void tracer_print_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1110 const struct side_arg
*sav
= side_arg_vec
->sav
;
1111 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1113 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
1114 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
1117 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_array
.attr
), type_desc
->u
.side_array
.nr_attr
);
1118 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1119 printf("elements: ");
1121 for (i
= 0; i
< side_sav_len
; i
++) {
1122 printf("%s", i
? ", " : "");
1123 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
1129 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1131 const struct side_arg
*sav
= side_arg_vec
->sav
;
1132 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1134 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_vla
.attr
), type_desc
->u
.side_vla
.nr_attr
);
1135 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1136 printf("elements: ");
1138 for (i
= 0; i
< side_sav_len
; i
++) {
1139 printf("%s", i
? ", " : "");
1140 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
1146 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode
, const char *ptr
)
1148 switch (access_mode
) {
1149 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
1151 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1152 /* Dereference pointer */
1153 memcpy(&ptr
, ptr
, sizeof(const char *));
1161 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode
, uint32_t len
)
1163 switch (access_mode
) {
1164 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
1166 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1167 return sizeof(void *);
1174 union int64_value
tracer_load_gather_integer_value(const struct side_type_gather_integer
*side_integer
,
1177 enum side_type_gather_access_mode access_mode
=
1178 (enum side_type_gather_access_mode
) side_integer
->access_mode
;
1179 uint32_t integer_size_bytes
= side_integer
->type
.integer_size
;
1180 const char *ptr
= (const char *) _ptr
;
1181 union side_integer_value value
;
1183 ptr
= tracer_gather_access(access_mode
, ptr
+ side_integer
->offset
);
1184 memcpy(&value
, ptr
, integer_size_bytes
);
1185 return tracer_load_integer_value(&side_integer
->type
, &value
,
1186 side_integer
->offset_bits
, NULL
);
1190 uint32_t tracer_print_gather_bool_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1192 enum side_type_gather_access_mode access_mode
=
1193 (enum side_type_gather_access_mode
) type_gather
->u
.side_bool
.access_mode
;
1194 uint32_t bool_size_bytes
= type_gather
->u
.side_bool
.type
.bool_size
;
1195 const char *ptr
= (const char *) _ptr
;
1196 union side_bool_value value
;
1198 switch (bool_size_bytes
) {
1207 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_bool
.offset
);
1208 memcpy(&value
, ptr
, bool_size_bytes
);
1209 tracer_print_type_bool(":", &type_gather
->u
.side_bool
.type
, &value
,
1210 type_gather
->u
.side_bool
.offset_bits
);
1211 return tracer_gather_size(access_mode
, bool_size_bytes
);
1215 uint32_t tracer_print_gather_byte_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1217 enum side_type_gather_access_mode access_mode
=
1218 (enum side_type_gather_access_mode
) type_gather
->u
.side_byte
.access_mode
;
1219 const char *ptr
= (const char *) _ptr
;
1222 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_byte
.offset
);
1223 memcpy(&value
, ptr
, 1);
1224 tracer_print_type_header(":", side_ptr_get(type_gather
->u
.side_byte
.type
.attr
),
1225 type_gather
->u
.side_byte
.type
.nr_attr
);
1226 printf("0x%" PRIx8
, value
);
1227 return tracer_gather_size(access_mode
, 1);
1231 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
,
1232 enum tracer_display_base default_base
)
1234 enum side_type_gather_access_mode access_mode
=
1235 (enum side_type_gather_access_mode
) type_gather
->u
.side_integer
.access_mode
;
1236 uint32_t integer_size_bytes
= type_gather
->u
.side_integer
.type
.integer_size
;
1237 const char *ptr
= (const char *) _ptr
;
1238 union side_integer_value value
;
1240 switch (integer_size_bytes
) {
1249 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_integer
.offset
);
1250 memcpy(&value
, ptr
, integer_size_bytes
);
1251 tracer_print_type_integer(":", &type_gather
->u
.side_integer
.type
, &value
,
1252 type_gather
->u
.side_integer
.offset_bits
, default_base
);
1253 return tracer_gather_size(access_mode
, integer_size_bytes
);
1257 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1259 enum side_type_gather_access_mode access_mode
=
1260 (enum side_type_gather_access_mode
) type_gather
->u
.side_float
.access_mode
;
1261 uint32_t float_size_bytes
= type_gather
->u
.side_float
.type
.float_size
;
1262 const char *ptr
= (const char *) _ptr
;
1263 union side_float_value value
;
1265 switch (float_size_bytes
) {
1274 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_float
.offset
);
1275 memcpy(&value
, ptr
, float_size_bytes
);
1276 tracer_print_type_float(":", &type_gather
->u
.side_float
.type
, &value
);
1277 return tracer_gather_size(access_mode
, float_size_bytes
);
1281 uint32_t tracer_print_gather_string_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1283 enum side_type_gather_access_mode access_mode
=
1284 (enum side_type_gather_access_mode
) type_gather
->u
.side_string
.access_mode
;
1285 const char *ptr
= (const char *) _ptr
;
1288 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_string
.offset
);
1289 tracer_print_type_header(":", side_ptr_get(type_gather
->u
.side_string
.type
.attr
),
1290 type_gather
->u
.side_string
.type
.nr_attr
);
1292 tracer_print_string(ptr
, type_gather
->u
.side_string
.type
.unit_size
,
1293 type_gather
->u
.side_string
.type
.byte_order
, &string_len
);
1296 string_len
= type_gather
->u
.side_string
.type
.unit_size
;
1298 return tracer_gather_size(access_mode
, string_len
);
1302 uint32_t tracer_print_gather_type(const struct side_type
*type_desc
, const void *ptr
)
1307 switch (type_desc
->type
) {
1308 /* Gather basic types */
1309 case SIDE_TYPE_GATHER_BOOL
:
1310 len
= tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, ptr
);
1312 case SIDE_TYPE_GATHER_INTEGER
:
1313 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
,
1314 TRACER_DISPLAY_BASE_10
);
1316 case SIDE_TYPE_GATHER_BYTE
:
1317 len
= tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, ptr
);
1319 case SIDE_TYPE_GATHER_POINTER
:
1320 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
,
1321 TRACER_DISPLAY_BASE_16
);
1323 case SIDE_TYPE_GATHER_FLOAT
:
1324 len
= tracer_print_gather_float_type(&type_desc
->u
.side_gather
, ptr
);
1326 case SIDE_TYPE_GATHER_STRING
:
1327 len
= tracer_print_gather_string_type(&type_desc
->u
.side_gather
, ptr
);
1330 /* Gather enum types */
1331 case SIDE_TYPE_GATHER_ENUM
:
1332 len
= tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, ptr
);
1335 /* Gather compound types */
1336 case SIDE_TYPE_GATHER_STRUCT
:
1337 len
= tracer_print_gather_struct(&type_desc
->u
.side_gather
, ptr
);
1339 case SIDE_TYPE_GATHER_ARRAY
:
1340 len
= tracer_print_gather_array(&type_desc
->u
.side_gather
, ptr
);
1342 case SIDE_TYPE_GATHER_VLA
:
1343 len
= tracer_print_gather_vla(&type_desc
->u
.side_gather
, ptr
, ptr
);
1346 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
1354 uint32_t tracer_print_gather_enum_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1356 const struct side_enum_mappings
*mappings
= type_gather
->u
.side_enum
.mappings
;
1357 const struct side_type
*enum_elem_type
= type_gather
->u
.side_enum
.elem_type
;
1358 const struct side_type_gather_integer
*side_integer
= &enum_elem_type
->u
.side_gather
.u
.side_integer
;
1359 enum side_type_gather_access_mode access_mode
=
1360 (enum side_type_gather_access_mode
) side_integer
->access_mode
;
1361 uint32_t integer_size_bytes
= side_integer
->type
.integer_size
;
1362 const char *ptr
= (const char *) _ptr
;
1363 union side_integer_value value
;
1364 union int64_value v64
;
1366 switch (integer_size_bytes
) {
1375 ptr
= tracer_gather_access(access_mode
, ptr
+ side_integer
->offset
);
1376 memcpy(&value
, ptr
, integer_size_bytes
);
1377 v64
= tracer_load_gather_integer_value(side_integer
, &value
);
1378 print_attributes("attr", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
1379 printf("%s", mappings
->nr_attr
? ", " : "");
1380 tracer_print_gather_type(enum_elem_type
, ptr
);
1381 print_enum_labels(mappings
, v64
);
1382 return tracer_gather_size(access_mode
, integer_size_bytes
);
1386 void tracer_print_gather_field(const struct side_event_field
*field
, const void *ptr
)
1388 printf("%s: ", field
->field_name
);
1389 (void) tracer_print_gather_type(&field
->side_type
, ptr
);
1393 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
)
1395 enum side_type_gather_access_mode access_mode
=
1396 (enum side_type_gather_access_mode
) type_gather
->u
.side_struct
.access_mode
;
1397 const char *ptr
= (const char *) _ptr
;
1400 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_struct
.offset
);
1401 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_struct
.type
->attr
), type_gather
->u
.side_struct
.type
->nr_attr
);
1402 printf("%s", type_gather
->u
.side_struct
.type
->nr_attr
? ", " : "");
1403 printf("fields: { ");
1404 for (i
= 0; i
< type_gather
->u
.side_struct
.type
->nr_fields
; i
++) {
1405 printf("%s", i
? ", " : "");
1406 tracer_print_gather_field(&type_gather
->u
.side_struct
.type
->fields
[i
], ptr
);
1409 return tracer_gather_size(access_mode
, type_gather
->u
.side_struct
.size
);
1413 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
)
1415 enum side_type_gather_access_mode access_mode
=
1416 (enum side_type_gather_access_mode
) type_gather
->u
.side_array
.access_mode
;
1417 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1420 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_array
.offset
);
1422 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_array
.type
.attr
), type_gather
->u
.side_array
.type
.nr_attr
);
1423 printf("%s", type_gather
->u
.side_array
.type
.nr_attr
? ", " : "");
1424 printf("elements: ");
1426 for (i
= 0; i
< type_gather
->u
.side_array
.type
.length
; i
++) {
1427 switch (type_gather
->u
.side_array
.type
.elem_type
->type
) {
1428 case SIDE_TYPE_GATHER_VLA
:
1429 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1434 printf("%s", i
? ", " : "");
1435 ptr
+= tracer_print_gather_type(type_gather
->u
.side_array
.type
.elem_type
, ptr
);
1438 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1442 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
,
1443 const void *_length_ptr
)
1445 enum side_type_gather_access_mode access_mode
=
1446 (enum side_type_gather_access_mode
) type_gather
->u
.side_vla
.access_mode
;
1447 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1448 const char *length_ptr
= (const char *) _length_ptr
;
1449 union int64_value v64
;
1453 switch (type_gather
->u
.side_vla
.length_type
->type
) {
1454 case SIDE_TYPE_GATHER_INTEGER
:
1457 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
1460 v64
= tracer_load_gather_integer_value(&type_gather
->u
.side_vla
.length_type
->u
.side_gather
.u
.side_integer
,
1462 length
= (uint32_t) v64
.u
;
1463 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_vla
.offset
);
1465 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_vla
.type
.attr
), type_gather
->u
.side_vla
.type
.nr_attr
);
1466 printf("%s", type_gather
->u
.side_vla
.type
.nr_attr
? ", " : "");
1467 printf("elements: ");
1469 for (i
= 0; i
< length
; i
++) {
1470 switch (type_gather
->u
.side_vla
.type
.elem_type
->type
) {
1471 case SIDE_TYPE_GATHER_VLA
:
1472 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1477 printf("%s", i
? ", " : "");
1478 ptr
+= tracer_print_gather_type(type_gather
->u
.side_vla
.type
.elem_type
, ptr
);
1481 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1484 struct tracer_visitor_priv
{
1485 const struct side_type
*elem_type
;
1490 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1491 const struct side_arg
*elem
)
1493 struct tracer_visitor_priv
*tracer_priv
= (struct tracer_visitor_priv
*) tracer_ctx
->priv
;
1495 printf("%s", tracer_priv
->i
++ ? ", " : "");
1496 tracer_print_type(tracer_priv
->elem_type
, elem
);
1497 return SIDE_VISITOR_STATUS_OK
;
1501 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
)
1503 enum side_visitor_status status
;
1504 struct tracer_visitor_priv tracer_priv
= {
1505 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
1508 const struct side_tracer_visitor_ctx tracer_ctx
= {
1509 .write_elem
= tracer_write_elem_cb
,
1510 .priv
= &tracer_priv
,
1513 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_vla_visitor
.attr
), type_desc
->u
.side_vla_visitor
.nr_attr
);
1514 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1515 printf("elements: ");
1517 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1519 case SIDE_VISITOR_STATUS_OK
:
1521 case SIDE_VISITOR_STATUS_ERROR
:
1522 fprintf(stderr
, "ERROR: Visitor error\n");
1529 void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
)
1531 const struct side_arg_dynamic_field
*fields
= dynamic_struct
->fields
;
1532 uint32_t i
, len
= dynamic_struct
->len
;
1534 print_attributes("attr", "::", side_ptr_get(dynamic_struct
->attr
), dynamic_struct
->nr_attr
);
1535 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1536 printf("fields:: ");
1538 for (i
= 0; i
< len
; i
++) {
1539 printf("%s", i
? ", " : "");
1540 printf("%s:: ", fields
[i
].field_name
);
1541 tracer_print_dynamic(&fields
[i
].elem
);
1546 struct tracer_dynamic_struct_visitor_priv
{
1551 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1552 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1553 const struct side_arg_dynamic_field
*dynamic_field
)
1555 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
=
1556 (struct tracer_dynamic_struct_visitor_priv
*) tracer_ctx
->priv
;
1558 printf("%s", tracer_priv
->i
++ ? ", " : "");
1559 printf("%s:: ", dynamic_field
->field_name
);
1560 tracer_print_dynamic(&dynamic_field
->elem
);
1561 return SIDE_VISITOR_STATUS_OK
;
1565 void tracer_print_dynamic_struct_visitor(const struct side_arg
*item
)
1567 enum side_visitor_status status
;
1568 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1571 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1572 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1573 .priv
= &tracer_priv
,
1575 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.app_ctx
;
1577 print_attributes("attr", "::", side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct_visitor
.attr
), item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
);
1578 printf("%s", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1579 printf("fields:: ");
1581 status
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1583 case SIDE_VISITOR_STATUS_OK
:
1585 case SIDE_VISITOR_STATUS_ERROR
:
1586 fprintf(stderr
, "ERROR: Visitor error\n");
1593 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla
*vla
)
1595 const struct side_arg
*sav
= vla
->sav
;
1596 uint32_t i
, side_sav_len
= vla
->len
;
1598 print_attributes("attr", "::", side_ptr_get(vla
->attr
), vla
->nr_attr
);
1599 printf("%s", vla
->nr_attr
? ", " : "");
1600 printf("elements:: ");
1602 for (i
= 0; i
< side_sav_len
; i
++) {
1603 printf("%s", i
? ", " : "");
1604 tracer_print_dynamic(&sav
[i
]);
1609 struct tracer_dynamic_vla_visitor_priv
{
1614 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1615 const struct side_tracer_visitor_ctx
*tracer_ctx
,
1616 const struct side_arg
*elem
)
1618 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
=
1619 (struct tracer_dynamic_vla_visitor_priv
*) tracer_ctx
->priv
;
1621 printf("%s", tracer_priv
->i
++ ? ", " : "");
1622 tracer_print_dynamic(elem
);
1623 return SIDE_VISITOR_STATUS_OK
;
1627 void tracer_print_dynamic_vla_visitor(const struct side_arg
*item
)
1629 enum side_visitor_status status
;
1630 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1633 const struct side_tracer_visitor_ctx tracer_ctx
= {
1634 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1635 .priv
= &tracer_priv
,
1637 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.app_ctx
;
1639 print_attributes("attr", "::", side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla_visitor
.attr
), item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
);
1640 printf("%s", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1641 printf("elements:: ");
1643 status
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1645 case SIDE_VISITOR_STATUS_OK
:
1647 case SIDE_VISITOR_STATUS_ERROR
:
1648 fprintf(stderr
, "ERROR: Visitor error\n");
1655 void tracer_print_dynamic(const struct side_arg
*item
)
1658 switch (item
->type
) {
1659 /* Dynamic basic types */
1660 case SIDE_TYPE_DYNAMIC_NULL
:
1661 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_null
.attr
),
1662 item
->u
.side_dynamic
.side_null
.nr_attr
);
1663 printf("<NULL TYPE>");
1665 case SIDE_TYPE_DYNAMIC_BOOL
:
1666 tracer_print_type_bool("::", &item
->u
.side_dynamic
.side_bool
.type
, &item
->u
.side_dynamic
.side_bool
.value
, 0);
1668 case SIDE_TYPE_DYNAMIC_INTEGER
:
1669 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1670 TRACER_DISPLAY_BASE_10
);
1672 case SIDE_TYPE_DYNAMIC_BYTE
:
1673 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_byte
.type
.attr
), item
->u
.side_dynamic
.side_byte
.type
.nr_attr
);
1674 printf("0x%" PRIx8
, item
->u
.side_dynamic
.side_byte
.value
);
1676 case SIDE_TYPE_DYNAMIC_POINTER
:
1677 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1678 TRACER_DISPLAY_BASE_16
);
1680 case SIDE_TYPE_DYNAMIC_FLOAT
:
1681 tracer_print_type_float("::", &item
->u
.side_dynamic
.side_float
.type
,
1682 &item
->u
.side_dynamic
.side_float
.value
);
1684 case SIDE_TYPE_DYNAMIC_STRING
:
1685 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_string
.type
.attr
), item
->u
.side_dynamic
.side_string
.type
.nr_attr
);
1686 tracer_print_string((const char *)(uintptr_t) item
->u
.side_dynamic
.side_string
.value
,
1687 item
->u
.side_dynamic
.side_string
.type
.unit_size
,
1688 item
->u
.side_dynamic
.side_string
.type
.byte_order
, NULL
);
1691 /* Dynamic compound types */
1692 case SIDE_TYPE_DYNAMIC_STRUCT
:
1693 tracer_print_dynamic_struct(item
->u
.side_dynamic
.side_dynamic_struct
);
1695 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1696 tracer_print_dynamic_struct_visitor(item
);
1698 case SIDE_TYPE_DYNAMIC_VLA
:
1699 tracer_print_dynamic_vla(item
->u
.side_dynamic
.side_dynamic_vla
);
1701 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1702 tracer_print_dynamic_vla_visitor(item
);
1705 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1712 void tracer_print_static_fields(const struct side_event_description
*desc
,
1713 const struct side_arg_vec
*side_arg_vec
,
1716 const struct side_arg
*sav
= side_arg_vec
->sav
;
1717 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1719 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
1720 if (desc
->nr_fields
!= side_sav_len
) {
1721 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1724 print_attributes(", attr", ":", side_ptr_get(desc
->attr
), desc
->nr_attr
);
1725 printf("%s", side_sav_len
? ", fields: [ " : "");
1726 for (i
= 0; i
< side_sav_len
; i
++) {
1727 printf("%s", i
? ", " : "");
1728 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
1737 void tracer_call(const struct side_event_description
*desc
,
1738 const struct side_arg_vec
*side_arg_vec
,
1739 void *priv
__attribute__((unused
)))
1741 uint32_t nr_fields
= 0;
1743 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1748 void tracer_call_variadic(const struct side_event_description
*desc
,
1749 const struct side_arg_vec
*side_arg_vec
,
1750 const struct side_arg_dynamic_struct
*var_struct
,
1751 void *priv
__attribute__((unused
)))
1753 uint32_t nr_fields
= 0, i
, var_struct_len
= var_struct
->len
;
1755 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1757 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1758 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1761 print_attributes(", attr ", "::", side_ptr_get(var_struct
->attr
), var_struct
->nr_attr
);
1762 printf("%s", var_struct_len
? ", fields:: [ " : "");
1763 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1764 printf("%s", i
? ", " : "");
1765 printf("%s:: ", var_struct
->fields
[i
].field_name
);
1766 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
1774 void tracer_event_notification(enum side_tracer_notification notif
,
1775 struct side_event_description
**events
, uint32_t nr_events
,
1776 void *priv
__attribute__((unused
)))
1781 printf("----------------------------------------------------------\n");
1782 printf("Tracer notified of events %s\n",
1783 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1784 for (i
= 0; i
< nr_events
; i
++) {
1785 struct side_event_description
*event
= events
[i
];
1787 /* Skip NULL pointers */
1790 printf("provider: %s, event: %s\n",
1791 event
->provider_name
, event
->event_name
);
1792 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1793 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1794 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1798 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1803 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1804 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1808 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1814 printf("----------------------------------------------------------\n");
1817 static __attribute__((constructor
))
1818 void tracer_init(void);
1820 void tracer_init(void)
1822 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1827 static __attribute__((destructor
))
1828 void tracer_exit(void);
1830 void tracer_exit(void)
1832 side_tracer_event_notification_unregister(tracer_handle
);