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 (side_enum_get(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 side_enum_get(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 side_enum_get(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 (side_enum_get(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 side_enum_get(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
= side_enum_get(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
,
464 side_enum_get(mapping
->label
.byte_order
), NULL
);
468 printf("<NO LABEL>");
473 void tracer_print_enum(const struct side_type
*type_desc
, const struct side_arg
*item
)
475 const struct side_enum_mappings
*mappings
= side_ptr_get(type_desc
->u
.side_enum
.mappings
);
476 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum
.elem_type
);
477 union int64_value v64
;
479 if (side_enum_get(elem_type
->type
) != side_enum_get(item
->type
)) {
480 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
483 v64
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
484 &item
->u
.side_static
.integer_value
, 0, NULL
);
485 print_attributes("attr", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
486 printf("%s", mappings
->nr_attr
? ", " : "");
487 tracer_print_type(elem_type
, item
);
488 print_enum_labels(mappings
, v64
);
492 uint32_t elem_type_to_stride(const struct side_type
*elem_type
)
496 switch (side_enum_get(elem_type
->type
)) {
509 return elem_type
->u
.side_integer
.integer_size
* CHAR_BIT
;
511 fprintf(stderr
, "ERROR: Unexpected enum bitmap element type\n");
518 void tracer_print_enum_bitmap(const struct side_type
*type_desc
,
519 const struct side_arg
*item
)
521 const struct side_enum_bitmap_mappings
*side_enum_mappings
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.mappings
);
522 const struct side_type
*enum_elem_type
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.elem_type
), *elem_type
;
523 uint32_t i
, print_count
= 0, stride_bit
, nr_items
;
524 const struct side_arg
*array_item
;
526 switch (side_enum_get(enum_elem_type
->type
)) {
527 case SIDE_TYPE_U8
: /* Fall-through */
528 case SIDE_TYPE_BYTE
: /* Fall-through */
529 case SIDE_TYPE_U16
: /* Fall-through */
530 case SIDE_TYPE_U32
: /* Fall-through */
531 case SIDE_TYPE_U64
: /* Fall-through */
532 case SIDE_TYPE_S8
: /* Fall-through */
533 case SIDE_TYPE_S16
: /* Fall-through */
534 case SIDE_TYPE_S32
: /* Fall-through */
536 elem_type
= enum_elem_type
;
540 case SIDE_TYPE_ARRAY
:
541 elem_type
= side_ptr_get(enum_elem_type
->u
.side_array
.elem_type
);
542 array_item
= side_ptr_get(side_ptr_get(item
->u
.side_static
.side_array
)->sav
);
543 nr_items
= type_desc
->u
.side_array
.length
;
546 elem_type
= side_ptr_get(enum_elem_type
->u
.side_vla
.elem_type
);
547 array_item
= side_ptr_get(side_ptr_get(item
->u
.side_static
.side_vla
)->sav
);
548 nr_items
= side_ptr_get(item
->u
.side_static
.side_vla
)->len
;
551 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
554 stride_bit
= elem_type_to_stride(elem_type
);
556 print_attributes("attr", ":", side_ptr_get(side_enum_mappings
->attr
), side_enum_mappings
->nr_attr
);
557 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
558 printf("labels: [ ");
559 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
560 const struct side_enum_bitmap_mapping
*mapping
= &side_ptr_get(side_enum_mappings
->mappings
)[i
];
564 if (mapping
->range_end
< mapping
->range_begin
) {
565 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
566 mapping
->range_begin
, mapping
->range_end
);
569 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
570 if (bit
> (nr_items
* stride_bit
) - 1)
572 if (side_enum_get(elem_type
->type
) == SIDE_TYPE_BYTE
) {
573 uint8_t v
= array_item
[bit
/ 8].u
.side_static
.byte_value
;
574 if (v
& (1ULL << (bit
% 8))) {
579 union int64_value v64
;
581 v64
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
582 &array_item
[bit
/ stride_bit
].u
.side_static
.integer_value
,
584 if (v64
.u
& (1ULL << (bit
% stride_bit
))) {
592 printf("%s", print_count
++ ? ", " : "");
593 tracer_print_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
,
594 side_enum_get(mapping
->label
.byte_order
), NULL
);
598 printf("<NO LABEL>");
603 void print_integer_binary(uint64_t v
, int bits
)
609 for (i
= 0; i
< bits
; i
++) {
610 printf("%c", v
& (1ULL << 63) ? '1' : '0');
616 void tracer_print_type_header(const char *separator
,
617 const struct side_attr
*attr
, uint32_t nr_attr
)
619 print_attributes("attr", separator
, attr
, nr_attr
);
620 printf("%s", nr_attr
? ", " : "");
621 printf("value%s ", separator
);
625 void tracer_print_type_bool(const char *separator
,
626 const struct side_type_bool
*type_bool
,
627 const union side_bool_value
*value
,
628 uint16_t offset_bits
)
634 if (!type_bool
->len_bits
)
635 len_bits
= type_bool
->bool_size
* CHAR_BIT
;
637 len_bits
= type_bool
->len_bits
;
638 if (len_bits
+ offset_bits
> type_bool
->bool_size
* CHAR_BIT
)
640 reverse_bo
= side_enum_get(type_bool
->byte_order
) != SIDE_TYPE_BYTE_ORDER_HOST
;
641 switch (type_bool
->bool_size
) {
643 v
= value
->side_bool8
;
649 side_u16
= value
->side_bool16
;
651 side_u16
= side_bswap_16(side_u16
);
659 side_u32
= value
->side_bool32
;
661 side_u32
= side_bswap_32(side_u32
);
669 side_u64
= value
->side_bool64
;
671 side_u64
= side_bswap_64(side_u64
);
680 v
&= (1ULL << len_bits
) - 1;
681 tracer_print_type_header(separator
, side_ptr_get(type_bool
->attr
), type_bool
->nr_attr
);
682 printf("%s", v
? "true" : "false");
686 void tracer_print_type_integer(const char *separator
,
687 const struct side_type_integer
*type_integer
,
688 const union side_integer_value
*value
,
689 uint16_t offset_bits
,
690 enum tracer_display_base default_base
)
692 enum tracer_display_base base
;
693 union int64_value v64
;
696 v64
= tracer_load_integer_value(type_integer
, value
, offset_bits
, &len_bits
);
697 tracer_print_type_header(separator
, side_ptr_get(type_integer
->attr
), type_integer
->nr_attr
);
698 base
= get_attr_display_base(side_ptr_get(type_integer
->attr
), type_integer
->nr_attr
, default_base
);
700 case TRACER_DISPLAY_BASE_2
:
701 print_integer_binary(v64
.u
, len_bits
);
703 case TRACER_DISPLAY_BASE_8
:
704 /* Clear sign bits beyond len_bits */
706 v64
.u
&= (1ULL << len_bits
) - 1;
707 printf("0%" PRIo64
, v64
.u
);
709 case TRACER_DISPLAY_BASE_10
:
710 if (type_integer
->signedness
)
711 printf("%" PRId64
, v64
.s
);
713 printf("%" PRIu64
, v64
.u
);
715 case TRACER_DISPLAY_BASE_16
:
716 /* Clear sign bits beyond len_bits */
718 v64
.u
&= (1ULL << len_bits
) - 1;
719 printf("0x%" PRIx64
, v64
.u
);
727 void tracer_print_type_float(const char *separator
,
728 const struct side_type_float
*type_float
,
729 const union side_float_value
*value
)
733 tracer_print_type_header(separator
, side_ptr_get(type_float
->attr
), type_float
->nr_attr
);
734 reverse_bo
= side_enum_get(type_float
->byte_order
) != SIDE_TYPE_FLOAT_WORD_ORDER_HOST
;
735 switch (type_float
->float_size
) {
743 .f
= value
->side_float_binary16
,
747 float16
.u
= side_bswap_16(float16
.u
);
748 printf("%g", (double) float16
.f
);
751 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
762 .f
= value
->side_float_binary32
,
766 float32
.u
= side_bswap_32(float32
.u
);
767 printf("%g", (double) float32
.f
);
770 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
781 .f
= value
->side_float_binary64
,
785 float64
.u
= side_bswap_64(float64
.u
);
786 printf("%g", (double) float64
.f
);
789 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
800 .f
= value
->side_float_binary128
,
804 side_bswap_128p(float128
.arr
);
805 printf("%Lg", (long double) float128
.f
);
808 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
813 fprintf(stderr
, "ERROR: Unknown float size\n");
819 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
)
821 enum side_type_label type
;
823 switch (side_enum_get(type_desc
->type
)) {
825 switch (side_enum_get(item
->type
)) {
836 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
842 case SIDE_TYPE_ENUM_BITMAP
:
843 switch (side_enum_get(item
->type
)) {
849 case SIDE_TYPE_ARRAY
:
853 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
859 case SIDE_TYPE_GATHER_ENUM
:
860 switch (side_enum_get(item
->type
)) {
861 case SIDE_TYPE_GATHER_INTEGER
:
864 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
870 case SIDE_TYPE_DYNAMIC
:
871 switch (side_enum_get(item
->type
)) {
872 case SIDE_TYPE_DYNAMIC_NULL
:
873 case SIDE_TYPE_DYNAMIC_BOOL
:
874 case SIDE_TYPE_DYNAMIC_INTEGER
:
875 case SIDE_TYPE_DYNAMIC_BYTE
:
876 case SIDE_TYPE_DYNAMIC_POINTER
:
877 case SIDE_TYPE_DYNAMIC_FLOAT
:
878 case SIDE_TYPE_DYNAMIC_STRING
:
879 case SIDE_TYPE_DYNAMIC_STRUCT
:
880 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
881 case SIDE_TYPE_DYNAMIC_VLA
:
882 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
885 fprintf(stderr
, "ERROR: Unexpected dynamic type\n");
892 if (side_enum_get(type_desc
->type
) != side_enum_get(item
->type
)) {
893 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
899 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
)
900 type
= side_enum_get(type_desc
->type
);
902 type
= side_enum_get(item
->type
);
906 /* Stack-copy basic types */
908 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_null
.attr
),
909 type_desc
->u
.side_null
.nr_attr
);
910 printf("<NULL TYPE>");
914 tracer_print_type_bool(":", &type_desc
->u
.side_bool
, &item
->u
.side_static
.bool_value
, 0);
925 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
926 TRACER_DISPLAY_BASE_10
);
930 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_byte
.attr
), type_desc
->u
.side_byte
.nr_attr
);
931 printf("0x%" PRIx8
, item
->u
.side_static
.byte_value
);
934 case SIDE_TYPE_POINTER
:
935 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
936 TRACER_DISPLAY_BASE_16
);
939 case SIDE_TYPE_FLOAT_BINARY16
:
940 case SIDE_TYPE_FLOAT_BINARY32
:
941 case SIDE_TYPE_FLOAT_BINARY64
:
942 case SIDE_TYPE_FLOAT_BINARY128
:
943 tracer_print_type_float(":", &type_desc
->u
.side_float
, &item
->u
.side_static
.float_value
);
946 case SIDE_TYPE_STRING_UTF8
:
947 case SIDE_TYPE_STRING_UTF16
:
948 case SIDE_TYPE_STRING_UTF32
:
949 tracer_print_type_header(":", side_ptr_get(type_desc
->u
.side_string
.attr
), type_desc
->u
.side_string
.nr_attr
);
950 tracer_print_string(side_ptr_get(item
->u
.side_static
.string_value
),
951 type_desc
->u
.side_string
.unit_size
, side_enum_get(type_desc
->u
.side_string
.byte_order
), NULL
);
954 /* Stack-copy compound types */
955 case SIDE_TYPE_STRUCT
:
956 tracer_print_struct(type_desc
, side_ptr_get(item
->u
.side_static
.side_struct
));
958 case SIDE_TYPE_VARIANT
:
959 tracer_print_variant(type_desc
, side_ptr_get(item
->u
.side_static
.side_variant
));
961 case SIDE_TYPE_ARRAY
:
962 tracer_print_array(type_desc
, side_ptr_get(item
->u
.side_static
.side_array
));
965 tracer_print_vla(type_desc
, side_ptr_get(item
->u
.side_static
.side_vla
));
967 case SIDE_TYPE_VLA_VISITOR
:
968 tracer_print_vla_visitor(type_desc
, item
->u
.side_static
.side_vla_app_visitor_ctx
);
971 /* Stack-copy enumeration types */
973 tracer_print_enum(type_desc
, item
);
975 case SIDE_TYPE_ENUM_BITMAP
:
976 tracer_print_enum_bitmap(type_desc
, item
);
979 /* Gather basic types */
980 case SIDE_TYPE_GATHER_BOOL
:
981 (void) tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_bool_gather_ptr
));
983 case SIDE_TYPE_GATHER_INTEGER
:
984 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_integer_gather_ptr
),
985 TRACER_DISPLAY_BASE_10
);
987 case SIDE_TYPE_GATHER_BYTE
:
988 (void) tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_byte_gather_ptr
));
990 case SIDE_TYPE_GATHER_POINTER
:
991 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_integer_gather_ptr
),
992 TRACER_DISPLAY_BASE_16
);
994 case SIDE_TYPE_GATHER_FLOAT
:
995 (void) tracer_print_gather_float_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_float_gather_ptr
));
997 case SIDE_TYPE_GATHER_STRING
:
998 (void) tracer_print_gather_string_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_string_gather_ptr
));
1001 /* Gather compound type */
1002 case SIDE_TYPE_GATHER_STRUCT
:
1003 (void) tracer_print_gather_struct(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_struct_gather_ptr
));
1005 case SIDE_TYPE_GATHER_ARRAY
:
1006 (void) tracer_print_gather_array(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_array_gather_ptr
));
1008 case SIDE_TYPE_GATHER_VLA
:
1009 (void) tracer_print_gather_vla(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_vla_gather
.ptr
),
1010 side_ptr_get(item
->u
.side_static
.side_vla_gather
.length_ptr
));
1013 /* Gather enumeration types */
1014 case SIDE_TYPE_GATHER_ENUM
:
1015 (void) tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, side_ptr_get(item
->u
.side_static
.side_integer_gather_ptr
));
1018 /* Dynamic basic types */
1019 case SIDE_TYPE_DYNAMIC_NULL
:
1020 case SIDE_TYPE_DYNAMIC_BOOL
:
1021 case SIDE_TYPE_DYNAMIC_INTEGER
:
1022 case SIDE_TYPE_DYNAMIC_BYTE
:
1023 case SIDE_TYPE_DYNAMIC_POINTER
:
1024 case SIDE_TYPE_DYNAMIC_FLOAT
:
1025 case SIDE_TYPE_DYNAMIC_STRING
:
1027 /* Dynamic compound types */
1028 case SIDE_TYPE_DYNAMIC_STRUCT
:
1029 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1030 case SIDE_TYPE_DYNAMIC_VLA
:
1031 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1032 tracer_print_dynamic(item
);
1035 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1042 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg
*item
)
1044 printf("%s: ", side_ptr_get(item_desc
->field_name
));
1045 tracer_print_type(&item_desc
->side_type
, item
);
1049 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1051 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1052 const struct side_type_struct
*side_struct
= side_ptr_get(type_desc
->u
.side_struct
);
1053 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1055 if (side_struct
->nr_fields
!= side_sav_len
) {
1056 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
1059 print_attributes("attr", ":", side_ptr_get(side_struct
->attr
), side_struct
->nr_attr
);
1060 printf("%s", side_struct
->nr_attr
? ", " : "");
1061 printf("fields: { ");
1062 for (i
= 0; i
< side_sav_len
; i
++) {
1063 printf("%s", i
? ", " : "");
1064 tracer_print_field(&side_ptr_get(side_struct
->fields
)[i
], &sav
[i
]);
1070 void tracer_print_variant(const struct side_type
*type_desc
, const struct side_arg_variant
*side_arg_variant
)
1072 const struct side_type_variant
*side_type_variant
= side_ptr_get(type_desc
->u
.side_variant
);
1073 const struct side_type
*selector_type
= &side_type_variant
->selector
;
1074 union int64_value v64
;
1077 if (side_enum_get(selector_type
->type
) != side_enum_get(side_arg_variant
->selector
.type
)) {
1078 fprintf(stderr
, "ERROR: Unexpected variant selector type\n");
1081 switch (side_enum_get(selector_type
->type
)) {
1092 fprintf(stderr
, "ERROR: Expecting integer variant selector type\n");
1095 v64
= tracer_load_integer_value(&selector_type
->u
.side_integer
,
1096 &side_arg_variant
->selector
.u
.side_static
.integer_value
, 0, NULL
);
1097 for (i
= 0; i
< side_type_variant
->nr_options
; i
++) {
1098 const struct side_variant_option
*option
= &side_ptr_get(side_type_variant
->options
)[i
];
1100 if (v64
.s
>= option
->range_begin
&& v64
.s
<= option
->range_end
) {
1101 tracer_print_type(&option
->side_type
, &side_arg_variant
->option
);
1105 fprintf(stderr
, "ERROR: Variant selector value unknown %" PRId64
"\n", v64
.s
);
1110 void tracer_print_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1112 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1113 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1115 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
1116 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
1119 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_array
.attr
), type_desc
->u
.side_array
.nr_attr
);
1120 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1121 printf("elements: ");
1123 for (i
= 0; i
< side_sav_len
; i
++) {
1124 printf("%s", i
? ", " : "");
1125 tracer_print_type(side_ptr_get(type_desc
->u
.side_array
.elem_type
), &sav
[i
]);
1131 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1133 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1134 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1136 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_vla
.attr
), type_desc
->u
.side_vla
.nr_attr
);
1137 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1138 printf("elements: ");
1140 for (i
= 0; i
< side_sav_len
; i
++) {
1141 printf("%s", i
? ", " : "");
1142 tracer_print_type(side_ptr_get(type_desc
->u
.side_vla
.elem_type
), &sav
[i
]);
1148 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode
, const char *ptr
)
1150 switch (access_mode
) {
1151 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
1153 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1154 /* Dereference pointer */
1155 memcpy(&ptr
, ptr
, sizeof(const char *));
1163 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode
, uint32_t len
)
1165 switch (access_mode
) {
1166 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
1168 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1169 return sizeof(void *);
1176 union int64_value
tracer_load_gather_integer_value(const struct side_type_gather_integer
*side_integer
,
1179 enum side_type_gather_access_mode access_mode
=
1180 (enum side_type_gather_access_mode
) side_integer
->access_mode
;
1181 uint32_t integer_size_bytes
= side_integer
->type
.integer_size
;
1182 const char *ptr
= (const char *) _ptr
;
1183 union side_integer_value value
;
1185 ptr
= tracer_gather_access(access_mode
, ptr
+ side_integer
->offset
);
1186 memcpy(&value
, ptr
, integer_size_bytes
);
1187 return tracer_load_integer_value(&side_integer
->type
, &value
,
1188 side_integer
->offset_bits
, NULL
);
1192 uint32_t tracer_print_gather_bool_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1194 enum side_type_gather_access_mode access_mode
=
1195 (enum side_type_gather_access_mode
) type_gather
->u
.side_bool
.access_mode
;
1196 uint32_t bool_size_bytes
= type_gather
->u
.side_bool
.type
.bool_size
;
1197 const char *ptr
= (const char *) _ptr
;
1198 union side_bool_value value
;
1200 switch (bool_size_bytes
) {
1209 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_bool
.offset
);
1210 memcpy(&value
, ptr
, bool_size_bytes
);
1211 tracer_print_type_bool(":", &type_gather
->u
.side_bool
.type
, &value
,
1212 type_gather
->u
.side_bool
.offset_bits
);
1213 return tracer_gather_size(access_mode
, bool_size_bytes
);
1217 uint32_t tracer_print_gather_byte_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1219 enum side_type_gather_access_mode access_mode
=
1220 (enum side_type_gather_access_mode
) type_gather
->u
.side_byte
.access_mode
;
1221 const char *ptr
= (const char *) _ptr
;
1224 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_byte
.offset
);
1225 memcpy(&value
, ptr
, 1);
1226 tracer_print_type_header(":", side_ptr_get(type_gather
->u
.side_byte
.type
.attr
),
1227 type_gather
->u
.side_byte
.type
.nr_attr
);
1228 printf("0x%" PRIx8
, value
);
1229 return tracer_gather_size(access_mode
, 1);
1233 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
,
1234 enum tracer_display_base default_base
)
1236 enum side_type_gather_access_mode access_mode
=
1237 (enum side_type_gather_access_mode
) type_gather
->u
.side_integer
.access_mode
;
1238 uint32_t integer_size_bytes
= type_gather
->u
.side_integer
.type
.integer_size
;
1239 const char *ptr
= (const char *) _ptr
;
1240 union side_integer_value value
;
1242 switch (integer_size_bytes
) {
1251 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_integer
.offset
);
1252 memcpy(&value
, ptr
, integer_size_bytes
);
1253 tracer_print_type_integer(":", &type_gather
->u
.side_integer
.type
, &value
,
1254 type_gather
->u
.side_integer
.offset_bits
, default_base
);
1255 return tracer_gather_size(access_mode
, integer_size_bytes
);
1259 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1261 enum side_type_gather_access_mode access_mode
=
1262 (enum side_type_gather_access_mode
) type_gather
->u
.side_float
.access_mode
;
1263 uint32_t float_size_bytes
= type_gather
->u
.side_float
.type
.float_size
;
1264 const char *ptr
= (const char *) _ptr
;
1265 union side_float_value value
;
1267 switch (float_size_bytes
) {
1276 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_float
.offset
);
1277 memcpy(&value
, ptr
, float_size_bytes
);
1278 tracer_print_type_float(":", &type_gather
->u
.side_float
.type
, &value
);
1279 return tracer_gather_size(access_mode
, float_size_bytes
);
1283 uint32_t tracer_print_gather_string_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1285 enum side_type_gather_access_mode access_mode
=
1286 (enum side_type_gather_access_mode
) type_gather
->u
.side_string
.access_mode
;
1287 const char *ptr
= (const char *) _ptr
;
1290 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_string
.offset
);
1291 tracer_print_type_header(":", side_ptr_get(type_gather
->u
.side_string
.type
.attr
),
1292 type_gather
->u
.side_string
.type
.nr_attr
);
1294 tracer_print_string(ptr
, type_gather
->u
.side_string
.type
.unit_size
,
1295 side_enum_get(type_gather
->u
.side_string
.type
.byte_order
), &string_len
);
1298 string_len
= type_gather
->u
.side_string
.type
.unit_size
;
1300 return tracer_gather_size(access_mode
, string_len
);
1304 uint32_t tracer_print_gather_type(const struct side_type
*type_desc
, const void *ptr
)
1309 switch (side_enum_get(type_desc
->type
)) {
1310 /* Gather basic types */
1311 case SIDE_TYPE_GATHER_BOOL
:
1312 len
= tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, ptr
);
1314 case SIDE_TYPE_GATHER_INTEGER
:
1315 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
,
1316 TRACER_DISPLAY_BASE_10
);
1318 case SIDE_TYPE_GATHER_BYTE
:
1319 len
= tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, ptr
);
1321 case SIDE_TYPE_GATHER_POINTER
:
1322 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
,
1323 TRACER_DISPLAY_BASE_16
);
1325 case SIDE_TYPE_GATHER_FLOAT
:
1326 len
= tracer_print_gather_float_type(&type_desc
->u
.side_gather
, ptr
);
1328 case SIDE_TYPE_GATHER_STRING
:
1329 len
= tracer_print_gather_string_type(&type_desc
->u
.side_gather
, ptr
);
1332 /* Gather enum types */
1333 case SIDE_TYPE_GATHER_ENUM
:
1334 len
= tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, ptr
);
1337 /* Gather compound types */
1338 case SIDE_TYPE_GATHER_STRUCT
:
1339 len
= tracer_print_gather_struct(&type_desc
->u
.side_gather
, ptr
);
1341 case SIDE_TYPE_GATHER_ARRAY
:
1342 len
= tracer_print_gather_array(&type_desc
->u
.side_gather
, ptr
);
1344 case SIDE_TYPE_GATHER_VLA
:
1345 len
= tracer_print_gather_vla(&type_desc
->u
.side_gather
, ptr
, ptr
);
1348 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
1356 uint32_t tracer_print_gather_enum_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1358 const struct side_enum_mappings
*mappings
= side_ptr_get(type_gather
->u
.side_enum
.mappings
);
1359 const struct side_type
*enum_elem_type
= side_ptr_get(type_gather
->u
.side_enum
.elem_type
);
1360 const struct side_type_gather_integer
*side_integer
= &enum_elem_type
->u
.side_gather
.u
.side_integer
;
1361 enum side_type_gather_access_mode access_mode
=
1362 (enum side_type_gather_access_mode
) side_integer
->access_mode
;
1363 uint32_t integer_size_bytes
= side_integer
->type
.integer_size
;
1364 const char *ptr
= (const char *) _ptr
;
1365 union side_integer_value value
;
1366 union int64_value v64
;
1368 switch (integer_size_bytes
) {
1377 ptr
= tracer_gather_access(access_mode
, ptr
+ side_integer
->offset
);
1378 memcpy(&value
, ptr
, integer_size_bytes
);
1379 v64
= tracer_load_gather_integer_value(side_integer
, &value
);
1380 print_attributes("attr", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
1381 printf("%s", mappings
->nr_attr
? ", " : "");
1382 tracer_print_gather_type(enum_elem_type
, ptr
);
1383 print_enum_labels(mappings
, v64
);
1384 return tracer_gather_size(access_mode
, integer_size_bytes
);
1388 void tracer_print_gather_field(const struct side_event_field
*field
, const void *ptr
)
1390 printf("%s: ", side_ptr_get(field
->field_name
));
1391 (void) tracer_print_gather_type(&field
->side_type
, ptr
);
1395 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
)
1397 enum side_type_gather_access_mode access_mode
=
1398 (enum side_type_gather_access_mode
) type_gather
->u
.side_struct
.access_mode
;
1399 const struct side_type_struct
*side_struct
= side_ptr_get(type_gather
->u
.side_struct
.type
);
1400 const char *ptr
= (const char *) _ptr
;
1403 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_struct
.offset
);
1404 print_attributes("attr", ":", side_ptr_get(side_struct
->attr
), side_struct
->nr_attr
);
1405 printf("%s", side_struct
->nr_attr
? ", " : "");
1406 printf("fields: { ");
1407 for (i
= 0; i
< side_struct
->nr_fields
; i
++) {
1408 printf("%s", i
? ", " : "");
1409 tracer_print_gather_field(&side_ptr_get(side_struct
->fields
)[i
], ptr
);
1412 return tracer_gather_size(access_mode
, type_gather
->u
.side_struct
.size
);
1416 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
)
1418 enum side_type_gather_access_mode access_mode
=
1419 (enum side_type_gather_access_mode
) type_gather
->u
.side_array
.access_mode
;
1420 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1423 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_array
.offset
);
1425 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_array
.type
.attr
), type_gather
->u
.side_array
.type
.nr_attr
);
1426 printf("%s", type_gather
->u
.side_array
.type
.nr_attr
? ", " : "");
1427 printf("elements: ");
1429 for (i
= 0; i
< type_gather
->u
.side_array
.type
.length
; i
++) {
1430 const struct side_type
*elem_type
= side_ptr_get(type_gather
->u
.side_array
.type
.elem_type
);
1432 switch (side_enum_get(elem_type
->type
)) {
1433 case SIDE_TYPE_GATHER_VLA
:
1434 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1439 printf("%s", i
? ", " : "");
1440 ptr
+= tracer_print_gather_type(elem_type
, ptr
);
1443 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1447 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
,
1448 const void *_length_ptr
)
1450 enum side_type_gather_access_mode access_mode
=
1451 (enum side_type_gather_access_mode
) type_gather
->u
.side_vla
.access_mode
;
1452 const struct side_type
*length_type
= side_ptr_get(type_gather
->u
.side_vla
.length_type
);
1453 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1454 const char *length_ptr
= (const char *) _length_ptr
;
1455 union int64_value v64
;
1459 switch (side_enum_get(length_type
->type
)) {
1460 case SIDE_TYPE_GATHER_INTEGER
:
1463 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
1466 v64
= tracer_load_gather_integer_value(&length_type
->u
.side_gather
.u
.side_integer
,
1468 length
= (uint32_t) v64
.u
;
1469 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_vla
.offset
);
1471 print_attributes("attr", ":", side_ptr_get(type_gather
->u
.side_vla
.type
.attr
), type_gather
->u
.side_vla
.type
.nr_attr
);
1472 printf("%s", type_gather
->u
.side_vla
.type
.nr_attr
? ", " : "");
1473 printf("elements: ");
1475 for (i
= 0; i
< length
; i
++) {
1476 const struct side_type
*elem_type
= side_ptr_get(type_gather
->u
.side_vla
.type
.elem_type
);
1478 switch (side_enum_get(elem_type
->type
)) {
1479 case SIDE_TYPE_GATHER_VLA
:
1480 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1485 printf("%s", i
? ", " : "");
1486 ptr
+= tracer_print_gather_type(elem_type
, ptr
);
1489 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1492 struct tracer_visitor_priv
{
1493 const struct side_type
*elem_type
;
1498 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1499 const struct side_arg
*elem
)
1501 struct tracer_visitor_priv
*tracer_priv
= (struct tracer_visitor_priv
*) tracer_ctx
->priv
;
1503 printf("%s", tracer_priv
->i
++ ? ", " : "");
1504 tracer_print_type(tracer_priv
->elem_type
, elem
);
1505 return SIDE_VISITOR_STATUS_OK
;
1509 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
)
1511 enum side_visitor_status status
;
1512 struct tracer_visitor_priv tracer_priv
= {
1513 .elem_type
= side_ptr_get(type_desc
->u
.side_vla_visitor
.elem_type
),
1516 const struct side_tracer_visitor_ctx tracer_ctx
= {
1517 .write_elem
= tracer_write_elem_cb
,
1518 .priv
= &tracer_priv
,
1520 side_visitor_func func
;
1522 print_attributes("attr", ":", side_ptr_get(type_desc
->u
.side_vla_visitor
.attr
), type_desc
->u
.side_vla_visitor
.nr_attr
);
1523 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1524 printf("elements: ");
1526 func
= side_ptr_get(type_desc
->u
.side_vla_visitor
.visitor
);
1527 status
= func(&tracer_ctx
, app_ctx
);
1529 case SIDE_VISITOR_STATUS_OK
:
1531 case SIDE_VISITOR_STATUS_ERROR
:
1532 fprintf(stderr
, "ERROR: Visitor error\n");
1539 void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
)
1541 const struct side_arg_dynamic_field
*fields
= side_ptr_get(dynamic_struct
->fields
);
1542 uint32_t i
, len
= dynamic_struct
->len
;
1544 print_attributes("attr", "::", side_ptr_get(dynamic_struct
->attr
), dynamic_struct
->nr_attr
);
1545 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1546 printf("fields:: ");
1548 for (i
= 0; i
< len
; i
++) {
1549 printf("%s", i
? ", " : "");
1550 printf("%s:: ", side_ptr_get(fields
[i
].field_name
));
1551 tracer_print_dynamic(&fields
[i
].elem
);
1556 struct tracer_dynamic_struct_visitor_priv
{
1561 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1562 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1563 const struct side_arg_dynamic_field
*dynamic_field
)
1565 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
=
1566 (struct tracer_dynamic_struct_visitor_priv
*) tracer_ctx
->priv
;
1568 printf("%s", tracer_priv
->i
++ ? ", " : "");
1569 printf("%s:: ", side_ptr_get(dynamic_field
->field_name
));
1570 tracer_print_dynamic(&dynamic_field
->elem
);
1571 return SIDE_VISITOR_STATUS_OK
;
1575 void tracer_print_dynamic_struct_visitor(const struct side_arg
*item
)
1577 enum side_visitor_status status
;
1578 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1581 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1582 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1583 .priv
= &tracer_priv
,
1585 void *app_ctx
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct_visitor
.app_ctx
);
1587 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
);
1588 printf("%s", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1589 printf("fields:: ");
1591 status
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct_visitor
.visitor
)(&tracer_ctx
, app_ctx
);
1593 case SIDE_VISITOR_STATUS_OK
:
1595 case SIDE_VISITOR_STATUS_ERROR
:
1596 fprintf(stderr
, "ERROR: Visitor error\n");
1603 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla
*vla
)
1605 const struct side_arg
*sav
= side_ptr_get(vla
->sav
);
1606 uint32_t i
, side_sav_len
= vla
->len
;
1608 print_attributes("attr", "::", side_ptr_get(vla
->attr
), vla
->nr_attr
);
1609 printf("%s", vla
->nr_attr
? ", " : "");
1610 printf("elements:: ");
1612 for (i
= 0; i
< side_sav_len
; i
++) {
1613 printf("%s", i
? ", " : "");
1614 tracer_print_dynamic(&sav
[i
]);
1619 struct tracer_dynamic_vla_visitor_priv
{
1624 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1625 const struct side_tracer_visitor_ctx
*tracer_ctx
,
1626 const struct side_arg
*elem
)
1628 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
=
1629 (struct tracer_dynamic_vla_visitor_priv
*) tracer_ctx
->priv
;
1631 printf("%s", tracer_priv
->i
++ ? ", " : "");
1632 tracer_print_dynamic(elem
);
1633 return SIDE_VISITOR_STATUS_OK
;
1637 void tracer_print_dynamic_vla_visitor(const struct side_arg
*item
)
1639 enum side_visitor_status status
;
1640 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1643 const struct side_tracer_visitor_ctx tracer_ctx
= {
1644 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1645 .priv
= &tracer_priv
,
1647 void *app_ctx
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla_visitor
.app_ctx
);
1649 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
);
1650 printf("%s", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1651 printf("elements:: ");
1653 status
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla_visitor
.visitor
)(&tracer_ctx
, app_ctx
);
1655 case SIDE_VISITOR_STATUS_OK
:
1657 case SIDE_VISITOR_STATUS_ERROR
:
1658 fprintf(stderr
, "ERROR: Visitor error\n");
1665 void tracer_print_dynamic(const struct side_arg
*item
)
1668 switch (side_enum_get(item
->type
)) {
1669 /* Dynamic basic types */
1670 case SIDE_TYPE_DYNAMIC_NULL
:
1671 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_null
.attr
),
1672 item
->u
.side_dynamic
.side_null
.nr_attr
);
1673 printf("<NULL TYPE>");
1675 case SIDE_TYPE_DYNAMIC_BOOL
:
1676 tracer_print_type_bool("::", &item
->u
.side_dynamic
.side_bool
.type
, &item
->u
.side_dynamic
.side_bool
.value
, 0);
1678 case SIDE_TYPE_DYNAMIC_INTEGER
:
1679 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1680 TRACER_DISPLAY_BASE_10
);
1682 case SIDE_TYPE_DYNAMIC_BYTE
:
1683 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_byte
.type
.attr
), item
->u
.side_dynamic
.side_byte
.type
.nr_attr
);
1684 printf("0x%" PRIx8
, item
->u
.side_dynamic
.side_byte
.value
);
1686 case SIDE_TYPE_DYNAMIC_POINTER
:
1687 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1688 TRACER_DISPLAY_BASE_16
);
1690 case SIDE_TYPE_DYNAMIC_FLOAT
:
1691 tracer_print_type_float("::", &item
->u
.side_dynamic
.side_float
.type
,
1692 &item
->u
.side_dynamic
.side_float
.value
);
1694 case SIDE_TYPE_DYNAMIC_STRING
:
1695 tracer_print_type_header("::", side_ptr_get(item
->u
.side_dynamic
.side_string
.type
.attr
), item
->u
.side_dynamic
.side_string
.type
.nr_attr
);
1696 tracer_print_string((const char *)(uintptr_t) item
->u
.side_dynamic
.side_string
.value
,
1697 item
->u
.side_dynamic
.side_string
.type
.unit_size
,
1698 side_enum_get(item
->u
.side_dynamic
.side_string
.type
.byte_order
), NULL
);
1701 /* Dynamic compound types */
1702 case SIDE_TYPE_DYNAMIC_STRUCT
:
1703 tracer_print_dynamic_struct(side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct
));
1705 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1706 tracer_print_dynamic_struct_visitor(item
);
1708 case SIDE_TYPE_DYNAMIC_VLA
:
1709 tracer_print_dynamic_vla(side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla
));
1711 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1712 tracer_print_dynamic_vla_visitor(item
);
1715 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1722 void tracer_print_static_fields(const struct side_event_description
*desc
,
1723 const struct side_arg_vec
*side_arg_vec
,
1726 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1727 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1729 printf("provider: %s, event: %s", side_ptr_get(desc
->provider_name
), side_ptr_get(desc
->event_name
));
1730 if (desc
->nr_fields
!= side_sav_len
) {
1731 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1734 print_attributes(", attr", ":", side_ptr_get(desc
->attr
), desc
->nr_attr
);
1735 printf("%s", side_sav_len
? ", fields: [ " : "");
1736 for (i
= 0; i
< side_sav_len
; i
++) {
1737 printf("%s", i
? ", " : "");
1738 tracer_print_field(&side_ptr_get(desc
->fields
)[i
], &sav
[i
]);
1747 void tracer_call(const struct side_event_description
*desc
,
1748 const struct side_arg_vec
*side_arg_vec
,
1749 void *priv
__attribute__((unused
)))
1751 uint32_t nr_fields
= 0;
1753 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1758 void tracer_call_variadic(const struct side_event_description
*desc
,
1759 const struct side_arg_vec
*side_arg_vec
,
1760 const struct side_arg_dynamic_struct
*var_struct
,
1761 void *priv
__attribute__((unused
)))
1763 uint32_t nr_fields
= 0, i
, var_struct_len
= var_struct
->len
;
1765 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1767 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1768 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1771 print_attributes(", attr ", "::", side_ptr_get(var_struct
->attr
), var_struct
->nr_attr
);
1772 printf("%s", var_struct_len
? ", fields:: [ " : "");
1773 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1774 printf("%s", i
? ", " : "");
1775 printf("%s:: ", side_ptr_get(side_ptr_get(var_struct
->fields
)[i
].field_name
));
1776 tracer_print_dynamic(&side_ptr_get(var_struct
->fields
)[i
].elem
);
1784 void tracer_event_notification(enum side_tracer_notification notif
,
1785 struct side_event_description
**events
, uint32_t nr_events
,
1786 void *priv
__attribute__((unused
)))
1791 printf("----------------------------------------------------------\n");
1792 printf("Tracer notified of events %s\n",
1793 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1794 for (i
= 0; i
< nr_events
; i
++) {
1795 struct side_event_description
*event
= events
[i
];
1797 /* Skip NULL pointers */
1800 if (event
->version
!= SIDE_ABI_VERSION
) {
1801 printf("Error: event SIDE ABI version (%u) does not match the SIDE ABI version supported by the tracer (%u)\n",
1802 event
->version
, SIDE_ABI_VERSION
);
1805 printf("provider: %s, event: %s\n",
1806 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
));
1807 if (event
->struct_size
!= side_offsetofend(struct side_event_description
, side_event_description_orig_abi_last
)) {
1808 printf("Warning: Event %s.%s contains fields unknown to the tracer\n",
1809 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
));
1811 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1812 if (event
->nr_side_type_label
> _NR_SIDE_TYPE_LABEL
) {
1813 printf("Warning: event %s:%s may contain unknown field types (%u unknown types)\n",
1814 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
),
1815 event
->nr_side_type_label
- _NR_SIDE_TYPE_LABEL
);
1817 if (event
->nr_side_attr_type
> _NR_SIDE_ATTR_TYPE
) {
1818 printf("Warning: event %s:%s may contain unknown attribute types (%u unknown types)\n",
1819 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
),
1820 event
->nr_side_attr_type
- _NR_SIDE_ATTR_TYPE
);
1822 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1823 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1827 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1832 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1833 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1837 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1843 printf("----------------------------------------------------------\n");
1846 static __attribute__((constructor
))
1847 void tracer_init(void);
1849 void tracer_init(void)
1851 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1856 static __attribute__((destructor
))
1857 void tracer_exit(void);
1859 void tracer_exit(void)
1861 side_tracer_event_notification_unregister(tracer_handle
);