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
= &side_ptr_get(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
= side_ptr_get(type_desc
->u
.side_enum
.mappings
);
475 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum
.elem_type
);
476 union int64_value v64
;
478 if (side_enum_get(elem_type
->type
) != side_enum_get(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 (side_enum_get(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
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.mappings
);
521 const struct side_type
*enum_elem_type
= side_ptr_get(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 (side_enum_get(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
= side_ptr_get(enum_elem_type
->u
.side_array
.elem_type
);
541 array_item
= side_ptr_get(side_ptr_get(item
->u
.side_static
.side_array
)->sav
);
542 nr_items
= type_desc
->u
.side_array
.length
;
545 elem_type
= side_ptr_get(enum_elem_type
->u
.side_vla
.elem_type
);
546 array_item
= side_ptr_get(side_ptr_get(item
->u
.side_static
.side_vla
)->sav
);
547 nr_items
= side_ptr_get(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_ptr_get(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 (side_enum_get(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 (side_enum_get(type_desc
->type
)) {
823 switch (side_enum_get(item
->type
)) {
834 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
840 case SIDE_TYPE_ENUM_BITMAP
:
841 switch (side_enum_get(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 (side_enum_get(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 (side_enum_get(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 (side_enum_get(type_desc
->type
) != side_enum_get(item
->type
)) {
891 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
897 if (side_enum_get(type_desc
->type
) == SIDE_TYPE_ENUM
|| side_enum_get(type_desc
->type
) == SIDE_TYPE_ENUM_BITMAP
|| side_enum_get(type_desc
->type
) == SIDE_TYPE_GATHER_ENUM
)
898 type
= side_enum_get(type_desc
->type
);
900 type
= side_enum_get(item
->type
);
904 /* Stack-copy basic types */
906 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_null
.attr
),
907 type_desc
->u
.side_null
.nr_attr
);
908 printf("<NULL TYPE>");
912 tracer_print_type_bool(":", &type_desc
->u
.side_bool
, &item
->u
.side_static
.bool_value
, 0);
923 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
924 TRACER_DISPLAY_BASE_10
);
928 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_byte
.attr
), type_desc
->u
.side_byte
.nr_attr
);
929 printf("0x%" PRIx8
, item
->u
.side_static
.byte_value
);
932 case SIDE_TYPE_POINTER
:
933 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
934 TRACER_DISPLAY_BASE_16
);
937 case SIDE_TYPE_FLOAT_BINARY16
:
938 case SIDE_TYPE_FLOAT_BINARY32
:
939 case SIDE_TYPE_FLOAT_BINARY64
:
940 case SIDE_TYPE_FLOAT_BINARY128
:
941 tracer_print_type_float(":", &type_desc
->u
.side_float
, &item
->u
.side_static
.float_value
);
944 case SIDE_TYPE_STRING_UTF8
:
945 case SIDE_TYPE_STRING_UTF16
:
946 case SIDE_TYPE_STRING_UTF32
:
947 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_string
.attr
), type_desc
->u
.side_string
.nr_attr
);
948 tracer_print_string(side_ptr_get(item
->u
.side_static
.string_value
),
949 type_desc
->u
.side_string
.unit_size
, type_desc
->u
.side_string
.byte_order
, NULL
);
952 /* Stack-copy compound types */
953 case SIDE_TYPE_STRUCT
:
954 tracer_print_struct(type_desc
, side_ptr_get(item
->u
.side_static
.side_struct
));
956 case SIDE_TYPE_VARIANT
:
957 tracer_print_variant(type_desc
, side_ptr_get(item
->u
.side_static
.side_variant
));
959 case SIDE_TYPE_ARRAY
:
960 tracer_print_array(type_desc
, side_ptr_get(item
->u
.side_static
.side_array
));
963 tracer_print_vla(type_desc
, side_ptr_get(item
->u
.side_static
.side_vla
));
965 case SIDE_TYPE_VLA_VISITOR
:
966 tracer_print_vla_visitor(type_desc
, item
->u
.side_static
.side_vla_app_visitor_ctx
);
969 /* Stack-copy enumeration types */
971 tracer_print_enum(type_desc
, item
);
973 case SIDE_TYPE_ENUM_BITMAP
:
974 tracer_print_enum_bitmap(type_desc
, item
);
977 /* Gather basic types */
978 case SIDE_TYPE_GATHER_BOOL
:
979 (void) tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_bool_gather_ptr
));
981 case SIDE_TYPE_GATHER_INTEGER
:
982 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_integer_gather_ptr
),
983 TRACER_DISPLAY_BASE_10
);
985 case SIDE_TYPE_GATHER_BYTE
:
986 (void) tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_byte_gather_ptr
));
988 case SIDE_TYPE_GATHER_POINTER
:
989 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_integer_gather_ptr
),
990 TRACER_DISPLAY_BASE_16
);
992 case SIDE_TYPE_GATHER_FLOAT
:
993 (void) tracer_print_gather_float_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_float_gather_ptr
));
995 case SIDE_TYPE_GATHER_STRING
:
996 (void) tracer_print_gather_string_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_string_gather_ptr
));
999 /* Gather compound type */
1000 case SIDE_TYPE_GATHER_STRUCT
:
1001 (void) tracer_print_gather_struct(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_struct_gather_ptr
));
1003 case SIDE_TYPE_GATHER_ARRAY
:
1004 (void) tracer_print_gather_array(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_array_gather_ptr
));
1006 case SIDE_TYPE_GATHER_VLA
:
1007 (void) tracer_print_gather_vla(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_vla_gather
.ptr
),
1008 side_ptr_get(item
->u
.side_static
.side_vla_gather
.length_ptr
));
1011 /* Gather enumeration types */
1012 case SIDE_TYPE_GATHER_ENUM
:
1013 (void) tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_integer_gather_ptr
));
1016 /* Dynamic basic types */
1017 case SIDE_TYPE_DYNAMIC_NULL
:
1018 case SIDE_TYPE_DYNAMIC_BOOL
:
1019 case SIDE_TYPE_DYNAMIC_INTEGER
:
1020 case SIDE_TYPE_DYNAMIC_BYTE
:
1021 case SIDE_TYPE_DYNAMIC_POINTER
:
1022 case SIDE_TYPE_DYNAMIC_FLOAT
:
1023 case SIDE_TYPE_DYNAMIC_STRING
:
1025 /* Dynamic compound types */
1026 case SIDE_TYPE_DYNAMIC_STRUCT
:
1027 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1028 case SIDE_TYPE_DYNAMIC_VLA
:
1029 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1030 tracer_print_dynamic(item
);
1033 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1040 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg
*item
)
1042 printf("%s: ", side_ptr_get(item_desc
->field_name
));
1043 tracer_print_type(&item_desc
->side_type
, item
);
1047 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1049 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1050 const struct side_type_struct
*side_struct
= side_ptr_get(type_desc
->u
.side_struct
);
1051 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1053 if (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(side_struct
->attr
), side_struct
->nr_attr
);
1058 printf("%s", side_struct
->nr_attr
? ", " : "");
1059 printf("fields: { ");
1060 for (i
= 0; i
< side_sav_len
; i
++) {
1061 printf("%s", i
? ", " : "");
1062 tracer_print_field(&side_ptr_get(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
= side_ptr_get(type_desc
->u
.side_variant
);
1071 const struct side_type
*selector_type
= &side_type_variant
->selector
;
1072 union int64_value v64
;
1075 if (side_enum_get(selector_type
->type
) != side_enum_get(side_arg_variant
->selector
.type
)) {
1076 fprintf(stderr
, "ERROR: Unexpected variant selector type\n");
1079 switch (side_enum_get(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_ptr_get(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_ptr_get(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(side_ptr_get(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_ptr_get(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(side_ptr_get(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 (side_enum_get(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
= side_ptr_get(type_gather
->u
.side_enum
.mappings
);
1357 const struct side_type
*enum_elem_type
= side_ptr_get(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: ", side_ptr_get(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 struct side_type_struct
*side_struct
= side_ptr_get(type_gather
->u
.side_struct
.type
);
1398 const char *ptr
= (const char *) _ptr
;
1401 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_struct
.offset
);
1402 print_attributes("attr", ":", side_ptr_get(side_struct
->attr
), side_struct
->nr_attr
);
1403 printf("%s", side_struct
->nr_attr
? ", " : "");
1404 printf("fields: { ");
1405 for (i
= 0; i
< side_struct
->nr_fields
; i
++) {
1406 printf("%s", i
? ", " : "");
1407 tracer_print_gather_field(&side_ptr_get(side_struct
->fields
)[i
], ptr
);
1410 return tracer_gather_size(access_mode
, type_gather
->u
.side_struct
.size
);
1414 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
)
1416 enum side_type_gather_access_mode access_mode
=
1417 (enum side_type_gather_access_mode
) type_gather
->u
.side_array
.access_mode
;
1418 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1421 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_array
.offset
);
1423 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_array
.type
.attr
), type_gather
->u
.side_array
.type
.nr_attr
);
1424 printf("%s", type_gather
->u
.side_array
.type
.nr_attr
? ", " : "");
1425 printf("elements: ");
1427 for (i
= 0; i
< type_gather
->u
.side_array
.type
.length
; i
++) {
1428 const struct side_type
*elem_type
= side_ptr_get(type_gather
->u
.side_array
.type
.elem_type
);
1430 switch (side_enum_get(elem_type
->type
)) {
1431 case SIDE_TYPE_GATHER_VLA
:
1432 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1437 printf("%s", i
? ", " : "");
1438 ptr
+= tracer_print_gather_type(elem_type
, ptr
);
1441 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1445 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
,
1446 const void *_length_ptr
)
1448 enum side_type_gather_access_mode access_mode
=
1449 (enum side_type_gather_access_mode
) type_gather
->u
.side_vla
.access_mode
;
1450 const struct side_type
*length_type
= side_ptr_get(type_gather
->u
.side_vla
.length_type
);
1451 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1452 const char *length_ptr
= (const char *) _length_ptr
;
1453 union int64_value v64
;
1457 switch (side_enum_get(length_type
->type
)) {
1458 case SIDE_TYPE_GATHER_INTEGER
:
1461 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
1464 v64
= tracer_load_gather_integer_value(&length_type
->u
.side_gather
.u
.side_integer
,
1466 length
= (uint32_t) v64
.u
;
1467 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_vla
.offset
);
1469 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_vla
.type
.attr
), type_gather
->u
.side_vla
.type
.nr_attr
);
1470 printf("%s", type_gather
->u
.side_vla
.type
.nr_attr
? ", " : "");
1471 printf("elements: ");
1473 for (i
= 0; i
< length
; i
++) {
1474 const struct side_type
*elem_type
= side_ptr_get(type_gather
->u
.side_vla
.type
.elem_type
);
1476 switch (side_enum_get(elem_type
->type
)) {
1477 case SIDE_TYPE_GATHER_VLA
:
1478 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1483 printf("%s", i
? ", " : "");
1484 ptr
+= tracer_print_gather_type(elem_type
, ptr
);
1487 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1490 struct tracer_visitor_priv
{
1491 const struct side_type
*elem_type
;
1496 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1497 const struct side_arg
*elem
)
1499 struct tracer_visitor_priv
*tracer_priv
= (struct tracer_visitor_priv
*) tracer_ctx
->priv
;
1501 printf("%s", tracer_priv
->i
++ ? ", " : "");
1502 tracer_print_type(tracer_priv
->elem_type
, elem
);
1503 return SIDE_VISITOR_STATUS_OK
;
1507 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
)
1509 enum side_visitor_status status
;
1510 struct tracer_visitor_priv tracer_priv
= {
1511 .elem_type
= side_ptr_get(type_desc
->u
.side_vla_visitor
.elem_type
),
1514 const struct side_tracer_visitor_ctx tracer_ctx
= {
1515 .write_elem
= tracer_write_elem_cb
,
1516 .priv
= &tracer_priv
,
1519 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_vla_visitor
.attr
), type_desc
->u
.side_vla_visitor
.nr_attr
);
1520 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1521 printf("elements: ");
1523 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1525 case SIDE_VISITOR_STATUS_OK
:
1527 case SIDE_VISITOR_STATUS_ERROR
:
1528 fprintf(stderr
, "ERROR: Visitor error\n");
1535 void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
)
1537 const struct side_arg_dynamic_field
*fields
= side_ptr_get(dynamic_struct
->fields
);
1538 uint32_t i
, len
= dynamic_struct
->len
;
1540 print_attributes("attr", "::", side_ptr_get(dynamic_struct
->attr
), dynamic_struct
->nr_attr
);
1541 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1542 printf("fields:: ");
1544 for (i
= 0; i
< len
; i
++) {
1545 printf("%s", i
? ", " : "");
1546 printf("%s:: ", side_ptr_get(fields
[i
].field_name
));
1547 tracer_print_dynamic(&fields
[i
].elem
);
1552 struct tracer_dynamic_struct_visitor_priv
{
1557 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1558 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1559 const struct side_arg_dynamic_field
*dynamic_field
)
1561 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
=
1562 (struct tracer_dynamic_struct_visitor_priv
*) tracer_ctx
->priv
;
1564 printf("%s", tracer_priv
->i
++ ? ", " : "");
1565 printf("%s:: ", side_ptr_get(dynamic_field
->field_name
));
1566 tracer_print_dynamic(&dynamic_field
->elem
);
1567 return SIDE_VISITOR_STATUS_OK
;
1571 void tracer_print_dynamic_struct_visitor(const struct side_arg
*item
)
1573 enum side_visitor_status status
;
1574 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1577 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1578 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1579 .priv
= &tracer_priv
,
1581 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.app_ctx
;
1583 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
);
1584 printf("%s", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1585 printf("fields:: ");
1587 status
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1589 case SIDE_VISITOR_STATUS_OK
:
1591 case SIDE_VISITOR_STATUS_ERROR
:
1592 fprintf(stderr
, "ERROR: Visitor error\n");
1599 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla
*vla
)
1601 const struct side_arg
*sav
= side_ptr_get(vla
->sav
);
1602 uint32_t i
, side_sav_len
= vla
->len
;
1604 print_attributes("attr", "::", side_ptr_get(vla
->attr
), vla
->nr_attr
);
1605 printf("%s", vla
->nr_attr
? ", " : "");
1606 printf("elements:: ");
1608 for (i
= 0; i
< side_sav_len
; i
++) {
1609 printf("%s", i
? ", " : "");
1610 tracer_print_dynamic(&sav
[i
]);
1615 struct tracer_dynamic_vla_visitor_priv
{
1620 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1621 const struct side_tracer_visitor_ctx
*tracer_ctx
,
1622 const struct side_arg
*elem
)
1624 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
=
1625 (struct tracer_dynamic_vla_visitor_priv
*) tracer_ctx
->priv
;
1627 printf("%s", tracer_priv
->i
++ ? ", " : "");
1628 tracer_print_dynamic(elem
);
1629 return SIDE_VISITOR_STATUS_OK
;
1633 void tracer_print_dynamic_vla_visitor(const struct side_arg
*item
)
1635 enum side_visitor_status status
;
1636 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1639 const struct side_tracer_visitor_ctx tracer_ctx
= {
1640 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1641 .priv
= &tracer_priv
,
1643 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.app_ctx
;
1645 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
);
1646 printf("%s", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1647 printf("elements:: ");
1649 status
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1651 case SIDE_VISITOR_STATUS_OK
:
1653 case SIDE_VISITOR_STATUS_ERROR
:
1654 fprintf(stderr
, "ERROR: Visitor error\n");
1661 void tracer_print_dynamic(const struct side_arg
*item
)
1664 switch (side_enum_get(item
->type
)) {
1665 /* Dynamic basic types */
1666 case SIDE_TYPE_DYNAMIC_NULL
:
1667 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_null
.attr
),
1668 item
->u
.side_dynamic
.side_null
.nr_attr
);
1669 printf("<NULL TYPE>");
1671 case SIDE_TYPE_DYNAMIC_BOOL
:
1672 tracer_print_type_bool("::", &item
->u
.side_dynamic
.side_bool
.type
, &item
->u
.side_dynamic
.side_bool
.value
, 0);
1674 case SIDE_TYPE_DYNAMIC_INTEGER
:
1675 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1676 TRACER_DISPLAY_BASE_10
);
1678 case SIDE_TYPE_DYNAMIC_BYTE
:
1679 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_byte
.type
.attr
), item
->u
.side_dynamic
.side_byte
.type
.nr_attr
);
1680 printf("0x%" PRIx8
, item
->u
.side_dynamic
.side_byte
.value
);
1682 case SIDE_TYPE_DYNAMIC_POINTER
:
1683 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1684 TRACER_DISPLAY_BASE_16
);
1686 case SIDE_TYPE_DYNAMIC_FLOAT
:
1687 tracer_print_type_float("::", &item
->u
.side_dynamic
.side_float
.type
,
1688 &item
->u
.side_dynamic
.side_float
.value
);
1690 case SIDE_TYPE_DYNAMIC_STRING
:
1691 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_string
.type
.attr
), item
->u
.side_dynamic
.side_string
.type
.nr_attr
);
1692 tracer_print_string((const char *)(uintptr_t) item
->u
.side_dynamic
.side_string
.value
,
1693 item
->u
.side_dynamic
.side_string
.type
.unit_size
,
1694 item
->u
.side_dynamic
.side_string
.type
.byte_order
, NULL
);
1697 /* Dynamic compound types */
1698 case SIDE_TYPE_DYNAMIC_STRUCT
:
1699 tracer_print_dynamic_struct(side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct
));
1701 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1702 tracer_print_dynamic_struct_visitor(item
);
1704 case SIDE_TYPE_DYNAMIC_VLA
:
1705 tracer_print_dynamic_vla(side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla
));
1707 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1708 tracer_print_dynamic_vla_visitor(item
);
1711 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1718 void tracer_print_static_fields(const struct side_event_description
*desc
,
1719 const struct side_arg_vec
*side_arg_vec
,
1722 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1723 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1725 printf("provider: %s, event: %s", side_ptr_get(desc
->provider_name
), side_ptr_get(desc
->event_name
));
1726 if (desc
->nr_fields
!= side_sav_len
) {
1727 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1730 print_attributes(", attr", ":", side_ptr_get(desc
->attr
), desc
->nr_attr
);
1731 printf("%s", side_sav_len
? ", fields: [ " : "");
1732 for (i
= 0; i
< side_sav_len
; i
++) {
1733 printf("%s", i
? ", " : "");
1734 tracer_print_field(&side_ptr_get(desc
->fields
)[i
], &sav
[i
]);
1743 void tracer_call(const struct side_event_description
*desc
,
1744 const struct side_arg_vec
*side_arg_vec
,
1745 void *priv
__attribute__((unused
)))
1747 uint32_t nr_fields
= 0;
1749 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1754 void tracer_call_variadic(const struct side_event_description
*desc
,
1755 const struct side_arg_vec
*side_arg_vec
,
1756 const struct side_arg_dynamic_struct
*var_struct
,
1757 void *priv
__attribute__((unused
)))
1759 uint32_t nr_fields
= 0, i
, var_struct_len
= var_struct
->len
;
1761 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1763 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1764 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1767 print_attributes(", attr ", "::", side_ptr_get(var_struct
->attr
), var_struct
->nr_attr
);
1768 printf("%s", var_struct_len
? ", fields:: [ " : "");
1769 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1770 printf("%s", i
? ", " : "");
1771 printf("%s:: ", side_ptr_get(side_ptr_get(var_struct
->fields
)[i
].field_name
));
1772 tracer_print_dynamic(&side_ptr_get(var_struct
->fields
)[i
].elem
);
1780 void tracer_event_notification(enum side_tracer_notification notif
,
1781 struct side_event_description
**events
, uint32_t nr_events
,
1782 void *priv
__attribute__((unused
)))
1787 printf("----------------------------------------------------------\n");
1788 printf("Tracer notified of events %s\n",
1789 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1790 for (i
= 0; i
< nr_events
; i
++) {
1791 struct side_event_description
*event
= events
[i
];
1793 /* Skip NULL pointers */
1796 printf("provider: %s, event: %s\n",
1797 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
));
1798 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1799 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1800 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1804 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1809 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1810 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1814 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1820 printf("----------------------------------------------------------\n");
1823 static __attribute__((constructor
))
1824 void tracer_init(void);
1826 void tracer_init(void)
1828 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1833 static __attribute__((destructor
))
1834 void tracer_exit(void);
1836 void tracer_exit(void)
1838 side_tracer_event_notification_unregister(tracer_handle
);