1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
14 #include <side/trace.h>
16 #include "visit-arg-vec.h"
17 #include "visit-description.h"
19 /* TODO: optionally print caller address. */
20 static bool print_caller
= false;
22 #define MAX_NESTING 32
24 enum tracer_display_base
{
25 TRACER_DISPLAY_BASE_2
,
26 TRACER_DISPLAY_BASE_8
,
27 TRACER_DISPLAY_BASE_10
,
28 TRACER_DISPLAY_BASE_16
,
32 uint64_t u
[NR_SIDE_INTEGER128_SPLIT
];
33 int64_t s
[NR_SIDE_INTEGER128_SPLIT
];
37 int nesting
; /* Keep track of nesting, useful for tabulations. */
38 int item_nr
[MAX_NESTING
]; /* Item number in current nesting level, useful for comma-separated lists. */
41 static struct side_tracer_handle
*tracer_handle
;
43 static uint64_t tracer_key
;
45 static struct side_description_visitor description_visitor
;
48 void tracer_convert_string_to_utf8(const void *p
, uint8_t unit_size
, enum side_type_label_byte_order byte_order
,
49 size_t *strlen_with_null
,
52 size_t ret
, inbytesleft
= 0, outbytesleft
, bufsize
, input_size
;
53 const char *str
= p
, *fromcode
;
54 char *inbuf
= (char *) p
, *outbuf
, *buf
;
60 *strlen_with_null
= strlen(str
) + 1;
61 *output_str
= (char *) str
;
65 const uint16_t *p16
= p
;
68 case SIDE_TYPE_BYTE_ORDER_LE
:
70 fromcode
= "UTF-16LE";
73 case SIDE_TYPE_BYTE_ORDER_BE
:
75 fromcode
= "UTF-16BE";
79 fprintf(stderr
, "Unknown byte order\n");
84 input_size
= inbytesleft
+ 2;
86 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
87 * { ef, bf, bf } UTF-8 (3 bytes).
89 bufsize
= inbytesleft
/ 2 * 3 + 1;
94 const uint32_t *p32
= p
;
97 case SIDE_TYPE_BYTE_ORDER_LE
:
99 fromcode
= "UTF-32LE";
102 case SIDE_TYPE_BYTE_ORDER_BE
:
104 fromcode
= "UTF-32BE";
108 fprintf(stderr
, "Unknown byte order\n");
113 input_size
= inbytesleft
+ 4;
115 * Each 4-byte UTF-32 character converts to at most a
116 * 4-byte UTF-8 character.
118 bufsize
= inbytesleft
+ 1;
122 fprintf(stderr
, "Unknown string unit size %" PRIu8
"\n", unit_size
);
126 cd
= iconv_open("UTF8", fromcode
);
127 if (cd
== (iconv_t
) -1) {
128 perror("iconv_open");
131 buf
= malloc(bufsize
);
135 outbuf
= (char *) buf
;
136 outbytesleft
= bufsize
;
137 ret
= iconv(cd
, &inbuf
, &inbytesleft
, &outbuf
, &outbytesleft
);
138 if (ret
== (size_t) -1) {
143 fprintf(stderr
, "Buffer too small to convert string input\n");
147 if (iconv_close(cd
) == -1) {
148 perror("iconv_close");
151 if (strlen_with_null
)
152 *strlen_with_null
= input_size
;
157 void tracer_print_type_string(const void *p
, uint8_t unit_size
, enum side_type_label_byte_order byte_order
,
158 size_t *strlen_with_null
)
160 char *output_str
= NULL
;
162 tracer_convert_string_to_utf8(p
, unit_size
, byte_order
, strlen_with_null
, &output_str
);
163 printf("\"%s\"", output_str
);
169 void side_check_value_u64(union int_value v
)
171 if (v
.u
[SIDE_INTEGER128_SPLIT_HIGH
]) {
172 fprintf(stderr
, "Unexpected integer value\n");
178 void side_check_value_s64(union int_value v
)
180 if (v
.s
[SIDE_INTEGER128_SPLIT_LOW
] & (1ULL << 63)) {
181 if (v
.s
[SIDE_INTEGER128_SPLIT_HIGH
] != ~0LL) {
182 fprintf(stderr
, "Unexpected integer value\n");
186 if (v
.s
[SIDE_INTEGER128_SPLIT_HIGH
]) {
187 fprintf(stderr
, "Unexpected integer value\n");
194 int64_t get_attr_integer64_value(const struct side_attr
*attr
)
198 switch (side_enum_get(attr
->value
.type
)) {
199 case SIDE_ATTR_TYPE_U8
:
200 val
= attr
->value
.u
.integer_value
.side_u8
;
202 case SIDE_ATTR_TYPE_U16
:
203 val
= attr
->value
.u
.integer_value
.side_u16
;
205 case SIDE_ATTR_TYPE_U32
:
206 val
= attr
->value
.u
.integer_value
.side_u32
;
208 case SIDE_ATTR_TYPE_U64
:
209 val
= attr
->value
.u
.integer_value
.side_u64
;
211 case SIDE_ATTR_TYPE_U128
:
213 union int_value v
= {
215 [SIDE_INTEGER128_SPLIT_LOW
] = attr
->value
.u
.integer_value
.side_u128_split
[SIDE_INTEGER128_SPLIT_LOW
],
216 [SIDE_INTEGER128_SPLIT_HIGH
] = attr
->value
.u
.integer_value
.side_u128_split
[SIDE_INTEGER128_SPLIT_HIGH
],
219 side_check_value_u64(v
);
220 val
= v
.u
[SIDE_INTEGER128_SPLIT_LOW
];
223 case SIDE_ATTR_TYPE_S8
:
224 val
= attr
->value
.u
.integer_value
.side_s8
;
226 case SIDE_ATTR_TYPE_S16
:
227 val
= attr
->value
.u
.integer_value
.side_s16
;
229 case SIDE_ATTR_TYPE_S32
:
230 val
= attr
->value
.u
.integer_value
.side_s32
;
232 case SIDE_ATTR_TYPE_S64
:
233 val
= attr
->value
.u
.integer_value
.side_s64
;
235 case SIDE_ATTR_TYPE_S128
:
237 union int_value v
= {
239 [SIDE_INTEGER128_SPLIT_LOW
] = attr
->value
.u
.integer_value
.side_s128_split
[SIDE_INTEGER128_SPLIT_LOW
],
240 [SIDE_INTEGER128_SPLIT_HIGH
] = attr
->value
.u
.integer_value
.side_s128_split
[SIDE_INTEGER128_SPLIT_HIGH
],
243 side_check_value_s64(v
);
244 val
= v
.s
[SIDE_INTEGER128_SPLIT_LOW
];
248 fprintf(stderr
, "Unexpected attribute type\n");
255 enum tracer_display_base
get_attr_display_base(const struct side_attr
*_attr
, uint32_t nr_attr
,
256 enum tracer_display_base default_base
)
260 for (i
= 0; i
< nr_attr
; i
++) {
261 const struct side_attr
*attr
= &_attr
[i
];
262 char *utf8_str
= NULL
;
265 tracer_convert_string_to_utf8(side_ptr_get(attr
->key
.p
), attr
->key
.unit_size
,
266 side_enum_get(attr
->key
.byte_order
), NULL
, &utf8_str
);
267 cmp
= strcmp(utf8_str
, "std.integer.base");
268 if (utf8_str
!= side_ptr_get(attr
->key
.p
))
271 int64_t val
= get_attr_integer64_value(attr
);
275 return TRACER_DISPLAY_BASE_2
;
277 return TRACER_DISPLAY_BASE_8
;
279 return TRACER_DISPLAY_BASE_10
;
281 return TRACER_DISPLAY_BASE_16
;
283 fprintf(stderr
, "Unexpected integer display base: %" PRId64
"\n", val
);
288 return default_base
; /* Default */
292 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
294 char *utf8_str
= NULL
;
296 tracer_convert_string_to_utf8(side_ptr_get(attr
->key
.p
), attr
->key
.unit_size
,
297 side_enum_get(attr
->key
.byte_order
), NULL
, &utf8_str
);
298 printf("{ key%s \"%s\", value%s ", separator
, utf8_str
, separator
);
299 if (utf8_str
!= side_ptr_get(attr
->key
.p
))
301 switch (side_enum_get(attr
->value
.type
)) {
302 case SIDE_ATTR_TYPE_BOOL
:
303 printf("%s", attr
->value
.u
.bool_value
? "true" : "false");
305 case SIDE_ATTR_TYPE_U8
:
306 printf("%" PRIu8
, attr
->value
.u
.integer_value
.side_u8
);
308 case SIDE_ATTR_TYPE_U16
:
309 printf("%" PRIu16
, attr
->value
.u
.integer_value
.side_u16
);
311 case SIDE_ATTR_TYPE_U32
:
312 printf("%" PRIu32
, attr
->value
.u
.integer_value
.side_u32
);
314 case SIDE_ATTR_TYPE_U64
:
315 printf("%" PRIu64
, attr
->value
.u
.integer_value
.side_u64
);
317 case SIDE_ATTR_TYPE_U128
:
318 if (attr
->value
.u
.integer_value
.side_u128_split
[SIDE_INTEGER128_SPLIT_HIGH
] == 0) {
319 printf("0x%" PRIx64
, attr
->value
.u
.integer_value
.side_u128_split
[SIDE_INTEGER128_SPLIT_LOW
]);
321 printf("0x%" PRIx64
"%016" PRIx64
,
322 attr
->value
.u
.integer_value
.side_u128_split
[SIDE_INTEGER128_SPLIT_HIGH
],
323 attr
->value
.u
.integer_value
.side_u128_split
[SIDE_INTEGER128_SPLIT_LOW
]);
326 case SIDE_ATTR_TYPE_S8
:
327 printf("%" PRId8
, attr
->value
.u
.integer_value
.side_s8
);
329 case SIDE_ATTR_TYPE_S16
:
330 printf("%" PRId16
, attr
->value
.u
.integer_value
.side_s16
);
332 case SIDE_ATTR_TYPE_S32
:
333 printf("%" PRId32
, attr
->value
.u
.integer_value
.side_s32
);
335 case SIDE_ATTR_TYPE_S64
:
336 printf("%" PRId64
, attr
->value
.u
.integer_value
.side_s64
);
338 case SIDE_ATTR_TYPE_S128
:
339 if (attr
->value
.u
.integer_value
.side_s128_split
[SIDE_INTEGER128_SPLIT_HIGH
] == 0) {
340 printf("0x%" PRIx64
, attr
->value
.u
.integer_value
.side_s128_split
[SIDE_INTEGER128_SPLIT_LOW
]);
342 printf("0x%" PRIx64
"%016" PRIx64
,
343 attr
->value
.u
.integer_value
.side_s128_split
[SIDE_INTEGER128_SPLIT_HIGH
],
344 attr
->value
.u
.integer_value
.side_s128_split
[SIDE_INTEGER128_SPLIT_LOW
]);
347 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
349 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary16
);
352 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
355 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
357 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary32
);
360 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
363 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
365 printf("%g", (double) attr
->value
.u
.float_value
.side_float_binary64
);
368 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
371 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
373 printf("%Lg", (long double) attr
->value
.u
.float_value
.side_float_binary128
);
376 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
379 case SIDE_ATTR_TYPE_STRING
:
380 tracer_print_type_string(side_ptr_get(attr
->value
.u
.string_value
.p
),
381 attr
->value
.u
.string_value
.unit_size
,
382 side_enum_get(attr
->value
.u
.string_value
.byte_order
), NULL
);
385 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
392 void print_attributes(const char *prefix_str
, const char *separator
,
393 const struct side_attr
*attr
, uint32_t nr_attr
)
399 printf("%s%s [", prefix_str
, separator
);
400 for (i
= 0; i
< nr_attr
; i
++) {
401 printf("%s", i
? ", " : " ");
402 tracer_print_attr_type(separator
, &attr
[i
]);
408 union int_value
tracer_load_integer_value(const struct side_type_integer
*type_integer
,
409 const union side_integer_value
*value
,
410 uint16_t offset_bits
, uint16_t *_len_bits
)
412 union int_value v
= {};
416 if (!type_integer
->len_bits
)
417 len_bits
= type_integer
->integer_size
* CHAR_BIT
;
419 len_bits
= type_integer
->len_bits
;
420 if (len_bits
+ offset_bits
> type_integer
->integer_size
* CHAR_BIT
)
422 reverse_bo
= side_enum_get(type_integer
->byte_order
) != SIDE_TYPE_BYTE_ORDER_HOST
;
423 switch (type_integer
->integer_size
) {
425 if (type_integer
->signedness
)
426 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = value
->side_s8
;
428 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = value
->side_u8
;
431 if (type_integer
->signedness
) {
434 side_s16
= value
->side_s16
;
436 side_s16
= side_bswap_16(side_s16
);
437 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s16
;
441 side_u16
= value
->side_u16
;
443 side_u16
= side_bswap_16(side_u16
);
444 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u16
;
448 if (type_integer
->signedness
) {
451 side_s32
= value
->side_s32
;
453 side_s32
= side_bswap_32(side_s32
);
454 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s32
;
458 side_u32
= value
->side_u32
;
460 side_u32
= side_bswap_32(side_u32
);
461 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u32
;
465 if (type_integer
->signedness
) {
468 side_s64
= value
->side_s64
;
470 side_s64
= side_bswap_64(side_s64
);
471 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s64
;
475 side_u64
= value
->side_u64
;
477 side_u64
= side_bswap_64(side_u64
);
478 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u64
;
482 if (type_integer
->signedness
) {
483 int64_t side_s64
[NR_SIDE_INTEGER128_SPLIT
];
485 side_s64
[SIDE_INTEGER128_SPLIT_LOW
] = value
->side_s128_split
[SIDE_INTEGER128_SPLIT_LOW
];
486 side_s64
[SIDE_INTEGER128_SPLIT_HIGH
] = value
->side_s128_split
[SIDE_INTEGER128_SPLIT_HIGH
];
488 side_s64
[SIDE_INTEGER128_SPLIT_LOW
] = side_bswap_64(side_s64
[SIDE_INTEGER128_SPLIT_LOW
]);
489 side_s64
[SIDE_INTEGER128_SPLIT_HIGH
] = side_bswap_64(side_s64
[SIDE_INTEGER128_SPLIT_HIGH
]);
490 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s64
[SIDE_INTEGER128_SPLIT_HIGH
];
491 v
.s
[SIDE_INTEGER128_SPLIT_HIGH
] = side_s64
[SIDE_INTEGER128_SPLIT_LOW
];
493 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s64
[SIDE_INTEGER128_SPLIT_LOW
];
494 v
.s
[SIDE_INTEGER128_SPLIT_HIGH
] = side_s64
[SIDE_INTEGER128_SPLIT_HIGH
];
497 uint64_t side_u64
[NR_SIDE_INTEGER128_SPLIT
];
499 side_u64
[SIDE_INTEGER128_SPLIT_LOW
] = value
->side_u128_split
[SIDE_INTEGER128_SPLIT_LOW
];
500 side_u64
[SIDE_INTEGER128_SPLIT_HIGH
] = value
->side_u128_split
[SIDE_INTEGER128_SPLIT_HIGH
];
502 side_u64
[SIDE_INTEGER128_SPLIT_LOW
] = side_bswap_64(side_u64
[SIDE_INTEGER128_SPLIT_LOW
]);
503 side_u64
[SIDE_INTEGER128_SPLIT_HIGH
] = side_bswap_64(side_u64
[SIDE_INTEGER128_SPLIT_HIGH
]);
504 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u64
[SIDE_INTEGER128_SPLIT_HIGH
];
505 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = side_u64
[SIDE_INTEGER128_SPLIT_LOW
];
507 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u64
[SIDE_INTEGER128_SPLIT_LOW
];
508 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = side_u64
[SIDE_INTEGER128_SPLIT_HIGH
];
515 if (type_integer
->integer_size
<= 8) {
516 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] >>= offset_bits
;
518 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] &= (1ULL << len_bits
) - 1;
519 if (type_integer
->signedness
) {
521 if (v
.u
[SIDE_INTEGER128_SPLIT_LOW
] & (1ULL << (len_bits
- 1))) {
522 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] |= ~((1ULL << len_bits
) - 1);
523 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = ~0ULL;
528 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
529 if (len_bits
< 128 || offset_bits
!= 0)
533 *_len_bits
= len_bits
;
538 void print_enum_labels(const struct side_enum_mappings
*mappings
, union int_value v
)
540 uint32_t i
, print_count
= 0;
542 side_check_value_s64(v
);
543 printf(", labels: [ ");
544 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
545 const struct side_enum_mapping
*mapping
= &side_ptr_get(mappings
->mappings
)[i
];
547 if (mapping
->range_end
< mapping
->range_begin
) {
548 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
549 mapping
->range_begin
, mapping
->range_end
);
552 if (v
.s
[SIDE_INTEGER128_SPLIT_LOW
] >= mapping
->range_begin
&& v
.s
[SIDE_INTEGER128_SPLIT_LOW
] <= mapping
->range_end
) {
553 printf("%s", print_count
++ ? ", " : "");
554 tracer_print_type_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
,
555 side_enum_get(mapping
->label
.byte_order
), NULL
);
559 printf("<NO LABEL>");
564 uint32_t elem_type_to_stride(const struct side_type
*elem_type
)
568 switch (side_enum_get(elem_type
->type
)) {
583 return elem_type
->u
.side_integer
.integer_size
* CHAR_BIT
;
585 fprintf(stderr
, "ERROR: Unexpected enum bitmap element type\n");
592 void print_integer_binary(uint64_t v
[NR_SIDE_INTEGER128_SPLIT
], int bits
)
599 v
[SIDE_INTEGER128_SPLIT_HIGH
] <<= 64 - bits
;
600 for (bit
= 0; bit
< bits
; bit
++) {
601 printf("%c", v
[SIDE_INTEGER128_SPLIT_HIGH
] & (1ULL << 63) ? '1' : '0');
602 v
[SIDE_INTEGER128_SPLIT_HIGH
] <<= 1;
606 v
[SIDE_INTEGER128_SPLIT_LOW
] <<= 64 - bits
;
607 for (bit
= 0; bit
< bits
; bit
++) {
608 printf("%c", v
[SIDE_INTEGER128_SPLIT_LOW
] & (1ULL << 63) ? '1' : '0');
609 v
[SIDE_INTEGER128_SPLIT_LOW
] <<= 1;
614 void tracer_print_type_header(const char *prefix
, const char *separator
,
615 const struct side_attr
*attr
, uint32_t nr_attr
)
617 print_attributes("attr", separator
, attr
, nr_attr
);
618 printf("%s", nr_attr
? ", " : "");
619 printf("%s%s ", prefix
, separator
);
623 void tracer_print_type_bool(const char *separator
,
624 const struct side_type_bool
*type_bool
,
625 const union side_bool_value
*value
,
626 uint16_t offset_bits
)
632 if (!type_bool
->len_bits
)
633 len_bits
= type_bool
->bool_size
* CHAR_BIT
;
635 len_bits
= type_bool
->len_bits
;
636 if (len_bits
+ offset_bits
> type_bool
->bool_size
* CHAR_BIT
)
638 reverse_bo
= side_enum_get(type_bool
->byte_order
) != SIDE_TYPE_BYTE_ORDER_HOST
;
639 switch (type_bool
->bool_size
) {
641 v
= value
->side_bool8
;
647 side_u16
= value
->side_bool16
;
649 side_u16
= side_bswap_16(side_u16
);
657 side_u32
= value
->side_bool32
;
659 side_u32
= side_bswap_32(side_u32
);
667 side_u64
= value
->side_bool64
;
669 side_u64
= side_bswap_64(side_u64
);
678 v
&= (1ULL << len_bits
) - 1;
679 tracer_print_type_header("value", separator
, side_ptr_get(type_bool
->attr
), type_bool
->nr_attr
);
680 printf("%s", v
? "true" : "false");
684 #define U128_BASE_10_ARRAY_LEN sizeof("340282366920938463463374607431768211455")
686 #define S128_BASE_10_ARRAY_LEN sizeof("-170141183460469231731687303715884105728")
689 * u128_tostring_base_10 is inspired from https://stackoverflow.com/a/4364365
692 void u128_tostring_base_10(union int_value v
, char str
[U128_BASE_10_ARRAY_LEN
])
694 int d
[39] = {}, i
, j
, str_i
= 0;
696 for (i
= 63; i
> -1; i
--) {
697 if ((v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] >> i
) & 1)
699 for (j
= 0; j
< 39; j
++)
701 for (j
= 0; j
< 38; j
++) {
702 d
[j
+ 1] += d
[j
] / 10;
706 for (i
= 63; i
> -1; i
--) {
707 if ((v
.u
[SIDE_INTEGER128_SPLIT_LOW
] >> i
) & 1)
710 for (j
= 0; j
< 39; j
++)
713 for (j
= 0; j
< 38; j
++) {
714 d
[j
+ 1] += d
[j
] / 10;
718 for (i
= 38; i
> 0; i
--)
721 for (; i
> -1; i
--) {
722 str
[str_i
++] = '0' + d
[i
];
728 void s128_tostring_base_10(union int_value v
, char str
[S128_BASE_10_ARRAY_LEN
])
730 uint64_t low
, high
, tmp
;
732 if (v
.s
[SIDE_INTEGER128_SPLIT_HIGH
] >= 0) {
734 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = (uint64_t) v
.s
[SIDE_INTEGER128_SPLIT_LOW
];
735 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = (uint64_t) v
.s
[SIDE_INTEGER128_SPLIT_HIGH
];
736 u128_tostring_base_10(v
, str
);
742 /* Special-case minimum value, which has no positive signed representation. */
743 if ((v
.s
[SIDE_INTEGER128_SPLIT_HIGH
] == INT64_MIN
) && (v
.s
[SIDE_INTEGER128_SPLIT_LOW
] == 0)) {
744 memcpy(str
, "-170141183460469231731687303715884105728", S128_BASE_10_ARRAY_LEN
);
747 /* Convert from two's complement. */
748 high
= ~(uint64_t) v
.s
[SIDE_INTEGER128_SPLIT_HIGH
];
749 low
= ~(uint64_t) v
.s
[SIDE_INTEGER128_SPLIT_LOW
];
753 /* Clear overflow to sign bit. */
754 high
&= ~0x8000000000000000ULL
;
756 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = tmp
;
757 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = high
;
759 u128_tostring_base_10(v
, str
+ 1);
763 #define U128_BASE_8_ARRAY_LEN sizeof("3777777777777777777777777777777777777777777")
766 void u128_tostring_base_8(union int_value v
, char str
[U128_BASE_8_ARRAY_LEN
])
768 int d
[43] = {}, i
, j
, str_i
= 0;
770 for (i
= 63; i
> -1; i
--) {
771 if ((v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] >> i
) & 1)
773 for (j
= 0; j
< 43; j
++)
775 for (j
= 0; j
< 42; j
++) {
776 d
[j
+ 1] += d
[j
] / 8;
780 for (i
= 63; i
> -1; i
--) {
781 if ((v
.u
[SIDE_INTEGER128_SPLIT_LOW
] >> i
) & 1)
784 for (j
= 0; j
< 43; j
++)
787 for (j
= 0; j
< 42; j
++) {
788 d
[j
+ 1] += d
[j
] / 8;
792 for (i
= 42; i
> 0; i
--)
795 for (; i
> -1; i
--) {
796 str
[str_i
++] = '0' + d
[i
];
802 void tracer_print_type_integer(const char *separator
,
803 const struct side_type_integer
*type_integer
,
804 const union side_integer_value
*value
,
805 uint16_t offset_bits
,
806 enum tracer_display_base default_base
)
808 enum tracer_display_base base
;
812 v
= tracer_load_integer_value(type_integer
, value
, offset_bits
, &len_bits
);
813 tracer_print_type_header("value", separator
, side_ptr_get(type_integer
->attr
), type_integer
->nr_attr
);
814 base
= get_attr_display_base(side_ptr_get(type_integer
->attr
), type_integer
->nr_attr
, default_base
);
816 case TRACER_DISPLAY_BASE_2
:
817 print_integer_binary(v
.u
, len_bits
);
819 case TRACER_DISPLAY_BASE_8
:
820 /* Clear sign bits beyond len_bits */
822 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] &= (1ULL << len_bits
) - 1;
823 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = 0;
824 } else if (len_bits
< 128) {
825 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] &= (1ULL << (len_bits
- 64)) - 1;
827 if (len_bits
<= 64) {
828 printf("0o%" PRIo64
, v
.u
[SIDE_INTEGER128_SPLIT_LOW
]);
830 char str
[U128_BASE_8_ARRAY_LEN
];
832 u128_tostring_base_8(v
, str
);
836 case TRACER_DISPLAY_BASE_10
:
837 if (len_bits
<= 64) {
838 if (type_integer
->signedness
)
839 printf("%" PRId64
, v
.s
[SIDE_INTEGER128_SPLIT_LOW
]);
841 printf("%" PRIu64
, v
.u
[SIDE_INTEGER128_SPLIT_LOW
]);
843 if (type_integer
->signedness
) {
844 char str
[S128_BASE_10_ARRAY_LEN
];
845 s128_tostring_base_10(v
, str
);
848 char str
[U128_BASE_10_ARRAY_LEN
];
849 u128_tostring_base_10(v
, str
);
854 case TRACER_DISPLAY_BASE_16
:
855 /* Clear sign bits beyond len_bits */
857 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] &= (1ULL << len_bits
) - 1;
858 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] = 0;
859 } else if (len_bits
< 128) {
860 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] &= (1ULL << (len_bits
- 64)) - 1;
862 if (len_bits
<= 64 || v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] == 0) {
863 printf("0x%" PRIx64
, v
.u
[SIDE_INTEGER128_SPLIT_LOW
]);
865 printf("0x%" PRIx64
"%016" PRIx64
,
866 v
.u
[SIDE_INTEGER128_SPLIT_HIGH
],
867 v
.u
[SIDE_INTEGER128_SPLIT_LOW
]);
876 void tracer_print_type_float(const char *separator
,
877 const struct side_type_float
*type_float
,
878 const union side_float_value
*value
)
882 tracer_print_type_header("value", separator
, side_ptr_get(type_float
->attr
), type_float
->nr_attr
);
883 reverse_bo
= side_enum_get(type_float
->byte_order
) != SIDE_TYPE_FLOAT_WORD_ORDER_HOST
;
884 switch (type_float
->float_size
) {
892 .f
= value
->side_float_binary16
,
896 float16
.u
= side_bswap_16(float16
.u
);
897 printf("%g", (double) float16
.f
);
900 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
911 .f
= value
->side_float_binary32
,
915 float32
.u
= side_bswap_32(float32
.u
);
916 printf("%g", (double) float32
.f
);
919 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
930 .f
= value
->side_float_binary64
,
934 float64
.u
= side_bswap_64(float64
.u
);
935 printf("%g", (double) float64
.f
);
938 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
949 .f
= value
->side_float_binary128
,
953 side_bswap_128p(float128
.arr
);
954 printf("%Lg", (long double) float128
.f
);
957 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
962 fprintf(stderr
, "ERROR: Unknown float size\n");
968 void push_nesting(struct print_ctx
*ctx
)
970 if (++ctx
->nesting
>= MAX_NESTING
) {
971 fprintf(stderr
, "ERROR: Nesting too deep.\n");
974 ctx
->item_nr
[ctx
->nesting
] = 0;
978 void pop_nesting(struct print_ctx
*ctx
)
980 ctx
->item_nr
[ctx
->nesting
] = 0;
981 if (ctx
->nesting
-- <= 0) {
982 fprintf(stderr
, "ERROR: Nesting underflow.\n");
988 int get_nested_item_nr(struct print_ctx
*ctx
)
990 return ctx
->item_nr
[ctx
->nesting
];
994 void inc_nested_item_nr(struct print_ctx
*ctx
)
996 ctx
->item_nr
[ctx
->nesting
]++;
1000 void tracer_before_print_event(const struct side_event_description
*desc
,
1001 const struct side_arg_vec
*side_arg_vec
,
1002 const struct side_arg_dynamic_struct
*var_struct
__attribute__((unused
)),
1003 void *caller_addr
, void *priv
__attribute__((unused
)))
1005 uint32_t side_sav_len
= side_arg_vec
->len
;
1007 if (desc
->nr_fields
!= side_sav_len
) {
1008 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1013 printf("caller: [%p], ", caller_addr
);
1014 printf("provider: %s, event: %s",
1015 side_ptr_get(desc
->provider_name
),
1016 side_ptr_get(desc
->event_name
));
1017 print_attributes(", attr", ":", side_ptr_get(desc
->attr
), desc
->nr_attr
);
1021 void tracer_after_print_event(const struct side_event_description
*desc
__attribute__((unused
)),
1022 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)),
1023 const struct side_arg_dynamic_struct
*var_struct
__attribute__((unused
)),
1024 void *caller_addr
__attribute__((unused
)), void *priv
__attribute__((unused
)))
1030 void tracer_before_print_static_fields(const struct side_arg_vec
*side_arg_vec
, void *priv
)
1032 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1033 uint32_t side_sav_len
= side_arg_vec
->len
;
1035 printf("%s", side_sav_len
? ", fields: {" : "");
1041 void tracer_after_print_static_fields(const struct side_arg_vec
*side_arg_vec
, void *priv
)
1043 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1044 uint32_t side_sav_len
= side_arg_vec
->len
;
1052 void tracer_before_print_variadic_fields(const struct side_arg_dynamic_struct
*var_struct
,
1055 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1056 uint32_t var_struct_len
= var_struct
->len
;
1058 print_attributes(", attr ", "::", side_ptr_get(var_struct
->attr
), var_struct
->nr_attr
);
1059 printf("%s", var_struct_len
? ", fields:: {" : "");
1064 void tracer_after_print_variadic_fields(const struct side_arg_dynamic_struct
*var_struct
, void *priv
)
1066 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1067 uint32_t var_struct_len
= var_struct
->len
;
1075 void tracer_before_print_field(const struct side_event_field
*item_desc
, void *priv
)
1077 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1079 if (get_nested_item_nr(ctx
) != 0)
1081 printf(" %s: { ", side_ptr_get(item_desc
->field_name
));
1085 void tracer_after_print_field(const struct side_event_field
*item_desc
__attribute__((unused
)), void *priv
)
1087 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1090 inc_nested_item_nr(ctx
);
1094 void tracer_before_print_elem(const struct side_type
*type_desc
__attribute__((unused
)), void *priv
)
1096 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1098 if (get_nested_item_nr(ctx
) != 0)
1105 void tracer_after_print_elem(const struct side_type
*type_desc
__attribute__((unused
)), void *priv
)
1107 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1110 inc_nested_item_nr(ctx
);
1114 void tracer_print_null(const struct side_type
*type_desc
,
1115 const struct side_arg
*item
__attribute__((unused
)),
1116 void *priv
__attribute__((unused
)))
1118 tracer_print_type_header("value", ":", side_ptr_get(type_desc
->u
.side_null
.attr
),
1119 type_desc
->u
.side_null
.nr_attr
);
1120 printf("<NULL TYPE>");
1124 void tracer_print_bool(const struct side_type
*type_desc
,
1125 const struct side_arg
*item
,
1126 void *priv
__attribute__((unused
)))
1128 tracer_print_type_bool(":", &type_desc
->u
.side_bool
, &item
->u
.side_static
.bool_value
, 0);
1132 void tracer_print_integer(const struct side_type
*type_desc
,
1133 const struct side_arg
*item
,
1134 void *priv
__attribute__((unused
)))
1136 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0, TRACER_DISPLAY_BASE_10
);
1140 void tracer_print_byte(const struct side_type
*type_desc
__attribute__((unused
)),
1141 const struct side_arg
*item
,
1142 void *priv
__attribute__((unused
)))
1144 tracer_print_type_header("value", ":", side_ptr_get(type_desc
->u
.side_byte
.attr
), type_desc
->u
.side_byte
.nr_attr
);
1145 printf("0x%" PRIx8
, item
->u
.side_static
.byte_value
);
1149 void tracer_print_pointer(const struct side_type
*type_desc
,
1150 const struct side_arg
*item
,
1151 void *priv
__attribute__((unused
)))
1153 tracer_print_type_integer(":", &type_desc
->u
.side_integer
, &item
->u
.side_static
.integer_value
, 0, TRACER_DISPLAY_BASE_16
);
1157 void tracer_print_float(const struct side_type
*type_desc
,
1158 const struct side_arg
*item
,
1159 void *priv
__attribute__((unused
)))
1161 tracer_print_type_float(":", &type_desc
->u
.side_float
, &item
->u
.side_static
.float_value
);
1165 void tracer_print_string(const struct side_type
*type_desc
,
1166 const struct side_arg
*item
,
1167 void *priv
__attribute__((unused
)))
1169 tracer_print_type_header("value", ":", side_ptr_get(type_desc
->u
.side_string
.attr
), type_desc
->u
.side_string
.nr_attr
);
1170 tracer_print_type_string(side_ptr_get(item
->u
.side_static
.string_value
),
1171 type_desc
->u
.side_string
.unit_size
,
1172 side_enum_get(type_desc
->u
.side_string
.byte_order
), NULL
);
1176 void tracer_before_print_struct(const struct side_type_struct
*side_struct
,
1177 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)), void *priv
)
1179 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1181 print_attributes("attr", ":", side_ptr_get(side_struct
->attr
), side_struct
->nr_attr
);
1182 printf("%s", side_struct
->nr_attr
? ", " : "");
1183 printf("fields: {");
1189 void tracer_after_print_struct(const struct side_type_struct
*side_struct
__attribute__((unused
)),
1190 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)), void *priv
)
1192 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1199 void tracer_before_print_array(const struct side_type_array
*side_array
,
1200 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)), void *priv
)
1202 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1204 print_attributes("attr", ":", side_ptr_get(side_array
->attr
), side_array
->nr_attr
);
1205 printf("%s", side_array
->nr_attr
? ", " : "");
1206 printf("elements: [");
1211 void tracer_after_print_array(const struct side_type_array
*side_array
__attribute__((unused
)),
1212 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)), void *priv
)
1214 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1221 void do_tracer_before_print_vla(const struct side_type_vla
*side_vla
,
1222 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)), void *priv
)
1224 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1226 print_attributes("attr", ":", side_ptr_get(side_vla
->attr
), side_vla
->nr_attr
);
1227 printf("%s", side_vla
->nr_attr
? ", " : "");
1228 printf("elements: [");
1234 void do_tracer_after_print_vla(const struct side_type_vla
*side_vla
__attribute__((unused
)),
1235 const struct side_arg_vec
*side_arg_vec
__attribute__((unused
)), void *priv
)
1237 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1244 void tracer_before_print_vla(const struct side_type_vla
*side_vla
,
1245 const struct side_arg_vec
*side_arg_vec
, void *priv
)
1247 switch (side_enum_get(side_ptr_get(side_vla
->length_type
)->type
)) {
1248 case SIDE_TYPE_U8
: /* Fall-through */
1249 case SIDE_TYPE_U16
: /* Fall-through */
1250 case SIDE_TYPE_U32
: /* Fall-through */
1251 case SIDE_TYPE_U64
: /* Fall-through */
1252 case SIDE_TYPE_U128
: /* Fall-through */
1253 case SIDE_TYPE_S8
: /* Fall-through */
1254 case SIDE_TYPE_S16
: /* Fall-through */
1255 case SIDE_TYPE_S32
: /* Fall-through */
1256 case SIDE_TYPE_S64
: /* Fall-through */
1257 case SIDE_TYPE_S128
:
1260 fprintf(stderr
, "ERROR: Unexpected vla length type\n");
1263 do_tracer_before_print_vla(side_vla
, side_arg_vec
, priv
);
1267 void tracer_after_print_vla(const struct side_type_vla
*side_vla
,
1268 const struct side_arg_vec
*side_arg_vec
, void *priv
)
1270 do_tracer_after_print_vla(side_vla
, side_arg_vec
, priv
);
1274 void tracer_before_print_vla_visitor(const struct side_type_vla_visitor
*side_vla_visitor
,
1275 const struct side_arg_vla_visitor
*side_arg_vla_visitor
__attribute__((unused
)), void *priv
)
1277 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1279 switch (side_enum_get(side_ptr_get(side_vla_visitor
->length_type
)->type
)) {
1280 case SIDE_TYPE_U8
: /* Fall-through */
1281 case SIDE_TYPE_U16
: /* Fall-through */
1282 case SIDE_TYPE_U32
: /* Fall-through */
1283 case SIDE_TYPE_U64
: /* Fall-through */
1284 case SIDE_TYPE_U128
: /* Fall-through */
1285 case SIDE_TYPE_S8
: /* Fall-through */
1286 case SIDE_TYPE_S16
: /* Fall-through */
1287 case SIDE_TYPE_S32
: /* Fall-through */
1288 case SIDE_TYPE_S64
: /* Fall-through */
1289 case SIDE_TYPE_S128
:
1292 fprintf(stderr
, "ERROR: Unexpected vla visitor length type\n");
1296 print_attributes("attr", ":", side_ptr_get(side_vla_visitor
->attr
), side_vla_visitor
->nr_attr
);
1297 printf("%s", side_vla_visitor
->nr_attr
? ", " : "");
1298 printf("elements: [");
1303 void tracer_after_print_vla_visitor(const struct side_type_vla_visitor
*side_vla_visitor
__attribute__((unused
)),
1304 const struct side_arg_vla_visitor
*side_arg_vla_visitor
__attribute__((unused
)), void *priv
)
1306 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1312 static void tracer_print_enum(const struct side_type
*type_desc
,
1313 const struct side_arg
*item
, void *priv
)
1315 const struct side_enum_mappings
*mappings
= side_ptr_get(type_desc
->u
.side_enum
.mappings
);
1316 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum
.elem_type
);
1319 if (side_enum_get(elem_type
->type
) != side_enum_get(item
->type
)) {
1320 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
1323 v
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
1324 &item
->u
.side_static
.integer_value
, 0, NULL
);
1325 print_attributes("attr", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
1326 printf("%s", mappings
->nr_attr
? ", " : "");
1328 tracer_print_integer(elem_type
, item
, priv
);
1330 print_enum_labels(mappings
, v
);
1333 static void tracer_print_enum_bitmap(const struct side_type
*type_desc
,
1334 const struct side_arg
*item
, void *priv
__attribute__((unused
)))
1336 const struct side_enum_bitmap_mappings
*side_enum_mappings
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.mappings
);
1337 const struct side_type
*enum_elem_type
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.elem_type
), *elem_type
;
1338 uint32_t i
, print_count
= 0, stride_bit
, nr_items
;
1339 const struct side_arg
*array_item
;
1341 switch (side_enum_get(enum_elem_type
->type
)) {
1342 case SIDE_TYPE_U8
: /* Fall-through */
1343 case SIDE_TYPE_BYTE
: /* Fall-through */
1344 case SIDE_TYPE_U16
: /* Fall-through */
1345 case SIDE_TYPE_U32
: /* Fall-through */
1346 case SIDE_TYPE_U64
: /* Fall-through */
1347 case SIDE_TYPE_U128
: /* Fall-through */
1348 case SIDE_TYPE_S8
: /* Fall-through */
1349 case SIDE_TYPE_S16
: /* Fall-through */
1350 case SIDE_TYPE_S32
: /* Fall-through */
1351 case SIDE_TYPE_S64
: /* Fall-through */
1352 case SIDE_TYPE_S128
:
1353 elem_type
= enum_elem_type
;
1357 case SIDE_TYPE_ARRAY
:
1358 elem_type
= side_ptr_get(enum_elem_type
->u
.side_array
.elem_type
);
1359 array_item
= side_ptr_get(side_ptr_get(item
->u
.side_static
.side_array
)->sav
);
1360 nr_items
= type_desc
->u
.side_array
.length
;
1363 elem_type
= side_ptr_get(enum_elem_type
->u
.side_vla
.elem_type
);
1364 array_item
= side_ptr_get(side_ptr_get(item
->u
.side_static
.side_vla
)->sav
);
1365 nr_items
= side_ptr_get(item
->u
.side_static
.side_vla
)->len
;
1368 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
1371 stride_bit
= elem_type_to_stride(elem_type
);
1373 print_attributes("attr", ":", side_ptr_get(side_enum_mappings
->attr
), side_enum_mappings
->nr_attr
);
1374 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
1375 printf("labels: [ ");
1376 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
1377 const struct side_enum_bitmap_mapping
*mapping
= &side_ptr_get(side_enum_mappings
->mappings
)[i
];
1381 if (mapping
->range_end
< mapping
->range_begin
) {
1382 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
1383 mapping
->range_begin
, mapping
->range_end
);
1386 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
1387 if (bit
> (nr_items
* stride_bit
) - 1)
1389 if (side_enum_get(elem_type
->type
) == SIDE_TYPE_BYTE
) {
1390 uint8_t v
= array_item
[bit
/ 8].u
.side_static
.byte_value
;
1391 if (v
& (1ULL << (bit
% 8))) {
1396 union int_value v
= {};
1398 v
= tracer_load_integer_value(&elem_type
->u
.side_integer
,
1399 &array_item
[bit
/ stride_bit
].u
.side_static
.integer_value
,
1401 side_check_value_u64(v
);
1402 if (v
.u
[SIDE_INTEGER128_SPLIT_LOW
] & (1ULL << (bit
% stride_bit
))) {
1410 printf("%s", print_count
++ ? ", " : "");
1411 tracer_print_type_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
,
1412 side_enum_get(mapping
->label
.byte_order
), NULL
);
1416 printf("<NO LABEL>");
1421 void tracer_print_gather_bool(const struct side_type_gather_bool
*type
,
1422 const union side_bool_value
*value
,
1423 void *priv
__attribute__((unused
)))
1425 tracer_print_type_bool(":", &type
->type
, value
, type
->offset_bits
);
1429 void tracer_print_gather_byte(const struct side_type_gather_byte
*type
,
1430 const uint8_t *_ptr
,
1431 void *priv
__attribute__((unused
)))
1433 tracer_print_type_header("value", ":", side_ptr_get(type
->type
.attr
),
1434 type
->type
.nr_attr
);
1435 printf("0x%" PRIx8
, *_ptr
);
1439 void tracer_print_gather_integer(const struct side_type_gather_integer
*type
,
1440 const union side_integer_value
*value
,
1441 void *priv
__attribute__((unused
)))
1443 tracer_print_type_integer(":", &type
->type
, value
, type
->offset_bits
, TRACER_DISPLAY_BASE_10
);
1447 void tracer_print_gather_pointer(const struct side_type_gather_integer
*type
,
1448 const union side_integer_value
*value
,
1449 void *priv
__attribute__((unused
)))
1451 tracer_print_type_integer(":", &type
->type
, value
, type
->offset_bits
, TRACER_DISPLAY_BASE_16
);
1455 void tracer_print_gather_float(const struct side_type_gather_float
*type
,
1456 const union side_float_value
*value
,
1457 void *priv
__attribute__((unused
)))
1459 tracer_print_type_float(":", &type
->type
, value
);
1463 void tracer_print_gather_string(const struct side_type_gather_string
*type
,
1464 const void *p
, uint8_t unit_size
,
1465 enum side_type_label_byte_order byte_order
,
1466 size_t strlen_with_null
__attribute__((unused
)),
1467 void *priv
__attribute__((unused
)))
1469 //TODO use strlen_with_null input
1470 tracer_print_type_header("value", ":", side_ptr_get(type
->type
.attr
),
1471 type
->type
.nr_attr
);
1472 tracer_print_type_string(p
, unit_size
, byte_order
, NULL
);
1476 void tracer_before_print_gather_struct(const struct side_type_struct
*side_struct
, void *priv
)
1478 tracer_before_print_struct(side_struct
, NULL
, priv
);
1482 void tracer_after_print_gather_struct(const struct side_type_struct
*side_struct
, void *priv
)
1484 tracer_after_print_struct(side_struct
, NULL
, priv
);
1488 void tracer_before_print_gather_array(const struct side_type_array
*side_array
, void *priv
)
1490 tracer_before_print_array(side_array
, NULL
, priv
);
1494 void tracer_after_print_gather_array(const struct side_type_array
*side_array
, void *priv
)
1496 tracer_after_print_array(side_array
, NULL
, priv
);
1500 void tracer_before_print_gather_vla(const struct side_type_vla
*side_vla
,
1501 uint32_t length
__attribute__((unused
)), void *priv
)
1503 switch (side_enum_get(side_ptr_get(side_vla
->length_type
)->type
)) {
1504 case SIDE_TYPE_GATHER_INTEGER
:
1507 fprintf(stderr
, "ERROR: Unexpected vla length type\n");
1510 do_tracer_before_print_vla(side_vla
, NULL
, priv
);
1515 void tracer_after_print_gather_vla(const struct side_type_vla
*side_vla
,
1516 uint32_t length
__attribute__((unused
)), void *priv
)
1518 do_tracer_after_print_vla(side_vla
, NULL
, priv
);
1522 void tracer_print_gather_enum(const struct side_type_gather_enum
*type
,
1523 const union side_integer_value
*value
,
1524 void *priv
__attribute__((unused
)))
1526 const struct side_enum_mappings
*mappings
= side_ptr_get(type
->mappings
);
1527 const struct side_type
*enum_elem_type
= side_ptr_get(type
->elem_type
);
1528 const struct side_type_gather_integer
*side_integer
= &enum_elem_type
->u
.side_gather
.u
.side_integer
;
1531 v
= tracer_load_integer_value(&side_integer
->type
, value
, 0, NULL
);
1532 print_attributes("attr", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
1533 printf("%s", mappings
->nr_attr
? ", " : "");
1535 tracer_print_type_integer(":", &side_integer
->type
, value
, 0, TRACER_DISPLAY_BASE_10
);
1537 print_enum_labels(mappings
, v
);
1541 void tracer_before_print_dynamic_field(const struct side_arg_dynamic_field
*field
, void *priv
)
1543 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1545 if (get_nested_item_nr(ctx
) != 0)
1547 printf(" %s:: { ", side_ptr_get(field
->field_name
));
1551 void tracer_after_print_dynamic_field(const struct side_arg_dynamic_field
*field
__attribute__((unused
)), void *priv
)
1553 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1556 inc_nested_item_nr(ctx
);
1560 void tracer_before_print_dynamic_elem(const struct side_arg
*dynamic_item
__attribute__((unused
)), void *priv
)
1562 tracer_before_print_elem(NULL
, priv
);
1566 void tracer_after_print_dynamic_elem(const struct side_arg
*dynamic_item
__attribute__((unused
)), void *priv
)
1568 tracer_after_print_elem(NULL
, priv
);
1572 void tracer_print_dynamic_null(const struct side_arg
*item
,
1573 void *priv
__attribute__((unused
)))
1575 tracer_print_type_header("value", "::", side_ptr_get(item
->u
.side_dynamic
.side_null
.attr
),
1576 item
->u
.side_dynamic
.side_null
.nr_attr
);
1577 printf("<NULL TYPE>");
1581 void tracer_print_dynamic_bool(const struct side_arg
*item
,
1582 void *priv
__attribute__((unused
)))
1584 tracer_print_type_bool("::", &item
->u
.side_dynamic
.side_bool
.type
, &item
->u
.side_dynamic
.side_bool
.value
, 0);
1588 void tracer_print_dynamic_integer(const struct side_arg
*item
,
1589 void *priv
__attribute__((unused
)))
1591 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1592 TRACER_DISPLAY_BASE_10
);
1596 void tracer_print_dynamic_byte(const struct side_arg
*item
,
1597 void *priv
__attribute__((unused
)))
1599 tracer_print_type_header("value", "::", side_ptr_get(item
->u
.side_dynamic
.side_byte
.type
.attr
), item
->u
.side_dynamic
.side_byte
.type
.nr_attr
);
1600 printf("0x%" PRIx8
, item
->u
.side_dynamic
.side_byte
.value
);
1604 void tracer_print_dynamic_pointer(const struct side_arg
*item
,
1605 void *priv
__attribute__((unused
)))
1607 tracer_print_type_integer("::", &item
->u
.side_dynamic
.side_integer
.type
, &item
->u
.side_dynamic
.side_integer
.value
, 0,
1608 TRACER_DISPLAY_BASE_16
);
1612 void tracer_print_dynamic_float(const struct side_arg
*item
,
1613 void *priv
__attribute__((unused
)))
1615 tracer_print_type_float("::", &item
->u
.side_dynamic
.side_float
.type
,
1616 &item
->u
.side_dynamic
.side_float
.value
);
1620 void tracer_print_dynamic_string(const struct side_arg
*item
,
1621 void *priv
__attribute__((unused
)))
1623 tracer_print_type_header("value", "::", side_ptr_get(item
->u
.side_dynamic
.side_string
.type
.attr
), item
->u
.side_dynamic
.side_string
.type
.nr_attr
);
1624 tracer_print_type_string((const char *)(uintptr_t) item
->u
.side_dynamic
.side_string
.value
,
1625 item
->u
.side_dynamic
.side_string
.type
.unit_size
,
1626 side_enum_get(item
->u
.side_dynamic
.side_string
.type
.byte_order
), NULL
);
1630 void tracer_before_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
,
1633 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1635 print_attributes("attr", "::", side_ptr_get(dynamic_struct
->attr
), dynamic_struct
->nr_attr
);
1636 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1637 printf("fields:: {");
1642 void tracer_after_print_dynamic_struct(const struct side_arg_dynamic_struct
*dynamic_struct
__attribute__((unused
)),
1645 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1652 void tracer_before_print_dynamic_struct_visitor(const struct side_arg
*item
, void *priv
)
1654 struct side_arg_dynamic_struct_visitor
*dynamic_struct_visitor
;
1655 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1657 dynamic_struct_visitor
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct_visitor
);
1658 if (!dynamic_struct_visitor
)
1661 print_attributes("attr", "::", side_ptr_get(dynamic_struct_visitor
->attr
), dynamic_struct_visitor
->nr_attr
);
1662 printf("%s", dynamic_struct_visitor
->nr_attr
? ", " : "");
1663 printf("fields:: {");
1668 void tracer_after_print_dynamic_struct_visitor(const struct side_arg
*item
, void *priv
)
1670 struct side_arg_dynamic_struct_visitor
*dynamic_struct_visitor
;
1671 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1673 dynamic_struct_visitor
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_struct_visitor
);
1674 if (!dynamic_struct_visitor
)
1682 void tracer_before_print_dynamic_vla(const struct side_arg_dynamic_vla
*dynamic_vla
, void *priv
)
1684 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1686 print_attributes("attr", "::", side_ptr_get(dynamic_vla
->attr
), dynamic_vla
->nr_attr
);
1687 printf("%s", dynamic_vla
->nr_attr
? ", " : "");
1688 printf("elements:: [");
1693 void tracer_after_print_dynamic_vla(const struct side_arg_dynamic_vla
*dynamic_vla
__attribute__((unused
)), void *priv
)
1695 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1702 void tracer_before_print_dynamic_vla_visitor(const struct side_arg
*item
, void *priv
)
1704 struct side_arg_dynamic_vla_visitor
*dynamic_vla_visitor
;
1705 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1707 dynamic_vla_visitor
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla_visitor
);
1708 if (!dynamic_vla_visitor
)
1711 print_attributes("attr", "::", side_ptr_get(dynamic_vla_visitor
->attr
), dynamic_vla_visitor
->nr_attr
);
1712 printf("%s", dynamic_vla_visitor
->nr_attr
? ", " : "");
1713 printf("elements:: [");
1718 void tracer_after_print_dynamic_vla_visitor(const struct side_arg
*item
, void *priv
)
1720 struct side_arg_dynamic_vla_visitor
*dynamic_vla_visitor
;
1721 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1723 dynamic_vla_visitor
= side_ptr_get(item
->u
.side_dynamic
.side_dynamic_vla_visitor
);
1724 if (!dynamic_vla_visitor
)
1731 static struct side_type_visitor type_visitor
= {
1732 .before_event_func
= tracer_before_print_event
,
1733 .after_event_func
= tracer_after_print_event
,
1734 .before_static_fields_func
= tracer_before_print_static_fields
,
1735 .after_static_fields_func
= tracer_after_print_static_fields
,
1736 .before_variadic_fields_func
= tracer_before_print_variadic_fields
,
1737 .after_variadic_fields_func
= tracer_after_print_variadic_fields
,
1739 /* Stack-copy basic types. */
1740 .before_field_func
= tracer_before_print_field
,
1741 .after_field_func
= tracer_after_print_field
,
1742 .before_elem_func
= tracer_before_print_elem
,
1743 .after_elem_func
= tracer_after_print_elem
,
1744 .null_type_func
= tracer_print_null
,
1745 .bool_type_func
= tracer_print_bool
,
1746 .integer_type_func
= tracer_print_integer
,
1747 .byte_type_func
= tracer_print_byte
,
1748 .pointer_type_func
= tracer_print_pointer
,
1749 .float_type_func
= tracer_print_float
,
1750 .string_type_func
= tracer_print_string
,
1752 /* Stack-copy compound types. */
1753 .before_struct_type_func
= tracer_before_print_struct
,
1754 .after_struct_type_func
= tracer_after_print_struct
,
1755 .before_array_type_func
= tracer_before_print_array
,
1756 .after_array_type_func
= tracer_after_print_array
,
1757 .before_vla_type_func
= tracer_before_print_vla
,
1758 .after_vla_type_func
= tracer_after_print_vla
,
1759 .before_vla_visitor_type_func
= tracer_before_print_vla_visitor
,
1760 .after_vla_visitor_type_func
= tracer_after_print_vla_visitor
,
1762 /* Stack-copy enumeration types. */
1763 .enum_type_func
= tracer_print_enum
,
1764 .enum_bitmap_type_func
= tracer_print_enum_bitmap
,
1766 /* Gather basic types. */
1767 .gather_bool_type_func
= tracer_print_gather_bool
,
1768 .gather_byte_type_func
= tracer_print_gather_byte
,
1769 .gather_integer_type_func
= tracer_print_gather_integer
,
1770 .gather_pointer_type_func
= tracer_print_gather_pointer
,
1771 .gather_float_type_func
= tracer_print_gather_float
,
1772 .gather_string_type_func
= tracer_print_gather_string
,
1774 /* Gather compound types. */
1775 .before_gather_struct_type_func
= tracer_before_print_gather_struct
,
1776 .after_gather_struct_type_func
= tracer_after_print_gather_struct
,
1777 .before_gather_array_type_func
= tracer_before_print_gather_array
,
1778 .after_gather_array_type_func
= tracer_after_print_gather_array
,
1779 .before_gather_vla_type_func
= tracer_before_print_gather_vla
,
1780 .after_gather_vla_type_func
= tracer_after_print_gather_vla
,
1782 /* Gather enumeration types. */
1783 .gather_enum_type_func
= tracer_print_gather_enum
,
1785 /* Dynamic basic types. */
1786 .before_dynamic_field_func
= tracer_before_print_dynamic_field
,
1787 .after_dynamic_field_func
= tracer_after_print_dynamic_field
,
1788 .before_dynamic_elem_func
= tracer_before_print_dynamic_elem
,
1789 .after_dynamic_elem_func
= tracer_after_print_dynamic_elem
,
1791 .dynamic_null_func
= tracer_print_dynamic_null
,
1792 .dynamic_bool_func
= tracer_print_dynamic_bool
,
1793 .dynamic_integer_func
= tracer_print_dynamic_integer
,
1794 .dynamic_byte_func
= tracer_print_dynamic_byte
,
1795 .dynamic_pointer_func
= tracer_print_dynamic_pointer
,
1796 .dynamic_float_func
= tracer_print_dynamic_float
,
1797 .dynamic_string_func
= tracer_print_dynamic_string
,
1799 /* Dynamic compound types. */
1800 .before_dynamic_struct_func
= tracer_before_print_dynamic_struct
,
1801 .after_dynamic_struct_func
= tracer_after_print_dynamic_struct
,
1802 .before_dynamic_struct_visitor_func
= tracer_before_print_dynamic_struct_visitor
,
1803 .after_dynamic_struct_visitor_func
= tracer_after_print_dynamic_struct_visitor
,
1804 .before_dynamic_vla_func
= tracer_before_print_dynamic_vla
,
1805 .after_dynamic_vla_func
= tracer_after_print_dynamic_vla
,
1806 .before_dynamic_vla_visitor_func
= tracer_before_print_dynamic_vla_visitor
,
1807 .after_dynamic_vla_visitor_func
= tracer_after_print_dynamic_vla_visitor
,
1811 void tracer_call(const struct side_event_description
*desc
,
1812 const struct side_arg_vec
*side_arg_vec
,
1813 void *priv
__attribute__((unused
)),
1816 struct print_ctx ctx
= {};
1818 type_visitor_event(&type_visitor
, desc
, side_arg_vec
, NULL
, caller_addr
, &ctx
);
1822 void tracer_call_variadic(const struct side_event_description
*desc
,
1823 const struct side_arg_vec
*side_arg_vec
,
1824 const struct side_arg_dynamic_struct
*var_struct
,
1825 void *priv
__attribute__((unused
)),
1828 struct print_ctx ctx
= {};
1830 type_visitor_event(&type_visitor
, desc
, side_arg_vec
, var_struct
, caller_addr
, &ctx
);
1834 void before_print_description_event(const struct side_event_description
*desc
, void *priv
__attribute__((unused
)))
1836 printf("event description: provider: %s, event: %s", side_ptr_get(desc
->provider_name
), side_ptr_get(desc
->event_name
));
1837 print_attributes(", attr", ":", side_ptr_get(desc
->attr
), desc
->nr_attr
);
1841 void after_print_description_event(const struct side_event_description
*desc
, void *priv
__attribute__((unused
)))
1843 if (desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)
1844 printf(", <variadic fields>");
1849 void before_print_description_static_fields(const struct side_event_description
*desc
, void *priv
)
1851 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1852 uint32_t len
= desc
->nr_fields
;
1854 printf("%s", len
? ", fields: {" : "");
1859 void after_print_description_static_fields(const struct side_event_description
*desc
, void *priv
)
1861 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1862 uint32_t len
= desc
->nr_fields
;
1870 void before_print_description_field(const struct side_event_field
*item_desc
, void *priv
)
1872 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1874 if (get_nested_item_nr(ctx
) != 0)
1876 printf(" %s: { ", side_ptr_get(item_desc
->field_name
));
1880 void after_print_description_field(const struct side_event_field
*item_desc
__attribute__((unused
)), void *priv
)
1882 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1885 inc_nested_item_nr(ctx
);
1889 void before_print_description_elem(const struct side_type
*type_desc
__attribute__((unused
)), void *priv
)
1891 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1893 if (get_nested_item_nr(ctx
) != 0)
1900 void after_print_description_elem(const struct side_type
*type_desc
__attribute__((unused
)), void *priv
)
1902 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1905 inc_nested_item_nr(ctx
);
1909 void before_print_description_option(const struct side_variant_option
*option_desc
, void *priv
)
1911 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1913 if (get_nested_item_nr(ctx
) != 0)
1915 if (option_desc
->range_begin
== option_desc
->range_end
)
1916 printf(" [ %" PRIu64
" ]: { ",
1917 option_desc
->range_begin
);
1919 printf(" [ %" PRIu64
" - %" PRIu64
" ]: { ",
1920 option_desc
->range_begin
,
1921 option_desc
->range_end
);
1925 void after_print_description_option(const struct side_variant_option
*option_desc
__attribute__((unused
)), void *priv
)
1927 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
1930 inc_nested_item_nr(ctx
);
1934 void print_description_null(const struct side_type
*type_desc
,
1935 void *priv
__attribute__((unused
)))
1937 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_null
.attr
),
1938 type_desc
->u
.side_null
.nr_attr
);
1943 void print_description_bool(const struct side_type
*type_desc
,
1944 void *priv
__attribute__((unused
)))
1946 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_bool
.attr
),
1947 type_desc
->u
.side_bool
.nr_attr
);
1948 printf("bool { size: %" PRIu16
, type_desc
->u
.side_bool
.bool_size
);
1949 if (type_desc
->u
.side_bool
.len_bits
)
1950 printf(", len_bits: %" PRIu16
, type_desc
->u
.side_bool
.len_bits
);
1955 void print_description_integer(const struct side_type
*type_desc
,
1956 void *priv
__attribute__((unused
)))
1958 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_integer
.attr
),
1959 type_desc
->u
.side_integer
.nr_attr
);
1960 printf("integer { size: %" PRIu16
", signedness: %s, byte_order: \"%s\"",
1961 type_desc
->u
.side_integer
.integer_size
,
1962 type_desc
->u
.side_integer
.signedness
? "true" : "false",
1963 side_enum_get(type_desc
->u
.side_integer
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
1964 if (type_desc
->u
.side_integer
.len_bits
)
1965 printf(", len_bits: %" PRIu16
, type_desc
->u
.side_integer
.len_bits
);
1970 void print_description_byte(const struct side_type
*type_desc
,
1971 void *priv
__attribute__((unused
)))
1973 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_byte
.attr
),
1974 type_desc
->u
.side_byte
.nr_attr
);
1979 void print_description_pointer(const struct side_type
*type_desc
,
1980 void *priv
__attribute__((unused
)))
1982 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_integer
.attr
),
1983 type_desc
->u
.side_integer
.nr_attr
);
1984 printf("pointer { size: %" PRIu16
", signedness: %s, byte_order: \"%s\"",
1985 type_desc
->u
.side_integer
.integer_size
,
1986 type_desc
->u
.side_integer
.signedness
? "true" : "false",
1987 side_enum_get(type_desc
->u
.side_integer
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
1988 if (type_desc
->u
.side_integer
.len_bits
)
1989 printf(", len_bits: %" PRIu16
, type_desc
->u
.side_integer
.len_bits
);
1994 void print_description_float(const struct side_type
*type_desc
,
1995 void *priv
__attribute__((unused
)))
1997 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_float
.attr
),
1998 type_desc
->u
.side_float
.nr_attr
);
1999 printf("float { size: %" PRIu16
", byte_order: \"%s\"",
2000 type_desc
->u
.side_float
.float_size
,
2001 side_enum_get(type_desc
->u
.side_float
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
2006 void print_description_string(const struct side_type
*type_desc
,
2007 void *priv
__attribute__((unused
)))
2009 tracer_print_type_header("type", ":", side_ptr_get(type_desc
->u
.side_string
.attr
),
2010 type_desc
->u
.side_string
.nr_attr
);
2011 printf("string { unit_size: %" PRIu8
,
2012 type_desc
->u
.side_string
.unit_size
);
2013 if (type_desc
->u
.side_string
.unit_size
> 1)
2014 printf(", byte_order: \"%s\"",
2015 side_enum_get(type_desc
->u
.side_string
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
2020 void before_print_description_struct(const struct side_type_struct
*side_struct
, void *priv
)
2022 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2024 print_attributes("attr", ":", side_ptr_get(side_struct
->attr
), side_struct
->nr_attr
);
2025 printf("%s", side_struct
->nr_attr
? ", " : "");
2026 printf("type: struct { fields: {");
2032 void after_print_description_struct(const struct side_type_struct
*side_struct
__attribute__((unused
)), void *priv
)
2034 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2041 void before_print_description_variant(const struct side_type_variant
*side_variant
, void *priv
)
2043 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2045 print_attributes("attr", ":", side_ptr_get(side_variant
->attr
), side_variant
->nr_attr
);
2046 printf("%s", side_variant
->nr_attr
? ", " : "");
2047 printf("type: variant { options: {");
2052 void after_print_description_variant(const struct side_type_variant
*side_variant
__attribute__((unused
)), void *priv
)
2054 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2061 void before_print_description_array(const struct side_type_array
*side_array
, void *priv
)
2063 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2065 print_attributes("attr", ":", side_ptr_get(side_array
->attr
), side_array
->nr_attr
);
2066 printf("%s", side_array
->nr_attr
? ", " : "");
2067 printf("type: array { length: %" PRIu32
", element:", side_array
->length
);
2073 void after_print_description_array(const struct side_type_array
*side_array
__attribute__((unused
)), void *priv
)
2075 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2082 void before_print_description_vla(const struct side_type_vla
*side_vla
, void *priv
)
2084 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2086 print_attributes("attr", ":", side_ptr_get(side_vla
->attr
), side_vla
->nr_attr
);
2087 printf("%s", side_vla
->nr_attr
? ", " : "");
2088 printf("type: vla { length:");
2093 void after_length_print_description_vla(const struct side_type_vla
*side_vla
__attribute__((unused
)), void *priv
)
2095 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2098 printf(", element:");
2103 void after_element_print_description_vla(const struct side_type_vla
*side_vla
__attribute__((unused
)), void *priv
)
2105 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2112 void before_print_description_vla_visitor(const struct side_type_vla_visitor
*side_vla_visitor
, void *priv
)
2114 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2116 print_attributes("attr", ":", side_ptr_get(side_vla_visitor
->attr
), side_vla_visitor
->nr_attr
);
2117 printf("%s", side_vla_visitor
->nr_attr
? ", " : "");
2118 printf("type: vla_visitor { length:");
2123 void after_length_print_description_vla_visitor(const struct side_type_vla_visitor
*side_vla_visitor
__attribute__((unused
)), void *priv
)
2125 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2128 printf(", element:");
2133 void after_element_print_description_vla_visitor(const struct side_type_vla_visitor
*side_vla_visitor
__attribute__((unused
)), void *priv
)
2135 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2142 void do_before_print_description_enum(const char *type_name
, const struct side_enum_mappings
*mappings
, void *priv
__attribute__((unused
)))
2144 uint32_t i
, print_count
= 0;
2146 tracer_print_type_header("type", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
2147 printf("%s { labels: { ", type_name
);
2148 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
2149 const struct side_enum_mapping
*mapping
= &side_ptr_get(mappings
->mappings
)[i
];
2151 if (mapping
->range_end
< mapping
->range_begin
) {
2152 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
2153 mapping
->range_begin
, mapping
->range_end
);
2156 printf("%s", print_count
++ ? ", " : "");
2157 if (mapping
->range_begin
== mapping
->range_end
)
2158 printf("[ %" PRIu64
" ]: ", mapping
->range_begin
);
2160 printf("[ %" PRIu64
" - %" PRIu64
" ]: ",
2161 mapping
->range_begin
, mapping
->range_end
);
2162 tracer_print_type_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
,
2163 side_enum_get(mapping
->label
.byte_order
), NULL
);
2166 printf("<NO LABEL>");
2168 printf(" }, element: { ");
2173 void do_after_print_description_enum(const char *type_name
__attribute__((unused
)), const struct side_enum_mappings
*mappings
__attribute__((unused
)), void *priv
__attribute__((unused
)))
2179 void before_print_description_enum(const struct side_type
*type_desc
, void *priv
)
2181 const struct side_enum_mappings
*mappings
= side_ptr_get(type_desc
->u
.side_enum
.mappings
);
2182 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum
.elem_type
);
2184 switch (side_enum_get(elem_type
->type
)) {
2189 case SIDE_TYPE_U128
:
2194 case SIDE_TYPE_S128
:
2197 fprintf(stderr
, "Unsupported enum element type.\n");
2200 do_before_print_description_enum("enum", mappings
, priv
);
2204 void after_print_description_enum(const struct side_type
*type_desc
, void *priv
)
2206 const struct side_enum_mappings
*mappings
= side_ptr_get(type_desc
->u
.side_enum
.mappings
);
2208 do_after_print_description_enum("enum", mappings
, priv
);
2212 void before_print_description_enum_bitmap(const struct side_type
*type_desc
, void *priv
__attribute__((unused
)))
2214 const struct side_type
*elem_type
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.elem_type
);
2215 const struct side_enum_bitmap_mappings
*mappings
= side_ptr_get(type_desc
->u
.side_enum_bitmap
.mappings
);
2216 uint32_t i
, print_count
= 0;
2218 switch (side_enum_get(elem_type
->type
)) {
2219 case SIDE_TYPE_BYTE
:
2224 case SIDE_TYPE_U128
:
2225 case SIDE_TYPE_ARRAY
:
2229 fprintf(stderr
, "Unsupported enum element type.\n");
2232 tracer_print_type_header("type", ":", side_ptr_get(mappings
->attr
), mappings
->nr_attr
);
2233 printf("enum_bitmap { labels: { ");
2234 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
2235 const struct side_enum_bitmap_mapping
*mapping
= &side_ptr_get(mappings
->mappings
)[i
];
2237 if (mapping
->range_end
< mapping
->range_begin
) {
2238 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
2239 mapping
->range_begin
, mapping
->range_end
);
2242 printf("%s", print_count
++ ? ", " : "");
2243 if (mapping
->range_begin
== mapping
->range_end
)
2244 printf("[ %" PRIu64
" ]: ", mapping
->range_begin
);
2246 printf("[ %" PRIu64
" - %" PRIu64
" ]: ",
2247 mapping
->range_begin
, mapping
->range_end
);
2248 tracer_print_type_string(side_ptr_get(mapping
->label
.p
), mapping
->label
.unit_size
,
2249 side_enum_get(mapping
->label
.byte_order
), NULL
);
2252 printf("<NO LABEL>");
2254 printf(" }, element: { ");
2258 void after_print_description_enum_bitmap(const struct side_type
*type_desc
__attribute__((unused
)), void *priv
__attribute__((unused
)))
2264 void print_description_gather_bool(const struct side_type_gather_bool
*type
,
2265 void *priv
__attribute__((unused
)))
2267 tracer_print_type_header("type", ":", side_ptr_get(type
->type
.attr
),
2268 type
->type
.nr_attr
);
2269 printf("gather_bool { size: %" PRIu16
, type
->type
.bool_size
);
2270 if (type
->type
.len_bits
)
2271 printf(", len_bits: %" PRIu16
, type
->type
.len_bits
);
2272 printf(", offset: %" PRIu64
", offset_bits: %" PRIu16
", access_mode: %s",
2273 type
->offset
, type
->offset_bits
,
2274 side_enum_get(type
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2279 void print_description_gather_byte(const struct side_type_gather_byte
*type
,
2280 void *priv
__attribute__((unused
)))
2282 tracer_print_type_header("type", ":", side_ptr_get(type
->type
.attr
),
2283 type
->type
.nr_attr
);
2284 printf("gather_byte { offset: %" PRIu64
", access_mode: %s }",
2286 side_enum_get(type
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2290 void print_description_gather_integer(const struct side_type_gather_integer
*type
,
2291 void *priv
__attribute__((unused
)))
2293 tracer_print_type_header("type", ":", side_ptr_get(type
->type
.attr
),
2294 type
->type
.nr_attr
);
2295 printf("gather_integer { size: %" PRIu16
", signedness: %s, byte_order: \"%s\"",
2296 type
->type
.integer_size
,
2297 type
->type
.signedness
? "true" : "false",
2298 side_enum_get(type
->type
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
2299 if (type
->type
.len_bits
)
2300 printf(", len_bits: %" PRIu16
, type
->type
.len_bits
);
2301 printf(", offset: %" PRIu64
", offset_bits: %" PRIu16
", access_mode: %s",
2302 type
->offset
, type
->offset_bits
,
2303 side_enum_get(type
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2308 void print_description_gather_pointer(const struct side_type_gather_integer
*type
,
2309 void *priv
__attribute__((unused
)))
2311 tracer_print_type_header("type", ":", side_ptr_get(type
->type
.attr
),
2312 type
->type
.nr_attr
);
2313 printf("gather_pointer { size: %" PRIu16
", signedness: %s, byte_order: \"%s\"",
2314 type
->type
.integer_size
,
2315 type
->type
.signedness
? "true" : "false",
2316 side_enum_get(type
->type
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
2317 if (type
->type
.len_bits
)
2318 printf(", len_bits: %" PRIu16
, type
->type
.len_bits
);
2319 printf(", offset: %" PRIu64
", offset_bits: %" PRIu16
", access_mode: %s",
2320 type
->offset
, type
->offset_bits
,
2321 side_enum_get(type
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2326 void print_description_gather_float(const struct side_type_gather_float
*type
,
2327 void *priv
__attribute__((unused
)))
2329 tracer_print_type_header("type", ":", side_ptr_get(type
->type
.attr
),
2330 type
->type
.nr_attr
);
2331 printf("gather_float { size: %" PRIu16
", byte_order: \"%s\"",
2332 type
->type
.float_size
,
2333 side_enum_get(type
->type
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
2334 printf(", offset: %" PRIu64
", access_mode: %s",
2336 side_enum_get(type
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2341 void print_description_gather_string(const struct side_type_gather_string
*type
,
2342 void *priv
__attribute__((unused
)))
2344 tracer_print_type_header("type", ":", side_ptr_get(type
->type
.attr
),
2345 type
->type
.nr_attr
);
2346 printf("gather_string { unit_size: %" PRIu8
,
2347 type
->type
.unit_size
);
2348 if (type
->type
.unit_size
> 1)
2349 printf(", byte_order: \"%s\"",
2350 side_enum_get(type
->type
.byte_order
) == SIDE_TYPE_BYTE_ORDER_LE
? "le" : "be");
2351 printf(", offset: %" PRIu64
", access_mode: %s",
2353 side_enum_get(type
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2358 void before_print_description_gather_struct(const struct side_type_gather_struct
*side_gather_struct
, void *priv
)
2360 const struct side_type_struct
*side_struct
= side_ptr_get(side_gather_struct
->type
);
2361 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2363 print_attributes("attr", ":", side_ptr_get(side_struct
->attr
), side_struct
->nr_attr
);
2364 printf("%s", side_struct
->nr_attr
? ", " : "");
2365 printf("type: gather_struct { size: %" PRIu32
", offset: %" PRIu64
", access_mode: %s, fields: {",
2366 side_gather_struct
->size
, side_gather_struct
->offset
,
2367 side_enum_get(side_gather_struct
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2372 void after_print_description_gather_struct(const struct side_type_gather_struct
*side_gather_struct
__attribute__((unused
)), void *priv
)
2374 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2381 void before_print_description_gather_array(const struct side_type_gather_array
*side_gather_array
, void *priv
)
2383 const struct side_type_array
*side_array
= &side_gather_array
->type
;
2384 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2386 print_attributes("attr", ":", side_ptr_get(side_array
->attr
), side_array
->nr_attr
);
2387 printf("%s", side_array
->nr_attr
? ", " : "");
2388 printf("type: gather_array { offset: %" PRIu64
", access_mode: %s, element:",
2389 side_gather_array
->offset
,
2390 side_enum_get(side_gather_array
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2395 void after_print_description_gather_array(const struct side_type_gather_array
*side_gather_array
__attribute__((unused
)), void *priv
)
2397 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2404 void before_print_description_gather_vla(const struct side_type_gather_vla
*side_gather_vla
, void *priv
)
2406 const struct side_type_vla
*side_vla
= &side_gather_vla
->type
;
2407 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2409 print_attributes("attr", ":", side_ptr_get(side_vla
->attr
), side_vla
->nr_attr
);
2410 printf("%s", side_vla
->nr_attr
? ", " : "");
2411 printf("type: gather_vla { offset: %" PRIu64
", access_mode: %s, length:",
2412 side_gather_vla
->offset
,
2413 side_enum_get(side_gather_vla
->access_mode
) == SIDE_TYPE_GATHER_ACCESS_DIRECT
? "\"direct\"" : "\"pointer\"");
2418 void after_length_print_description_gather_vla(const struct side_type_gather_vla
*side_gather_vla
__attribute__((unused
)), void *priv
)
2420 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2423 printf(", element:");
2428 void after_element_print_description_gather_vla(const struct side_type_gather_vla
*side_gather_vla
__attribute__((unused
)), void *priv
)
2430 struct print_ctx
*ctx
= (struct print_ctx
*) priv
;
2437 void before_print_description_gather_enum(const struct side_type_gather_enum
*type
, void *priv
)
2439 const struct side_enum_mappings
*mappings
= side_ptr_get(type
->mappings
);
2440 const struct side_type
*elem_type
= side_ptr_get(type
->elem_type
);
2442 if (side_enum_get(elem_type
->type
) != SIDE_TYPE_GATHER_INTEGER
) {
2443 fprintf(stderr
, "Unsupported enum element type.\n");
2446 do_before_print_description_enum("gather_enum", mappings
, priv
);
2450 void after_print_description_gather_enum(const struct side_type_gather_enum
*type
, void *priv
)
2452 const struct side_enum_mappings
*mappings
= side_ptr_get(type
->mappings
);
2454 do_after_print_description_enum("gather_enum", mappings
, priv
);
2458 void print_description_dynamic(const struct side_type
*type_desc
__attribute__((unused
)), void *priv
__attribute__((unused
)))
2460 printf("type: dynamic");
2464 struct side_description_visitor description_visitor
= {
2465 .before_event_func
= before_print_description_event
,
2466 .after_event_func
= after_print_description_event
,
2467 .before_static_fields_func
= before_print_description_static_fields
,
2468 .after_static_fields_func
= after_print_description_static_fields
,
2470 /* Stack-copy basic types. */
2471 .before_field_func
= before_print_description_field
,
2472 .after_field_func
= after_print_description_field
,
2473 .before_elem_func
= before_print_description_elem
,
2474 .after_elem_func
= after_print_description_elem
,
2475 .before_option_func
= before_print_description_option
,
2476 .after_option_func
= after_print_description_option
,
2477 .null_type_func
= print_description_null
,
2478 .bool_type_func
= print_description_bool
,
2479 .integer_type_func
= print_description_integer
,
2480 .byte_type_func
= print_description_byte
,
2481 .pointer_type_func
= print_description_pointer
,
2482 .float_type_func
= print_description_float
,
2483 .string_type_func
= print_description_string
,
2485 /* Stack-copy compound types. */
2486 .before_struct_type_func
= before_print_description_struct
,
2487 .after_struct_type_func
= after_print_description_struct
,
2488 .before_variant_type_func
= before_print_description_variant
,
2489 .after_variant_type_func
= after_print_description_variant
,
2490 .before_array_type_func
= before_print_description_array
,
2491 .after_array_type_func
= after_print_description_array
,
2492 .before_vla_type_func
= before_print_description_vla
,
2493 .after_length_vla_type_func
= after_length_print_description_vla
,
2494 .after_element_vla_type_func
= after_element_print_description_vla
,
2495 .before_vla_visitor_type_func
= before_print_description_vla_visitor
,
2496 .after_length_vla_visitor_type_func
= after_length_print_description_vla_visitor
,
2497 .after_element_vla_visitor_type_func
= after_element_print_description_vla_visitor
,
2499 /* Stack-copy enumeration types. */
2500 .before_enum_type_func
= before_print_description_enum
,
2501 .after_enum_type_func
= after_print_description_enum
,
2502 .before_enum_bitmap_type_func
= before_print_description_enum_bitmap
,
2503 .after_enum_bitmap_type_func
= after_print_description_enum_bitmap
,
2505 /* Gather basic types. */
2506 .gather_bool_type_func
= print_description_gather_bool
,
2507 .gather_byte_type_func
= print_description_gather_byte
,
2508 .gather_integer_type_func
= print_description_gather_integer
,
2509 .gather_pointer_type_func
= print_description_gather_pointer
,
2510 .gather_float_type_func
= print_description_gather_float
,
2511 .gather_string_type_func
= print_description_gather_string
,
2513 /* Gather compound types. */
2514 .before_gather_struct_type_func
= before_print_description_gather_struct
,
2515 .after_gather_struct_type_func
= after_print_description_gather_struct
,
2516 .before_gather_array_type_func
= before_print_description_gather_array
,
2517 .after_gather_array_type_func
= after_print_description_gather_array
,
2518 .before_gather_vla_type_func
= before_print_description_gather_vla
,
2519 .after_length_gather_vla_type_func
= after_length_print_description_gather_vla
,
2520 .after_element_gather_vla_type_func
= after_element_print_description_gather_vla
,
2522 /* Gather enumeration types. */
2523 .before_gather_enum_type_func
= before_print_description_gather_enum
,
2524 .after_gather_enum_type_func
= after_print_description_gather_enum
,
2526 /* Dynamic types. */
2527 .dynamic_type_func
= print_description_dynamic
,
2531 void print_event_description(const struct side_event_description
*desc
)
2533 struct print_ctx ctx
= {};
2535 description_visitor_event(&description_visitor
, desc
, &ctx
);
2539 void tracer_event_notification(enum side_tracer_notification notif
,
2540 struct side_event_description
**events
, uint32_t nr_events
,
2541 void *priv
__attribute__((unused
)))
2546 printf("----------------------------------------------------------\n");
2547 printf("Tracer notified of events %s\n",
2548 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
2549 for (i
= 0; i
< nr_events
; i
++) {
2550 struct side_event_description
*event
= events
[i
];
2552 /* Skip NULL pointers */
2555 if (event
->version
!= SIDE_EVENT_DESCRIPTION_ABI_VERSION
) {
2556 printf("Error: event description ABI version (%u) does not match the version supported by the tracer (%u)\n",
2557 event
->version
, SIDE_EVENT_DESCRIPTION_ABI_VERSION
);
2560 printf("provider: %s, event: %s\n",
2561 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
));
2562 if (event
->struct_size
!= side_offsetofend(struct side_event_description
, side_event_description_orig_abi_last
)) {
2563 printf("Warning: Event %s.%s description contains fields unknown to the tracer\n",
2564 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
));
2566 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
2567 if (event
->nr_side_type_label
> _NR_SIDE_TYPE_LABEL
) {
2568 printf("Warning: event %s:%s may contain unknown field types (%u unknown types)\n",
2569 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
),
2570 event
->nr_side_type_label
- _NR_SIDE_TYPE_LABEL
);
2572 if (event
->nr_side_attr_type
> _NR_SIDE_ATTR_TYPE
) {
2573 printf("Warning: event %s:%s may contain unknown attribute types (%u unknown types)\n",
2574 side_ptr_get(event
->provider_name
), side_ptr_get(event
->event_name
),
2575 event
->nr_side_attr_type
- _NR_SIDE_ATTR_TYPE
);
2577 print_event_description(event
);
2578 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
2579 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
, tracer_key
);
2583 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
, tracer_key
);
2588 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
2589 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
, tracer_key
);
2593 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
, tracer_key
);
2599 printf("----------------------------------------------------------\n");
2602 static __attribute__((constructor
))
2603 void tracer_init(void);
2605 void tracer_init(void)
2607 if (side_tracer_request_key(&tracer_key
))
2609 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
2614 static __attribute__((destructor
))
2615 void tracer_exit(void);
2617 void tracer_exit(void)
2619 side_tracer_event_notification_unregister(tracer_handle
);