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_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
35 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
);
37 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
);
39 void tracer_print_dynamic(const struct side_arg
*dynamic_item
);
41 uint32_t tracer_print_gather_bool_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
43 uint32_t tracer_print_gather_byte_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
45 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
,
46 enum tracer_display_base default_base
);
48 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
50 uint32_t tracer_print_gather_string_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
52 uint32_t tracer_print_gather_enum_type(const struct side_type_gather
*type_gather
, const void *_ptr
);
54 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
);
56 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
);
58 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
,
59 const void *_length_ptr
);
61 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
);
64 void tracer_print_string(const void *p
, uint8_t unit_size
, enum side_type_label_byte_order byte_order
,
65 size_t *strlen_with_null
)
67 size_t ret
, inbytesleft
= 0, outbytesleft
, bufsize
;
68 const char *str
= p
, *fromcode
;
69 char *inbuf
= (char *) p
, *outbuf
, *buf
;
74 printf("\"%s\"", str
);
76 *strlen_with_null
= strlen(str
) + 1;
80 const uint16_t *p16
= p
;
83 case SIDE_TYPE_BYTE_ORDER_LE
:
85 fromcode
= "UTF-16LE";
88 case SIDE_TYPE_BYTE_ORDER_BE
:
90 fromcode
= "UTF-16BE";
94 fprintf(stderr
, "Unknown byte order\n");
100 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
101 * { ef, bf, bf } UTF-8 (3 bytes).
103 bufsize
= inbytesleft
/ 2 * 3 + 1;
108 const uint32_t *p32
= p
;
110 switch (byte_order
) {
111 case SIDE_TYPE_BYTE_ORDER_LE
:
113 fromcode
= "UTF-32LE";
116 case SIDE_TYPE_BYTE_ORDER_BE
:
118 fromcode
= "UTF-32BE";
122 fprintf(stderr
, "Unknown byte order\n");
128 * Each 4-byte UTF-32 character converts to at most a
129 * 4-byte UTF-8 character.
131 bufsize
= inbytesleft
+ 1;
135 fprintf(stderr
, "Unknown string unit size %" PRIu8
"\n", unit_size
);
139 cd
= iconv_open("UTF8", fromcode
);
140 if (cd
== (iconv_t
) -1) {
141 perror("iconv_open");
144 buf
= malloc(bufsize
);
148 outbuf
= (char *) buf
;
149 outbytesleft
= bufsize
;
150 ret
= iconv(cd
, &inbuf
, &inbytesleft
, &outbuf
, &outbytesleft
);
151 if (ret
== (size_t) -1) {
156 fprintf(stderr
, "Buffer too small to convert string input\n");
160 if (strlen_with_null
)
161 *strlen_with_null
= outbuf
- buf
;
162 printf("\"%s\"", buf
);
164 if (iconv_close(cd
) == -1) {
165 perror("iconv_close");
171 int64_t get_attr_integer_value(const struct side_attr
*attr
)
175 switch (attr
->value
.type
) {
176 case SIDE_ATTR_TYPE_U8
:
177 val
= attr
->value
.u
.integer_value
.side_u8
;
179 case SIDE_ATTR_TYPE_U16
:
180 val
= attr
->value
.u
.integer_value
.side_u16
;
182 case SIDE_ATTR_TYPE_U32
:
183 val
= attr
->value
.u
.integer_value
.side_u32
;
185 case SIDE_ATTR_TYPE_U64
:
186 val
= attr
->value
.u
.integer_value
.side_u64
;
188 case SIDE_ATTR_TYPE_S8
:
189 val
= attr
->value
.u
.integer_value
.side_s8
;
191 case SIDE_ATTR_TYPE_S16
:
192 val
= attr
->value
.u
.integer_value
.side_s16
;
194 case SIDE_ATTR_TYPE_S32
:
195 val
= attr
->value
.u
.integer_value
.side_s32
;
197 case SIDE_ATTR_TYPE_S64
:
198 val
= attr
->value
.u
.integer_value
.side_s64
;
201 fprintf(stderr
, "Unexpected attribute type\n");
208 enum tracer_display_base
get_attr_display_base(const struct side_attr
*_attr
, uint32_t nr_attr
,
209 enum tracer_display_base default_base
)
213 for (i
= 0; i
< nr_attr
; i
++) {
214 const struct side_attr
*attr
= &_attr
[i
];
216 if (!strcmp(attr
->key
, "std.integer.base")) {
217 int64_t val
= get_attr_integer_value(attr
);
221 return TRACER_DISPLAY_BASE_2
;
223 return TRACER_DISPLAY_BASE_8
;
225 return TRACER_DISPLAY_BASE_10
;
227 return TRACER_DISPLAY_BASE_16
;
229 fprintf(stderr
, "Unexpected integer display base: %" PRId64
"\n", val
);
234 return default_base
; /* Default */
238 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
240 printf("{ key%s \"%s\", value%s ", separator
, attr
->key
, separator
);
241 switch (attr
->value
.type
) {
242 case SIDE_ATTR_TYPE_BOOL
:
243 printf("%s", attr
->value
.u
.bool_value
? "true" : "false");
245 case SIDE_ATTR_TYPE_U8
:
246 printf("%" PRIu8
, attr
->value
.u
.integer_value
.side_u8
);
248 case SIDE_ATTR_TYPE_U16
:
249 printf("%" PRIu16
, attr
->value
.u
.integer_value
.side_u16
);
251 case SIDE_ATTR_TYPE_U32
:
252 printf("%" PRIu32
, attr
->value
.u
.integer_value
.side_u32
);
254 case SIDE_ATTR_TYPE_U64
:
255 printf("%" PRIu64
, attr
->value
.u
.integer_value
.side_u64
);
257 case SIDE_ATTR_TYPE_S8
:
258 printf("%" PRId8
, attr
->value
.u
.integer_value
.side_s8
);
260 case SIDE_ATTR_TYPE_S16
:
261 printf("%" PRId16
, attr
->value
.u
.integer_value
.side_s16
);
263 case SIDE_ATTR_TYPE_S32
:
264 printf("%" PRId32
, attr
->value
.u
.integer_value
.side_s32
);
266 case SIDE_ATTR_TYPE_S64
:
267 printf("%" PRId64
, attr
->value
.u
.integer_value
.side_s64
);
269 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
271 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary16
);
274 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
277 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
279 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary32
);
282 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
285 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
287 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary64
);
290 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
293 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
295 printf("%Lg", (long double) attr
->value
.u
.float_value
.side_float_binary128
);
298 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
301 case SIDE_ATTR_TYPE_STRING_UTF8
:
302 tracer_print_string((const void *)(uintptr_t) attr
->value
.u
.string_value
,
303 1, SIDE_TYPE_BYTE_ORDER_HOST
, NULL
);
305 case SIDE_ATTR_TYPE_STRING_UTF16
:
306 tracer_print_string((const void *)(uintptr_t) attr
->value
.u
.string_value
,
307 2, SIDE_TYPE_BYTE_ORDER_HOST
, NULL
);
309 case SIDE_ATTR_TYPE_STRING_UTF32
:
310 tracer_print_string((const void *)(uintptr_t) attr
->value
.u
.string_value
,
311 4, SIDE_TYPE_BYTE_ORDER_HOST
, NULL
);
314 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
321 void print_attributes(const char *prefix_str
, const char *separator
,
322 const struct side_attr
*attr
, uint32_t nr_attr
)
328 printf("%s%s [ ", prefix_str
, separator
);
329 for (i
= 0; i
< nr_attr
; i
++) {
330 printf("%s", i
? ", " : "");
331 tracer_print_attr_type(separator
, &attr
[i
]);
337 union int64_value
tracer_load_integer_value(const struct side_type_integer
*type_integer
,
338 const union side_integer_value
*value
,
339 uint16_t offset_bits
, uint16_t *_len_bits
)
341 union int64_value v64
;
345 if (!type_integer
->len_bits
)
346 len_bits
= type_integer
->integer_size
* CHAR_BIT
;
348 len_bits
= type_integer
->len_bits
;
349 if (len_bits
+ offset_bits
> type_integer
->integer_size
* CHAR_BIT
)
351 reverse_bo
= type_integer
->byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
;
352 switch (type_integer
->integer_size
) {
354 if (type_integer
->signedness
)
355 v64
.s
= value
->side_s8
;
357 v64
.u
= value
->side_u8
;
360 if (type_integer
->signedness
) {
363 side_s16
= value
->side_s16
;
365 side_s16
= side_bswap_16(side_s16
);
370 side_u16
= value
->side_u16
;
372 side_u16
= side_bswap_16(side_u16
);
377 if (type_integer
->signedness
) {
380 side_s32
= value
->side_s32
;
382 side_s32
= side_bswap_32(side_s32
);
387 side_u32
= value
->side_u32
;
389 side_u32
= side_bswap_32(side_u32
);
394 if (type_integer
->signedness
) {
397 side_s64
= value
->side_s64
;
399 side_s64
= side_bswap_64(side_s64
);
404 side_u64
= value
->side_u64
;
406 side_u64
= side_bswap_64(side_u64
);
413 v64
.u
>>= offset_bits
;
415 v64
.u
&= (1ULL << len_bits
) - 1;
416 if (type_integer
->signedness
) {
418 if (v64
.u
& (1ULL << (len_bits
- 1)))
419 v64
.u
|= ~((1ULL << len_bits
) - 1);
423 *_len_bits
= len_bits
;
428 void print_enum_labels(const struct side_enum_mappings
*mappings
, union int64_value v64
)
430 uint32_t i
, print_count
= 0;
432 printf(", labels: [ ");
433 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
434 const struct side_enum_mapping
*mapping
= &mappings
->mappings
[i
];
436 if (mapping
->range_end
< mapping
->range_begin
) {
437 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
438 mapping
->range_begin
, mapping
->range_end
);
441 if (v64
.s
>= mapping
->range_begin
&& v64
.s
<= mapping
->range_end
) {
442 printf("%s", print_count
++ ? ", " : "");
443 printf("\"%s\"", mapping
->label
);
447 printf("<NO LABEL>");
452 void tracer_print_enum(const struct side_type
*type_desc
, const struct side_arg
*item
)
454 const struct side_enum_mappings
*mappings
= type_desc
->u
.side_enum
.mappings
;
455 const struct side_type
*elem_type
= type_desc
->u
.side_enum
.elem_type
;
456 union int64_value v64
;
458 if (elem_type
->type
!= item
->type
) {
459 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
462 v64
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
463 &item
->u
.side_static
.integer_value
, 0, NULL
);
464 print_attributes("attr", ":", mappings
->attr
, mappings
->nr_attr
);
465 printf("%s", mappings
->nr_attr
? ", " : "");
466 tracer_print_type(elem_type
, item
);
467 print_enum_labels(mappings
, v64
);
471 uint32_t elem_type_to_stride(const struct side_type
*elem_type
)
475 switch (elem_type
->type
) {
488 return elem_type
->u
.side_integer
.integer_size
* CHAR_BIT
;
490 fprintf(stderr
, "ERROR: Unexpected enum bitmap element type\n");
497 void tracer_print_enum_bitmap(const struct side_type
*type_desc
,
498 const struct side_arg
*item
)
500 const struct side_enum_bitmap_mappings
*side_enum_mappings
= type_desc
->u
.side_enum_bitmap
.mappings
;
501 const struct side_type
*enum_elem_type
= type_desc
->u
.side_enum_bitmap
.elem_type
, *elem_type
;
502 uint32_t i
, print_count
= 0, stride_bit
, nr_items
;
503 const struct side_arg
*array_item
;
505 switch (enum_elem_type
->type
) {
506 case SIDE_TYPE_U8
: /* Fall-through */
507 case SIDE_TYPE_BYTE
: /* Fall-through */
508 case SIDE_TYPE_U16
: /* Fall-through */
509 case SIDE_TYPE_U32
: /* Fall-through */
510 case SIDE_TYPE_U64
: /* Fall-through */
511 case SIDE_TYPE_S8
: /* Fall-through */
512 case SIDE_TYPE_S16
: /* Fall-through */
513 case SIDE_TYPE_S32
: /* Fall-through */
515 elem_type
= enum_elem_type
;
519 case SIDE_TYPE_ARRAY
:
520 elem_type
= enum_elem_type
->u
.side_array
.elem_type
;
521 array_item
= item
->u
.side_static
.side_array
->sav
;
522 nr_items
= type_desc
->u
.side_array
.length
;
525 elem_type
= enum_elem_type
->u
.side_vla
.elem_type
;
526 array_item
= item
->u
.side_static
.side_vla
->sav
;
527 nr_items
= item
->u
.side_static
.side_vla
->len
;
530 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
533 stride_bit
= elem_type_to_stride(elem_type
);
535 print_attributes("attr", ":", side_enum_mappings
->attr
, side_enum_mappings
->nr_attr
);
536 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
537 printf("labels: [ ");
538 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
539 const struct side_enum_bitmap_mapping
*mapping
= &side_enum_mappings
->mappings
[i
];
543 if (mapping
->range_end
< mapping
->range_begin
) {
544 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
545 mapping
->range_begin
, mapping
->range_end
);
548 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
549 if (bit
> (nr_items
* stride_bit
) - 1)
551 if (elem_type
->type
== SIDE_TYPE_BYTE
) {
552 uint8_t v
= array_item
[bit
/ 8].u
.side_static
.byte_value
;
553 if (v
& (1ULL << (bit
% 8))) {
558 union int64_value v64
;
560 v64
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
561 &array_item
[bit
/ stride_bit
].u
.side_static
.integer_value
,
563 if (v64
.u
& (1ULL << (bit
% stride_bit
))) {
571 printf("%s", print_count
++ ? ", " : "");
572 printf("\"%s\"", mapping
->label
);
576 printf("<NO LABEL>");
581 void print_integer_binary(uint64_t v
, int bits
)
587 for (i
= 0; i
< bits
; i
++) {
588 printf("%c", v
& (1ULL << 63) ? '1' : '0');
594 void tracer_print_type_header(const char *separator
,
595 const struct side_attr
*attr
, uint32_t nr_attr
)
597 print_attributes("attr", separator
, attr
, nr_attr
);
598 printf("%s", nr_attr
? ", " : "");
599 printf("value%s ", separator
);
603 void tracer_print_type_bool(const char *separator
,
604 const struct side_type_bool
*type_bool
,
605 const union side_bool_value
*value
,
606 uint16_t offset_bits
)
612 if (!type_bool
->len_bits
)
613 len_bits
= type_bool
->bool_size
* CHAR_BIT
;
615 len_bits
= type_bool
->len_bits
;
616 if (len_bits
+ offset_bits
> type_bool
->bool_size
* CHAR_BIT
)
618 reverse_bo
= type_bool
->byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
;
619 switch (type_bool
->bool_size
) {
621 v
= value
->side_bool8
;
627 side_u16
= value
->side_bool16
;
629 side_u16
= side_bswap_16(side_u16
);
637 side_u32
= value
->side_bool32
;
639 side_u32
= side_bswap_32(side_u32
);
647 side_u64
= value
->side_bool64
;
649 side_u64
= side_bswap_64(side_u64
);
658 v
&= (1ULL << len_bits
) - 1;
659 tracer_print_type_header(separator
, type_bool
->attr
, type_bool
->nr_attr
);
660 printf("%s", v
? "true" : "false");
664 void tracer_print_type_integer(const char *separator
,
665 const struct side_type_integer
*type_integer
,
666 const union side_integer_value
*value
,
667 uint16_t offset_bits
,
668 enum tracer_display_base default_base
)
670 enum tracer_display_base base
;
671 union int64_value v64
;
674 v64
= tracer_load_integer_value(type_integer
, value
, offset_bits
, &len_bits
);
675 tracer_print_type_header(separator
, type_integer
->attr
, type_integer
->nr_attr
);
676 base
= get_attr_display_base(type_integer
->attr
, type_integer
->nr_attr
, default_base
);
678 case TRACER_DISPLAY_BASE_2
:
679 print_integer_binary(v64
.u
, len_bits
);
681 case TRACER_DISPLAY_BASE_8
:
682 /* Clear sign bits beyond len_bits */
684 v64
.u
&= (1ULL << len_bits
) - 1;
685 printf("0%" PRIo64
, v64
.u
);
687 case TRACER_DISPLAY_BASE_10
:
688 if (type_integer
->signedness
)
689 printf("%" PRId64
, v64
.s
);
691 printf("%" PRIu64
, v64
.u
);
693 case TRACER_DISPLAY_BASE_16
:
694 /* Clear sign bits beyond len_bits */
696 v64
.u
&= (1ULL << len_bits
) - 1;
697 printf("0x%" PRIx64
, v64
.u
);
705 void tracer_print_type_float(const char *separator
,
706 const struct side_type_float
*type_float
,
707 const union side_float_value
*value
)
711 tracer_print_type_header(separator
, type_float
->attr
, type_float
->nr_attr
);
712 reverse_bo
= type_float
->byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
;
713 switch (type_float
->float_size
) {
721 .f
= value
->side_float_binary16
,
725 float16
.u
= side_bswap_16(float16
.u
);
726 printf("%g", (double) float16
.f
);
729 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
740 .f
= value
->side_float_binary32
,
744 float32
.u
= side_bswap_32(float32
.u
);
745 printf("%g", (double) float32
.f
);
748 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
759 .f
= value
->side_float_binary64
,
763 float64
.u
= side_bswap_64(float64
.u
);
764 printf("%g", (double) float64
.f
);
767 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
778 .f
= value
->side_float_binary128
,
782 side_bswap_128p(float128
.arr
);
783 printf("%Lg", (long double) float128
.f
);
786 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
791 fprintf(stderr
, "ERROR: Unknown float size\n");
797 void tracer_print_type(const struct side_type
*type_desc
, const struct side_arg
*item
)
799 enum side_type_label type
;
801 switch (type_desc
->type
) {
803 switch (item
->type
) {
814 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
820 case SIDE_TYPE_ENUM_BITMAP
:
821 switch (item
->type
) {
827 case SIDE_TYPE_ARRAY
:
831 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
837 case SIDE_TYPE_GATHER_ENUM
:
838 switch (item
->type
) {
839 case SIDE_TYPE_GATHER_INTEGER
:
842 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
848 case SIDE_TYPE_DYNAMIC
:
849 switch (item
->type
) {
850 case SIDE_TYPE_DYNAMIC_NULL
:
851 case SIDE_TYPE_DYNAMIC_BOOL
:
852 case SIDE_TYPE_DYNAMIC_INTEGER
:
853 case SIDE_TYPE_DYNAMIC_BYTE
:
854 case SIDE_TYPE_DYNAMIC_POINTER
:
855 case SIDE_TYPE_DYNAMIC_FLOAT
:
856 case SIDE_TYPE_DYNAMIC_STRING
:
857 case SIDE_TYPE_DYNAMIC_STRUCT
:
858 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
859 case SIDE_TYPE_DYNAMIC_VLA
:
860 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
863 fprintf(stderr
, "ERROR: Unexpected dynamic type\n");
870 if (type_desc
->type
!= item
->type
) {
871 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
877 if (type_desc
->type
== SIDE_TYPE_ENUM
|| type_desc
->type
== SIDE_TYPE_ENUM_BITMAP
||
878 type_desc
->type
== SIDE_TYPE_GATHER_ENUM
)
879 type
= (enum side_type_label
) type_desc
->type
;
881 type
= (enum side_type_label
) item
->type
;
885 /* Stack-copy basic types */
887 tracer_print_type_header(":", type_desc
->u
.side_null
.attr
, type_desc
->u
.side_null
.nr_attr
);
888 printf("<NULL TYPE>");
892 tracer_print_type_bool(":", &type_desc
->u
.side_bool
, &item
->u
.side_static
.bool_value
, 0);
903 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
904 TRACER_DISPLAY_BASE_10
);
908 tracer_print_type_header(":", type_desc
->u
.side_byte
.attr
, type_desc
->u
.side_byte
.nr_attr
);
909 printf("0x%" PRIx8
, item
->u
.side_static
.byte_value
);
912 case SIDE_TYPE_POINTER
:
913 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0,
914 TRACER_DISPLAY_BASE_16
);
917 case SIDE_TYPE_FLOAT_BINARY16
:
918 case SIDE_TYPE_FLOAT_BINARY32
:
919 case SIDE_TYPE_FLOAT_BINARY64
:
920 case SIDE_TYPE_FLOAT_BINARY128
:
921 tracer_print_type_float(":", &type_desc
->u
.side_float
, &item
->u
.side_static
.float_value
);
924 case SIDE_TYPE_STRING_UTF8
:
925 case SIDE_TYPE_STRING_UTF16
:
926 case SIDE_TYPE_STRING_UTF32
:
927 tracer_print_type_header(":", type_desc
->u
.side_string
.attr
, type_desc
->u
.side_string
.nr_attr
);
928 tracer_print_string((const void *)(uintptr_t) item
->u
.side_static
.string_value
,
929 type_desc
->u
.side_string
.unit_size
, type_desc
->u
.side_string
.byte_order
, NULL
);
932 /* Stack-copy compound types */
933 case SIDE_TYPE_STRUCT
:
934 tracer_print_struct(type_desc
, item
->u
.side_static
.side_struct
);
936 case SIDE_TYPE_ARRAY
:
937 tracer_print_array(type_desc
, item
->u
.side_static
.side_array
);
940 tracer_print_vla(type_desc
, item
->u
.side_static
.side_vla
);
942 case SIDE_TYPE_VLA_VISITOR
:
943 tracer_print_vla_visitor(type_desc
, item
->u
.side_static
.side_vla_app_visitor_ctx
);
946 /* Stack-copy enumeration types */
948 tracer_print_enum(type_desc
, item
);
950 case SIDE_TYPE_ENUM_BITMAP
:
951 tracer_print_enum_bitmap(type_desc
, item
);
954 /* Gather basic types */
955 case SIDE_TYPE_GATHER_BOOL
:
956 (void) tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_bool_gather_ptr
);
958 case SIDE_TYPE_GATHER_INTEGER
:
959 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
,
960 TRACER_DISPLAY_BASE_10
);
962 case SIDE_TYPE_GATHER_BYTE
:
963 (void) tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_byte_gather_ptr
);
965 case SIDE_TYPE_GATHER_POINTER
:
966 (void) tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
,
967 TRACER_DISPLAY_BASE_16
);
969 case SIDE_TYPE_GATHER_FLOAT
:
970 (void) tracer_print_gather_float_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_float_gather_ptr
);
972 case SIDE_TYPE_GATHER_STRING
:
973 (void) tracer_print_gather_string_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_string_gather_ptr
);
976 /* Gather compound type */
977 case SIDE_TYPE_GATHER_STRUCT
:
978 (void) tracer_print_gather_struct(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_struct_gather_ptr
);
980 case SIDE_TYPE_GATHER_ARRAY
:
981 (void) tracer_print_gather_array(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_array_gather_ptr
);
983 case SIDE_TYPE_GATHER_VLA
:
984 (void) tracer_print_gather_vla(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_vla_gather
.ptr
,
985 item
->u
.side_static
.side_vla_gather
.length_ptr
);
988 /* Gather enumeration types */
989 case SIDE_TYPE_GATHER_ENUM
:
990 (void) tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, item
->u
.side_static
.side_integer_gather_ptr
);
993 /* Dynamic basic types */
994 case SIDE_TYPE_DYNAMIC_NULL
:
995 case SIDE_TYPE_DYNAMIC_BOOL
:
996 case SIDE_TYPE_DYNAMIC_INTEGER
:
997 case SIDE_TYPE_DYNAMIC_BYTE
:
998 case SIDE_TYPE_DYNAMIC_POINTER
:
999 case SIDE_TYPE_DYNAMIC_FLOAT
:
1000 case SIDE_TYPE_DYNAMIC_STRING
:
1002 /* Dynamic compound types */
1003 case SIDE_TYPE_DYNAMIC_STRUCT
:
1004 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1005 case SIDE_TYPE_DYNAMIC_VLA
:
1006 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1007 tracer_print_dynamic(item
);
1010 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1017 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg
*item
)
1019 printf("%s: ", item_desc
->field_name
);
1020 tracer_print_type(&item_desc
->side_type
, item
);
1024 void tracer_print_struct(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1026 const struct side_arg
*sav
= side_arg_vec
->sav
;
1027 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1029 if (type_desc
->u
.side_struct
->nr_fields
!= side_sav_len
) {
1030 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
1033 print_attributes("attr", ":", type_desc
->u
.side_struct
->attr
, type_desc
->u
.side_struct
->nr_attr
);
1034 printf("%s", type_desc
->u
.side_struct
->nr_attr
? ", " : "");
1035 printf("fields: { ");
1036 for (i
= 0; i
< side_sav_len
; i
++) {
1037 printf("%s", i
? ", " : "");
1038 tracer_print_field(&type_desc
->u
.side_struct
->fields
[i
], &sav
[i
]);
1044 void tracer_print_array(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1046 const struct side_arg
*sav
= side_arg_vec
->sav
;
1047 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1049 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
1050 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
1053 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1054 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1055 printf("elements: ");
1057 for (i
= 0; i
< side_sav_len
; i
++) {
1058 printf("%s", i
? ", " : "");
1059 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
1065 void tracer_print_vla(const struct side_type
*type_desc
, const struct side_arg_vec
*side_arg_vec
)
1067 const struct side_arg
*sav
= side_arg_vec
->sav
;
1068 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1070 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1071 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1072 printf("elements: ");
1074 for (i
= 0; i
< side_sav_len
; i
++) {
1075 printf("%s", i
? ", " : "");
1076 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
1082 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode
, const char *ptr
)
1084 switch (access_mode
) {
1085 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
1087 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1088 /* Dereference pointer */
1089 memcpy(&ptr
, ptr
, sizeof(ptr
));
1097 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode
, uint32_t len
)
1099 switch (access_mode
) {
1100 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
1102 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
1103 return sizeof(void *);
1110 union int64_value
tracer_load_gather_integer_value(const struct side_type_gather_integer
*side_integer
,
1113 enum side_type_gather_access_mode access_mode
=
1114 (enum side_type_gather_access_mode
) side_integer
->access_mode
;
1115 uint32_t integer_size_bytes
= side_integer
->type
.integer_size
;
1116 const char *ptr
= (const char *) _ptr
;
1117 union side_integer_value value
;
1119 ptr
= tracer_gather_access(access_mode
, ptr
+ side_integer
->offset
);
1120 memcpy(&value
, ptr
, integer_size_bytes
);
1121 return tracer_load_integer_value(&side_integer
->type
, &value
,
1122 side_integer
->offset_bits
, NULL
);
1126 uint32_t tracer_print_gather_bool_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1128 enum side_type_gather_access_mode access_mode
=
1129 (enum side_type_gather_access_mode
) type_gather
->u
.side_bool
.access_mode
;
1130 uint32_t bool_size_bytes
= type_gather
->u
.side_bool
.type
.bool_size
;
1131 const char *ptr
= (const char *) _ptr
;
1132 union side_bool_value value
;
1134 switch (bool_size_bytes
) {
1143 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_bool
.offset
);
1144 memcpy(&value
, ptr
, bool_size_bytes
);
1145 tracer_print_type_bool(":", &type_gather
->u
.side_bool
.type
, &value
,
1146 type_gather
->u
.side_bool
.offset_bits
);
1147 return tracer_gather_size(access_mode
, bool_size_bytes
);
1151 uint32_t tracer_print_gather_byte_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1153 enum side_type_gather_access_mode access_mode
=
1154 (enum side_type_gather_access_mode
) type_gather
->u
.side_byte
.access_mode
;
1155 const char *ptr
= (const char *) _ptr
;
1158 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_byte
.offset
);
1159 memcpy(&value
, ptr
, 1);
1160 tracer_print_type_header(":", type_gather
->u
.side_byte
.type
.attr
,
1161 type_gather
->u
.side_byte
.type
.nr_attr
);
1162 printf("0x%" PRIx8
, value
);
1163 return tracer_gather_size(access_mode
, 1);
1167 uint32_t tracer_print_gather_integer_type(const struct side_type_gather
*type_gather
, const void *_ptr
,
1168 enum tracer_display_base default_base
)
1170 enum side_type_gather_access_mode access_mode
=
1171 (enum side_type_gather_access_mode
) type_gather
->u
.side_integer
.access_mode
;
1172 uint32_t integer_size_bytes
= type_gather
->u
.side_integer
.type
.integer_size
;
1173 const char *ptr
= (const char *) _ptr
;
1174 union side_integer_value value
;
1176 switch (integer_size_bytes
) {
1185 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_integer
.offset
);
1186 memcpy(&value
, ptr
, integer_size_bytes
);
1187 tracer_print_type_integer(":", &type_gather
->u
.side_integer
.type
, &value
,
1188 type_gather
->u
.side_integer
.offset_bits
, default_base
);
1189 return tracer_gather_size(access_mode
, integer_size_bytes
);
1193 uint32_t tracer_print_gather_float_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1195 enum side_type_gather_access_mode access_mode
=
1196 (enum side_type_gather_access_mode
) type_gather
->u
.side_float
.access_mode
;
1197 uint32_t float_size_bytes
= type_gather
->u
.side_float
.type
.float_size
;
1198 const char *ptr
= (const char *) _ptr
;
1199 union side_float_value value
;
1201 switch (float_size_bytes
) {
1210 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_float
.offset
);
1211 memcpy(&value
, ptr
, float_size_bytes
);
1212 tracer_print_type_float(":", &type_gather
->u
.side_float
.type
, &value
);
1213 return tracer_gather_size(access_mode
, float_size_bytes
);
1217 uint32_t tracer_print_gather_string_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_string
.access_mode
;
1221 const char *ptr
= (const char *) _ptr
;
1224 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_string
.offset
);
1225 tracer_print_type_header(":", type_gather
->u
.side_string
.type
.attr
,
1226 type_gather
->u
.side_string
.type
.nr_attr
);
1228 tracer_print_string(ptr
, type_gather
->u
.side_string
.type
.unit_size
,
1229 type_gather
->u
.side_string
.type
.byte_order
, &string_len
);
1232 string_len
= type_gather
->u
.side_string
.type
.unit_size
;
1234 return tracer_gather_size(access_mode
, string_len
);
1238 uint32_t tracer_print_gather_type(const struct side_type
*type_desc
, const void *ptr
)
1243 switch (type_desc
->type
) {
1244 /* Gather basic types */
1245 case SIDE_TYPE_GATHER_BOOL
:
1246 len
= tracer_print_gather_bool_type(&type_desc
->u
.side_gather
, ptr
);
1248 case SIDE_TYPE_GATHER_INTEGER
:
1249 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
,
1250 TRACER_DISPLAY_BASE_10
);
1252 case SIDE_TYPE_GATHER_BYTE
:
1253 len
= tracer_print_gather_byte_type(&type_desc
->u
.side_gather
, ptr
);
1255 case SIDE_TYPE_GATHER_POINTER
:
1256 len
= tracer_print_gather_integer_type(&type_desc
->u
.side_gather
, ptr
,
1257 TRACER_DISPLAY_BASE_16
);
1259 case SIDE_TYPE_GATHER_FLOAT
:
1260 len
= tracer_print_gather_float_type(&type_desc
->u
.side_gather
, ptr
);
1262 case SIDE_TYPE_GATHER_STRING
:
1263 len
= tracer_print_gather_string_type(&type_desc
->u
.side_gather
, ptr
);
1266 /* Gather enum types */
1267 case SIDE_TYPE_GATHER_ENUM
:
1268 len
= tracer_print_gather_enum_type(&type_desc
->u
.side_gather
, ptr
);
1271 /* Gather compound types */
1272 case SIDE_TYPE_GATHER_STRUCT
:
1273 len
= tracer_print_gather_struct(&type_desc
->u
.side_gather
, ptr
);
1275 case SIDE_TYPE_GATHER_ARRAY
:
1276 len
= tracer_print_gather_array(&type_desc
->u
.side_gather
, ptr
);
1278 case SIDE_TYPE_GATHER_VLA
:
1279 len
= tracer_print_gather_vla(&type_desc
->u
.side_gather
, ptr
, ptr
);
1282 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
1290 uint32_t tracer_print_gather_enum_type(const struct side_type_gather
*type_gather
, const void *_ptr
)
1292 const struct side_enum_mappings
*mappings
= type_gather
->u
.side_enum
.mappings
;
1293 const struct side_type
*enum_elem_type
= type_gather
->u
.side_enum
.elem_type
;
1294 const struct side_type_gather_integer
*side_integer
= &enum_elem_type
->u
.side_gather
.u
.side_integer
;
1295 enum side_type_gather_access_mode access_mode
=
1296 (enum side_type_gather_access_mode
) side_integer
->access_mode
;
1297 uint32_t integer_size_bytes
= side_integer
->type
.integer_size
;
1298 const char *ptr
= (const char *) _ptr
;
1299 union side_integer_value value
;
1300 union int64_value v64
;
1302 switch (integer_size_bytes
) {
1311 ptr
= tracer_gather_access(access_mode
, ptr
+ side_integer
->offset
);
1312 memcpy(&value
, ptr
, integer_size_bytes
);
1313 v64
= tracer_load_gather_integer_value(side_integer
, &value
);
1314 print_attributes("attr", ":", mappings
->attr
, mappings
->nr_attr
);
1315 printf("%s", mappings
->nr_attr
? ", " : "");
1316 tracer_print_gather_type(enum_elem_type
, ptr
);
1317 print_enum_labels(mappings
, v64
);
1318 return tracer_gather_size(access_mode
, integer_size_bytes
);
1322 void tracer_print_gather_field(const struct side_event_field
*field
, const void *ptr
)
1324 printf("%s: ", field
->field_name
);
1325 (void) tracer_print_gather_type(&field
->side_type
, ptr
);
1329 uint32_t tracer_print_gather_struct(const struct side_type_gather
*type_gather
, const void *_ptr
)
1331 enum side_type_gather_access_mode access_mode
=
1332 (enum side_type_gather_access_mode
) type_gather
->u
.side_struct
.access_mode
;
1333 const char *ptr
= (const char *) _ptr
;
1336 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_struct
.offset
);
1337 print_attributes("attr", ":", type_gather
->u
.side_struct
.type
->attr
, type_gather
->u
.side_struct
.type
->nr_attr
);
1338 printf("%s", type_gather
->u
.side_struct
.type
->nr_attr
? ", " : "");
1339 printf("fields: { ");
1340 for (i
= 0; i
< type_gather
->u
.side_struct
.type
->nr_fields
; i
++) {
1341 printf("%s", i
? ", " : "");
1342 tracer_print_gather_field(&type_gather
->u
.side_struct
.type
->fields
[i
], ptr
);
1345 return tracer_gather_size(access_mode
, type_gather
->u
.side_struct
.size
);
1349 uint32_t tracer_print_gather_array(const struct side_type_gather
*type_gather
, const void *_ptr
)
1351 enum side_type_gather_access_mode access_mode
=
1352 (enum side_type_gather_access_mode
) type_gather
->u
.side_array
.access_mode
;
1353 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1356 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_array
.offset
);
1358 print_attributes("attr", ":", type_gather
->u
.side_array
.type
.attr
, type_gather
->u
.side_array
.type
.nr_attr
);
1359 printf("%s", type_gather
->u
.side_array
.type
.nr_attr
? ", " : "");
1360 printf("elements: ");
1362 for (i
= 0; i
< type_gather
->u
.side_array
.type
.length
; i
++) {
1363 switch (type_gather
->u
.side_array
.type
.elem_type
->type
) {
1364 case SIDE_TYPE_GATHER_VLA
:
1365 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1370 printf("%s", i
? ", " : "");
1371 ptr
+= tracer_print_gather_type(type_gather
->u
.side_array
.type
.elem_type
, ptr
);
1374 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1378 uint32_t tracer_print_gather_vla(const struct side_type_gather
*type_gather
, const void *_ptr
,
1379 const void *_length_ptr
)
1381 enum side_type_gather_access_mode access_mode
=
1382 (enum side_type_gather_access_mode
) type_gather
->u
.side_vla
.access_mode
;
1383 const char *ptr
= (const char *) _ptr
, *orig_ptr
;
1384 const char *length_ptr
= (const char *) _length_ptr
;
1385 union int64_value v64
;
1389 switch (type_gather
->u
.side_vla
.length_type
->type
) {
1390 case SIDE_TYPE_GATHER_INTEGER
:
1393 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
1396 v64
= tracer_load_gather_integer_value(&type_gather
->u
.side_vla
.length_type
->u
.side_gather
.u
.side_integer
,
1398 length
= (uint32_t) v64
.u
;
1399 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_vla
.offset
);
1401 print_attributes("attr", ":", type_gather
->u
.side_vla
.type
.attr
, type_gather
->u
.side_vla
.type
.nr_attr
);
1402 printf("%s", type_gather
->u
.side_vla
.type
.nr_attr
? ", " : "");
1403 printf("elements: ");
1405 for (i
= 0; i
< length
; i
++) {
1406 switch (type_gather
->u
.side_vla
.type
.elem_type
->type
) {
1407 case SIDE_TYPE_GATHER_VLA
:
1408 fprintf(stderr
, "<gather VLA only supported within gather structures>\n");
1413 printf("%s", i
? ", " : "");
1414 ptr
+= tracer_print_gather_type(type_gather
->u
.side_vla
.type
.elem_type
, ptr
);
1417 return tracer_gather_size(access_mode
, ptr
- orig_ptr
);
1420 struct tracer_visitor_priv
{
1421 const struct side_type
*elem_type
;
1426 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1427 const struct side_arg
*elem
)
1429 struct tracer_visitor_priv
*tracer_priv
= (struct tracer_visitor_priv
*) tracer_ctx
->priv
;
1431 printf("%s", tracer_priv
->i
++ ? ", " : "");
1432 tracer_print_type(tracer_priv
->elem_type
, elem
);
1433 return SIDE_VISITOR_STATUS_OK
;
1437 void tracer_print_vla_visitor(const struct side_type
*type_desc
, void *app_ctx
)
1439 enum side_visitor_status status
;
1440 struct tracer_visitor_priv tracer_priv
= {
1441 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
1444 const struct side_tracer_visitor_ctx tracer_ctx
= {
1445 .write_elem
= tracer_write_elem_cb
,
1446 .priv
= &tracer_priv
,
1449 print_attributes("attr", ":", type_desc
->u
.side_vla_visitor
.attr
, type_desc
->u
.side_vla_visitor
.nr_attr
);
1450 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1451 printf("elements: ");
1453 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1455 case SIDE_VISITOR_STATUS_OK
:
1457 case SIDE_VISITOR_STATUS_ERROR
:
1458 fprintf(stderr
, "ERROR: Visitor error\n");
1465 void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
)
1467 const struct side_arg_dynamic_field
*fields
= dynamic_struct
->fields
;
1468 uint32_t i
, len
= dynamic_struct
->len
;
1470 print_attributes("attr", "::", dynamic_struct
->attr
, dynamic_struct
->nr_attr
);
1471 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1472 printf("fields:: ");
1474 for (i
= 0; i
< len
; i
++) {
1475 printf("%s", i
? ", " : "");
1476 printf("%s:: ", fields
[i
].field_name
);
1477 tracer_print_dynamic(&fields
[i
].elem
);
1482 struct tracer_dynamic_struct_visitor_priv
{
1487 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1488 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1489 const struct side_arg_dynamic_field
*dynamic_field
)
1491 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
=
1492 (struct tracer_dynamic_struct_visitor_priv
*) tracer_ctx
->priv
;
1494 printf("%s", tracer_priv
->i
++ ? ", " : "");
1495 printf("%s:: ", dynamic_field
->field_name
);
1496 tracer_print_dynamic(&dynamic_field
->elem
);
1497 return SIDE_VISITOR_STATUS_OK
;
1501 void tracer_print_dynamic_struct_visitor(const struct side_arg
*item
)
1503 enum side_visitor_status status
;
1504 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1507 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1508 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1509 .priv
= &tracer_priv
,
1511 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.app_ctx
;
1513 print_attributes("attr", "::", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.attr
, item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
);
1514 printf("%s", item
->u
.side_dynamic
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1515 printf("fields:: ");
1517 status
= item
->u
.side_dynamic
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1519 case SIDE_VISITOR_STATUS_OK
:
1521 case SIDE_VISITOR_STATUS_ERROR
:
1522 fprintf(stderr
, "ERROR: Visitor error\n");
1529 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla
*vla
)
1531 const struct side_arg
*sav
= vla
->sav
;
1532 uint32_t i
, side_sav_len
= vla
->len
;
1534 print_attributes("attr", "::", vla
->attr
, vla
->nr_attr
);
1535 printf("%s", vla
->nr_attr
? ", " : "");
1536 printf("elements:: ");
1538 for (i
= 0; i
< side_sav_len
; i
++) {
1539 printf("%s", i
? ", " : "");
1540 tracer_print_dynamic(&sav
[i
]);
1545 struct tracer_dynamic_vla_visitor_priv
{
1550 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1551 const struct side_tracer_visitor_ctx
*tracer_ctx
,
1552 const struct side_arg
*elem
)
1554 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
=
1555 (struct tracer_dynamic_vla_visitor_priv
*) tracer_ctx
->priv
;
1557 printf("%s", tracer_priv
->i
++ ? ", " : "");
1558 tracer_print_dynamic(elem
);
1559 return SIDE_VISITOR_STATUS_OK
;
1563 void tracer_print_dynamic_vla_visitor(const struct side_arg
*item
)
1565 enum side_visitor_status status
;
1566 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1569 const struct side_tracer_visitor_ctx tracer_ctx
= {
1570 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1571 .priv
= &tracer_priv
,
1573 void *app_ctx
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.app_ctx
;
1575 print_attributes("attr", "::", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.attr
, item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
);
1576 printf("%s", item
->u
.side_dynamic
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1577 printf("elements:: ");
1579 status
= item
->u
.side_dynamic
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1581 case SIDE_VISITOR_STATUS_OK
:
1583 case SIDE_VISITOR_STATUS_ERROR
:
1584 fprintf(stderr
, "ERROR: Visitor error\n");
1591 void tracer_print_dynamic(const struct side_arg
*item
)
1594 switch (item
->type
) {
1595 /* Dynamic basic types */
1596 case SIDE_TYPE_DYNAMIC_NULL
:
1597 tracer_print_type_header("::", item
->u
.side_dynamic
.side_null
.attr
, item
->u
.side_dynamic
.side_null
.nr_attr
);
1598 printf("<NULL TYPE>");
1600 case SIDE_TYPE_DYNAMIC_BOOL
:
1601 tracer_print_type_bool("::", &item
->u
.side_dynamic
.side_bool
.type
, &item
->u
.side_dynamic
.side_bool
.value
, 0);
1603 case SIDE_TYPE_DYNAMIC_INTEGER
:
1604 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1605 TRACER_DISPLAY_BASE_10
);
1607 case SIDE_TYPE_DYNAMIC_BYTE
:
1608 tracer_print_type_header("::", item
->u
.side_dynamic
.side_byte
.type
.attr
, item
->u
.side_dynamic
.side_byte
.type
.nr_attr
);
1609 printf("0x%" PRIx8
, item
->u
.side_dynamic
.side_byte
.value
);
1611 case SIDE_TYPE_DYNAMIC_POINTER
:
1612 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1613 TRACER_DISPLAY_BASE_16
);
1615 case SIDE_TYPE_DYNAMIC_FLOAT
:
1616 tracer_print_type_float("::", &item
->u
.side_dynamic
.side_float
.type
,
1617 &item
->u
.side_dynamic
.side_float
.value
);
1619 case SIDE_TYPE_DYNAMIC_STRING
:
1620 tracer_print_type_header("::", item
->u
.side_dynamic
.side_string
.type
.attr
, item
->u
.side_dynamic
.side_string
.type
.nr_attr
);
1621 tracer_print_string((const char *)(uintptr_t) item
->u
.side_dynamic
.side_string
.value
,
1622 item
->u
.side_dynamic
.side_string
.type
.unit_size
,
1623 item
->u
.side_dynamic
.side_string
.type
.byte_order
, NULL
);
1626 /* Dynamic compound types */
1627 case SIDE_TYPE_DYNAMIC_STRUCT
:
1628 tracer_print_dynamic_struct(item
->u
.side_dynamic
.side_dynamic_struct
);
1630 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
1631 tracer_print_dynamic_struct_visitor(item
);
1633 case SIDE_TYPE_DYNAMIC_VLA
:
1634 tracer_print_dynamic_vla(item
->u
.side_dynamic
.side_dynamic_vla
);
1636 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
1637 tracer_print_dynamic_vla_visitor(item
);
1640 fprintf(stderr
, "<UNKNOWN TYPE>\n");
1647 void tracer_print_static_fields(const struct side_event_description
*desc
,
1648 const struct side_arg_vec
*side_arg_vec
,
1651 const struct side_arg
*sav
= side_arg_vec
->sav
;
1652 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1654 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
1655 if (desc
->nr_fields
!= side_sav_len
) {
1656 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1659 print_attributes(", attr", ":", desc
->attr
, desc
->nr_attr
);
1660 printf("%s", side_sav_len
? ", fields: [ " : "");
1661 for (i
= 0; i
< side_sav_len
; i
++) {
1662 printf("%s", i
? ", " : "");
1663 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
1671 void tracer_call(const struct side_event_description
*desc
,
1672 const struct side_arg_vec
*side_arg_vec
,
1673 void *priv
__attribute__((unused
)))
1675 uint32_t nr_fields
= 0;
1677 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1681 void tracer_call_variadic(const struct side_event_description
*desc
,
1682 const struct side_arg_vec
*side_arg_vec
,
1683 const struct side_arg_dynamic_struct
*var_struct
,
1684 void *priv
__attribute__((unused
)))
1686 uint32_t nr_fields
= 0, i
, var_struct_len
= var_struct
->len
;
1688 tracer_print_static_fields(desc
, side_arg_vec
, &nr_fields
);
1690 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1691 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1694 print_attributes(", attr ", "::", var_struct
->attr
, var_struct
->nr_attr
);
1695 printf("%s", var_struct_len
? ", fields:: [ " : "");
1696 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1697 printf("%s", i
? ", " : "");
1698 printf("%s:: ", var_struct
->fields
[i
].field_name
);
1699 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
1706 void tracer_event_notification(enum side_tracer_notification notif
,
1707 struct side_event_description
**events
, uint32_t nr_events
, void *priv
)
1712 printf("----------------------------------------------------------\n");
1713 printf("Tracer notified of events %s\n",
1714 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1715 for (i
= 0; i
< nr_events
; i
++) {
1716 struct side_event_description
*event
= events
[i
];
1718 /* Skip NULL pointers */
1721 printf("provider: %s, event: %s\n",
1722 event
->provider_name
, event
->event_name
);
1723 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1724 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1725 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1729 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1734 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1735 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1739 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1745 printf("----------------------------------------------------------\n");
1748 static __attribute__((constructor
))
1749 void tracer_init(void);
1751 void tracer_init(void)
1753 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1758 static __attribute__((destructor
))
1759 void tracer_exit(void);
1761 void tracer_exit(void)
1763 side_tracer_event_notification_unregister(tracer_handle
);