Add key characteristics to rfc
[libside.git] / src / tracer.c
CommitLineData
f611d0c3
MD
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6#include <stdint.h>
7#include <inttypes.h>
8#include <stdlib.h>
9#include <stdio.h>
ea32e5fc 10#include <stdbool.h>
1d9c515c 11#include <string.h>
52990f65 12#include <iconv.h>
f611d0c3 13
67337c4a 14#include <side/trace.h>
f611d0c3 15
cf80fbf9 16#include "visit-arg-vec.h"
f0619c77 17#include "visit-description.h"
cf80fbf9 18
0160d2c0
MD
19/* TODO: optionally print caller address. */
20static bool print_caller = false;
21
cf80fbf9
MD
22#define MAX_NESTING 32
23
1d9c515c
MD
24enum tracer_display_base {
25 TRACER_DISPLAY_BASE_2,
26 TRACER_DISPLAY_BASE_8,
27 TRACER_DISPLAY_BASE_10,
28 TRACER_DISPLAY_BASE_16,
29};
30
0cbdadb5
MD
31union int_value {
32 uint64_t u[NR_SIDE_INTEGER128_SPLIT];
33 int64_t s[NR_SIDE_INTEGER128_SPLIT];
4f5e1b67
MD
34};
35
cf80fbf9
MD
36struct print_ctx {
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. */
39};
40
67337c4a 41static struct side_tracer_handle *tracer_handle;
1e8aec23 42
bffe9ae3
MD
43static uint64_t tracer_key;
44
f0619c77
MD
45static struct side_description_visitor description_visitor;
46
52990f65 47static
67337c4a 48void tracer_convert_string_to_utf8(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
9ceac3e2
MD
49 size_t *strlen_with_null,
50 char **output_str)
52990f65 51{
3e60053f 52 size_t ret, inbytesleft = 0, outbytesleft, bufsize, input_size;
52990f65
MD
53 const char *str = p, *fromcode;
54 char *inbuf = (char *) p, *outbuf, *buf;
55 iconv_t cd;
56
57 switch (unit_size) {
58 case 1:
52990f65
MD
59 if (strlen_with_null)
60 *strlen_with_null = strlen(str) + 1;
9ceac3e2 61 *output_str = (char *) str;
52990f65
MD
62 return;
63 case 2:
64 {
65 const uint16_t *p16 = p;
66
67 switch (byte_order) {
67337c4a 68 case SIDE_TYPE_BYTE_ORDER_LE:
52990f65
MD
69 {
70 fromcode = "UTF-16LE";
71 break;
72 }
67337c4a 73 case SIDE_TYPE_BYTE_ORDER_BE:
52990f65
MD
74 {
75 fromcode = "UTF-16BE";
76 break;
77 }
78 default:
79 fprintf(stderr, "Unknown byte order\n");
80 abort();
81 }
82 for (; *p16; p16++)
83 inbytesleft += 2;
3e60053f 84 input_size = inbytesleft + 2;
52990f65
MD
85 /*
86 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
87 * { ef, bf, bf } UTF-8 (3 bytes).
88 */
89 bufsize = inbytesleft / 2 * 3 + 1;
90 break;
91 }
92 case 4:
93 {
94 const uint32_t *p32 = p;
95
96 switch (byte_order) {
67337c4a 97 case SIDE_TYPE_BYTE_ORDER_LE:
52990f65
MD
98 {
99 fromcode = "UTF-32LE";
100 break;
101 }
67337c4a 102 case SIDE_TYPE_BYTE_ORDER_BE:
52990f65
MD
103 {
104 fromcode = "UTF-32BE";
105 break;
106 }
107 default:
108 fprintf(stderr, "Unknown byte order\n");
109 abort();
110 }
111 for (; *p32; p32++)
112 inbytesleft += 4;
3e60053f 113 input_size = inbytesleft + 4;
52990f65
MD
114 /*
115 * Each 4-byte UTF-32 character converts to at most a
116 * 4-byte UTF-8 character.
117 */
118 bufsize = inbytesleft + 1;
119 break;
120 }
121 default:
122 fprintf(stderr, "Unknown string unit size %" PRIu8 "\n", unit_size);
123 abort();
124 }
125
126 cd = iconv_open("UTF8", fromcode);
127 if (cd == (iconv_t) -1) {
128 perror("iconv_open");
129 abort();
130 }
131 buf = malloc(bufsize);
132 if (!buf) {
133 abort();
134 }
135 outbuf = (char *) buf;
136 outbytesleft = bufsize;
137 ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
138 if (ret == (size_t) -1) {
139 perror("iconv");
140 abort();
141 }
142 if (inbytesleft) {
143 fprintf(stderr, "Buffer too small to convert string input\n");
144 abort();
145 }
146 (*outbuf++) = '\0';
52990f65
MD
147 if (iconv_close(cd) == -1) {
148 perror("iconv_close");
149 abort();
150 }
9ceac3e2 151 if (strlen_with_null)
3e60053f 152 *strlen_with_null = input_size;
9ceac3e2
MD
153 *output_str = buf;
154}
155
156static
cf80fbf9 157void tracer_print_type_string(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
9ceac3e2
MD
158 size_t *strlen_with_null)
159{
160 char *output_str = NULL;
161
162 tracer_convert_string_to_utf8(p, unit_size, byte_order, strlen_with_null, &output_str);
163 printf("\"%s\"", output_str);
164 if (output_str != p)
165 free(output_str);
52990f65
MD
166}
167
1d9c515c 168static
0cbdadb5
MD
169void side_check_value_u64(union int_value v)
170{
171 if (v.u[SIDE_INTEGER128_SPLIT_HIGH]) {
172 fprintf(stderr, "Unexpected integer value\n");
173 abort();
174 }
175}
176
177static
178void side_check_value_s64(union int_value v)
179{
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");
183 abort();
184 }
185 } else {
186 if (v.s[SIDE_INTEGER128_SPLIT_HIGH]) {
187 fprintf(stderr, "Unexpected integer value\n");
188 abort();
189 }
190 }
191}
192
193static
194int64_t get_attr_integer64_value(const struct side_attr *attr)
1d9c515c
MD
195{
196 int64_t val;
197
15f17024 198 switch (side_enum_get(attr->value.type)) {
67337c4a
MD
199 case SIDE_ATTR_TYPE_U8:
200 val = attr->value.u.integer_value.side_u8;
1d9c515c 201 break;
67337c4a
MD
202 case SIDE_ATTR_TYPE_U16:
203 val = attr->value.u.integer_value.side_u16;
1d9c515c 204 break;
67337c4a
MD
205 case SIDE_ATTR_TYPE_U32:
206 val = attr->value.u.integer_value.side_u32;
1d9c515c 207 break;
67337c4a
MD
208 case SIDE_ATTR_TYPE_U64:
209 val = attr->value.u.integer_value.side_u64;
1d9c515c 210 break;
0cbdadb5
MD
211 case SIDE_ATTR_TYPE_U128:
212 {
213 union int_value v = {
214 .u = {
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],
217 },
218 };
219 side_check_value_u64(v);
220 val = v.u[SIDE_INTEGER128_SPLIT_LOW];
221 break;
222 }
67337c4a
MD
223 case SIDE_ATTR_TYPE_S8:
224 val = attr->value.u.integer_value.side_s8;
1d9c515c 225 break;
67337c4a
MD
226 case SIDE_ATTR_TYPE_S16:
227 val = attr->value.u.integer_value.side_s16;
1d9c515c 228 break;
67337c4a
MD
229 case SIDE_ATTR_TYPE_S32:
230 val = attr->value.u.integer_value.side_s32;
1d9c515c 231 break;
67337c4a
MD
232 case SIDE_ATTR_TYPE_S64:
233 val = attr->value.u.integer_value.side_s64;
1d9c515c 234 break;
0cbdadb5
MD
235 case SIDE_ATTR_TYPE_S128:
236 {
237 union int_value v = {
238 .s = {
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],
241 },
242 };
243 side_check_value_s64(v);
244 val = v.s[SIDE_INTEGER128_SPLIT_LOW];
245 break;
246 }
1d9c515c
MD
247 default:
248 fprintf(stderr, "Unexpected attribute type\n");
249 abort();
250 }
251 return val;
252}
253
254static
67337c4a 255enum tracer_display_base get_attr_display_base(const struct side_attr *_attr, uint32_t nr_attr,
f0dafd60 256 enum tracer_display_base default_base)
1d9c515c
MD
257{
258 uint32_t i;
259
260 for (i = 0; i < nr_attr; i++) {
67337c4a 261 const struct side_attr *attr = &_attr[i];
9ceac3e2
MD
262 char *utf8_str = NULL;
263 bool cmp;
1d9c515c 264
3db2d8a1 265 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
3bc9ba43 266 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
9ceac3e2 267 cmp = strcmp(utf8_str, "std.integer.base");
3db2d8a1 268 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2
MD
269 free(utf8_str);
270 if (!cmp) {
0cbdadb5 271 int64_t val = get_attr_integer64_value(attr);
1d9c515c
MD
272
273 switch (val) {
274 case 2:
275 return TRACER_DISPLAY_BASE_2;
276 case 8:
277 return TRACER_DISPLAY_BASE_8;
278 case 10:
279 return TRACER_DISPLAY_BASE_10;
280 case 16:
281 return TRACER_DISPLAY_BASE_16;
282 default:
283 fprintf(stderr, "Unexpected integer display base: %" PRId64 "\n", val);
284 abort();
285 }
286 }
287 }
f0dafd60 288 return default_base; /* Default */
1d9c515c
MD
289}
290
bc3c89b3 291static
67337c4a 292void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
bc3c89b3 293{
9ceac3e2
MD
294 char *utf8_str = NULL;
295
3db2d8a1 296 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
3bc9ba43 297 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
9ceac3e2 298 printf("{ key%s \"%s\", value%s ", separator, utf8_str, separator);
3db2d8a1 299 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2 300 free(utf8_str);
15f17024 301 switch (side_enum_get(attr->value.type)) {
67337c4a 302 case SIDE_ATTR_TYPE_BOOL:
5f82db91 303 printf("%s", attr->value.u.bool_value ? "true" : "false");
bc3c89b3 304 break;
67337c4a
MD
305 case SIDE_ATTR_TYPE_U8:
306 printf("%" PRIu8, attr->value.u.integer_value.side_u8);
bc3c89b3 307 break;
67337c4a
MD
308 case SIDE_ATTR_TYPE_U16:
309 printf("%" PRIu16, attr->value.u.integer_value.side_u16);
bc3c89b3 310 break;
67337c4a
MD
311 case SIDE_ATTR_TYPE_U32:
312 printf("%" PRIu32, attr->value.u.integer_value.side_u32);
bc3c89b3 313 break;
67337c4a
MD
314 case SIDE_ATTR_TYPE_U64:
315 printf("%" PRIu64, attr->value.u.integer_value.side_u64);
bc3c89b3 316 break;
0cbdadb5
MD
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]);
320 } else {
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]);
324 }
325 break;
67337c4a
MD
326 case SIDE_ATTR_TYPE_S8:
327 printf("%" PRId8, attr->value.u.integer_value.side_s8);
bc3c89b3 328 break;
67337c4a
MD
329 case SIDE_ATTR_TYPE_S16:
330 printf("%" PRId16, attr->value.u.integer_value.side_s16);
bc3c89b3 331 break;
67337c4a
MD
332 case SIDE_ATTR_TYPE_S32:
333 printf("%" PRId32, attr->value.u.integer_value.side_s32);
bc3c89b3 334 break;
67337c4a
MD
335 case SIDE_ATTR_TYPE_S64:
336 printf("%" PRId64, attr->value.u.integer_value.side_s64);
bc3c89b3 337 break;
0cbdadb5
MD
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]);
341 } else {
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]);
345 }
346 break;
67337c4a 347 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
bc3c89b3 348#if __HAVE_FLOAT16
67337c4a 349 printf("%g", (double) attr->value.u.float_value.side_float_binary16);
bc3c89b3
MD
350 break;
351#else
de1b3cd2 352 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
bc3c89b3
MD
353 abort();
354#endif
67337c4a 355 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
bc3c89b3 356#if __HAVE_FLOAT32
67337c4a 357 printf("%g", (double) attr->value.u.float_value.side_float_binary32);
bc3c89b3
MD
358 break;
359#else
de1b3cd2 360 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
bc3c89b3
MD
361 abort();
362#endif
67337c4a 363 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
bc3c89b3 364#if __HAVE_FLOAT64
67337c4a 365 printf("%g", (double) attr->value.u.float_value.side_float_binary64);
bc3c89b3
MD
366 break;
367#else
de1b3cd2 368 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
bc3c89b3
MD
369 abort();
370#endif
67337c4a 371 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
bc3c89b3 372#if __HAVE_FLOAT128
67337c4a 373 printf("%Lg", (long double) attr->value.u.float_value.side_float_binary128);
bc3c89b3
MD
374 break;
375#else
de1b3cd2 376 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
bc3c89b3
MD
377 abort();
378#endif
67337c4a 379 case SIDE_ATTR_TYPE_STRING:
cf80fbf9 380 tracer_print_type_string(side_ptr_get(attr->value.u.string_value.p),
ab8a626e 381 attr->value.u.string_value.unit_size,
3bc9ba43 382 side_enum_get(attr->value.u.string_value.byte_order), NULL);
bc3c89b3
MD
383 break;
384 default:
de1b3cd2 385 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
bc3c89b3
MD
386 abort();
387 }
388 printf(" }");
389}
390
7d21cf51 391static
905c328e 392void print_attributes(const char *prefix_str, const char *separator,
67337c4a 393 const struct side_attr *attr, uint32_t nr_attr)
7d21cf51 394{
e65f9ce5 395 uint32_t i;
7d21cf51
MD
396
397 if (!nr_attr)
398 return;
cf80fbf9 399 printf("%s%s [", prefix_str, separator);
7d21cf51 400 for (i = 0; i < nr_attr; i++) {
cf80fbf9 401 printf("%s", i ? ", " : " ");
905c328e 402 tracer_print_attr_type(separator, &attr[i]);
7d21cf51
MD
403 }
404 printf(" ]");
405}
406
79f677ba 407static
0cbdadb5 408union int_value tracer_load_integer_value(const struct side_type_integer *type_integer,
67337c4a 409 const union side_integer_value *value,
f6a2a8ed 410 uint16_t offset_bits, uint16_t *_len_bits)
79f677ba 411{
0cbdadb5 412 union int_value v = {};
f6a2a8ed
MD
413 uint16_t len_bits;
414 bool reverse_bo;
79f677ba 415
f6a2a8ed
MD
416 if (!type_integer->len_bits)
417 len_bits = type_integer->integer_size * CHAR_BIT;
418 else
419 len_bits = type_integer->len_bits;
420 if (len_bits + offset_bits > type_integer->integer_size * CHAR_BIT)
d8be25de 421 abort();
3bc9ba43 422 reverse_bo = side_enum_get(type_integer->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
f6a2a8ed
MD
423 switch (type_integer->integer_size) {
424 case 1:
425 if (type_integer->signedness)
0cbdadb5 426 v.s[SIDE_INTEGER128_SPLIT_LOW] = value->side_s8;
f6a2a8ed 427 else
0cbdadb5 428 v.u[SIDE_INTEGER128_SPLIT_LOW] = value->side_u8;
d8be25de 429 break;
f6a2a8ed
MD
430 case 2:
431 if (type_integer->signedness) {
67337c4a 432 int16_t side_s16;
8bdd5c12 433
67337c4a 434 side_s16 = value->side_s16;
f6a2a8ed 435 if (reverse_bo)
67337c4a 436 side_s16 = side_bswap_16(side_s16);
0cbdadb5 437 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s16;
f6a2a8ed 438 } else {
67337c4a 439 uint16_t side_u16;
8bdd5c12 440
67337c4a 441 side_u16 = value->side_u16;
f6a2a8ed 442 if (reverse_bo)
67337c4a 443 side_u16 = side_bswap_16(side_u16);
0cbdadb5 444 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u16;
f6a2a8ed 445 }
d8be25de 446 break;
f6a2a8ed
MD
447 case 4:
448 if (type_integer->signedness) {
67337c4a 449 int32_t side_s32;
8bdd5c12 450
67337c4a 451 side_s32 = value->side_s32;
f6a2a8ed 452 if (reverse_bo)
67337c4a 453 side_s32 = side_bswap_32(side_s32);
0cbdadb5 454 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s32;
f6a2a8ed 455 } else {
67337c4a 456 uint32_t side_u32;
8bdd5c12 457
67337c4a 458 side_u32 = value->side_u32;
f6a2a8ed 459 if (reverse_bo)
67337c4a 460 side_u32 = side_bswap_32(side_u32);
0cbdadb5 461 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u32;
f6a2a8ed 462 }
d8be25de 463 break;
f6a2a8ed
MD
464 case 8:
465 if (type_integer->signedness) {
67337c4a 466 int64_t side_s64;
8bdd5c12 467
67337c4a 468 side_s64 = value->side_s64;
f6a2a8ed 469 if (reverse_bo)
67337c4a 470 side_s64 = side_bswap_64(side_s64);
0cbdadb5 471 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64;
f6a2a8ed 472 } else {
67337c4a 473 uint64_t side_u64;
8bdd5c12 474
67337c4a 475 side_u64 = value->side_u64;
f6a2a8ed 476 if (reverse_bo)
67337c4a 477 side_u64 = side_bswap_64(side_u64);
0cbdadb5
MD
478 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64;
479 }
480 break;
481 case 16:
482 if (type_integer->signedness) {
483 int64_t side_s64[NR_SIDE_INTEGER128_SPLIT];
484
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];
487 if (reverse_bo) {
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];
492 } else {
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];
495 }
496 } else {
497 uint64_t side_u64[NR_SIDE_INTEGER128_SPLIT];
498
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];
501 if (reverse_bo) {
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];
506 } else {
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];
509 }
f6a2a8ed 510 }
d8be25de
MD
511 break;
512 default:
d8be25de
MD
513 abort();
514 }
0cbdadb5
MD
515 if (type_integer->integer_size <= 8) {
516 v.u[SIDE_INTEGER128_SPLIT_LOW] >>= offset_bits;
517 if (len_bits < 64) {
518 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
519 if (type_integer->signedness) {
520 /* Sign-extend. */
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;
524 }
525 }
f6a2a8ed 526 }
0cbdadb5
MD
527 } else {
528 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
529 if (len_bits < 128 || offset_bits != 0)
530 abort();
f6a2a8ed
MD
531 }
532 if (_len_bits)
533 *_len_bits = len_bits;
0cbdadb5 534 return v;
f6a2a8ed
MD
535}
536
537static
0cbdadb5 538void print_enum_labels(const struct side_enum_mappings *mappings, union int_value v)
f6a2a8ed 539{
f6a2a8ed
MD
540 uint32_t i, print_count = 0;
541
0cbdadb5 542 side_check_value_s64(v);
d8be25de
MD
543 printf(", labels: [ ");
544 for (i = 0; i < mappings->nr_mappings; i++) {
64037418 545 const struct side_enum_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
79f677ba 546
ea32e5fc 547 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 548 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
549 mapping->range_begin, mapping->range_end);
550 abort();
551 }
0cbdadb5 552 if (v.s[SIDE_INTEGER128_SPLIT_LOW] >= mapping->range_begin && v.s[SIDE_INTEGER128_SPLIT_LOW] <= mapping->range_end) {
79f677ba 553 printf("%s", print_count++ ? ", " : "");
cf80fbf9 554 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
3bc9ba43 555 side_enum_get(mapping->label.byte_order), NULL);
79f677ba
MD
556 }
557 }
558 if (!print_count)
559 printf("<NO LABEL>");
560 printf(" ]");
561}
562
ea32e5fc 563static
67337c4a 564uint32_t elem_type_to_stride(const struct side_type *elem_type)
ea32e5fc 565{
af6aa6e1
MD
566 uint32_t stride_bit;
567
3ce69bfa 568 switch (side_enum_get(elem_type->type)) {
67337c4a 569 case SIDE_TYPE_BYTE:
af6aa6e1
MD
570 stride_bit = 8;
571 break;
8625d674 572
67337c4a
MD
573 case SIDE_TYPE_U8:
574 case SIDE_TYPE_U16:
575 case SIDE_TYPE_U32:
576 case SIDE_TYPE_U64:
0cbdadb5 577 case SIDE_TYPE_U128:
67337c4a
MD
578 case SIDE_TYPE_S8:
579 case SIDE_TYPE_S16:
580 case SIDE_TYPE_S32:
581 case SIDE_TYPE_S64:
0cbdadb5 582 case SIDE_TYPE_S128:
67337c4a 583 return elem_type->u.side_integer.integer_size * CHAR_BIT;
af6aa6e1 584 default:
8625d674 585 fprintf(stderr, "ERROR: Unexpected enum bitmap element type\n");
af6aa6e1
MD
586 abort();
587 }
588 return stride_bit;
589}
590
1d9c515c 591static
0cbdadb5 592void print_integer_binary(uint64_t v[NR_SIDE_INTEGER128_SPLIT], int bits)
1d9c515c 593{
0cbdadb5 594 int bit;
1d9c515c
MD
595
596 printf("0b");
0cbdadb5
MD
597 if (bits > 64) {
598 bits -= 64;
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;
603 }
604 bits = 64;
605 }
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;
1d9c515c
MD
610 }
611}
612
0e9be766 613static
f0619c77 614void tracer_print_type_header(const char *prefix, const char *separator,
67337c4a 615 const struct side_attr *attr, uint32_t nr_attr)
ac81c466 616{
aac52685
MD
617 print_attributes("attr", separator, attr, nr_attr);
618 printf("%s", nr_attr ? ", " : "");
f0619c77 619 printf("%s%s ", prefix, separator);
ac81c466
MD
620}
621
8ad2f385
MD
622static
623void tracer_print_type_bool(const char *separator,
67337c4a
MD
624 const struct side_type_bool *type_bool,
625 const union side_bool_value *value,
8ad2f385
MD
626 uint16_t offset_bits)
627{
88bab79c 628 uint32_t len_bits;
8ad2f385
MD
629 bool reverse_bo;
630 uint64_t v;
631
88bab79c
MD
632 if (!type_bool->len_bits)
633 len_bits = type_bool->bool_size * CHAR_BIT;
634 else
635 len_bits = type_bool->len_bits;
636 if (len_bits + offset_bits > type_bool->bool_size * CHAR_BIT)
8ad2f385 637 abort();
3bc9ba43 638 reverse_bo = side_enum_get(type_bool->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
88bab79c
MD
639 switch (type_bool->bool_size) {
640 case 1:
67337c4a 641 v = value->side_bool8;
8ad2f385 642 break;
88bab79c 643 case 2:
8ad2f385 644 {
67337c4a 645 uint16_t side_u16;
8ad2f385 646
67337c4a 647 side_u16 = value->side_bool16;
8ad2f385 648 if (reverse_bo)
67337c4a
MD
649 side_u16 = side_bswap_16(side_u16);
650 v = side_u16;
8ad2f385
MD
651 break;
652 }
88bab79c 653 case 4:
8ad2f385 654 {
67337c4a 655 uint32_t side_u32;
8ad2f385 656
67337c4a 657 side_u32 = value->side_bool32;
8ad2f385 658 if (reverse_bo)
67337c4a
MD
659 side_u32 = side_bswap_32(side_u32);
660 v = side_u32;
8ad2f385
MD
661 break;
662 }
88bab79c 663 case 8:
8ad2f385 664 {
67337c4a 665 uint64_t side_u64;
8ad2f385 666
67337c4a 667 side_u64 = value->side_bool64;
8ad2f385 668 if (reverse_bo)
67337c4a
MD
669 side_u64 = side_bswap_64(side_u64);
670 v = side_u64;
8ad2f385
MD
671 break;
672 }
673 default:
674 abort();
675 }
676 v >>= offset_bits;
88bab79c
MD
677 if (len_bits < 64)
678 v &= (1ULL << len_bits) - 1;
f0619c77 679 tracer_print_type_header("value", separator, side_ptr_get(type_bool->attr), type_bool->nr_attr);
8ad2f385
MD
680 printf("%s", v ? "true" : "false");
681}
682
0cbdadb5
MD
683/* 2^128 - 1 */
684#define U128_BASE_10_ARRAY_LEN sizeof("340282366920938463463374607431768211455")
685/* -2^127 */
686#define S128_BASE_10_ARRAY_LEN sizeof("-170141183460469231731687303715884105728")
687
688/*
689 * u128_tostring_base_10 is inspired from https://stackoverflow.com/a/4364365
690 */
691static
692void u128_tostring_base_10(union int_value v, char str[U128_BASE_10_ARRAY_LEN])
693{
694 int d[39] = {}, i, j, str_i = 0;
695
696 for (i = 63; i > -1; i--) {
697 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
698 d[0]++;
699 for (j = 0; j < 39; j++)
700 d[j] *= 2;
701 for (j = 0; j < 38; j++) {
702 d[j + 1] += d[j] / 10;
703 d[j] %= 10;
704 }
705 }
706 for (i = 63; i > -1; i--) {
707 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
708 d[0]++;
709 if (i > 0) {
710 for (j = 0; j < 39; j++)
711 d[j] *= 2;
712 }
713 for (j = 0; j < 38; j++) {
714 d[j + 1] += d[j] / 10;
715 d[j] %= 10;
716 }
717 }
718 for (i = 38; i > 0; i--)
719 if (d[i] > 0)
720 break;
721 for (; i > -1; i--) {
722 str[str_i++] = '0' + d[i];
723 }
724 str[str_i] = '\0';
725}
726
727static
728void s128_tostring_base_10(union int_value v, char str[S128_BASE_10_ARRAY_LEN])
729{
730 uint64_t low, high, tmp;
731
732 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] >= 0) {
733 /* Positive. */
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);
737 return;
738 }
739
740 /* Negative. */
741
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);
745 return;
746 }
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];
750 tmp = low + 1;
751 if (tmp < low) {
752 high++;
753 /* Clear overflow to sign bit. */
754 high &= ~0x8000000000000000ULL;
755 }
756 v.u[SIDE_INTEGER128_SPLIT_LOW] = tmp;
757 v.u[SIDE_INTEGER128_SPLIT_HIGH] = high;
758 str[0] = '-';
759 u128_tostring_base_10(v, str + 1);
760}
761
762/* 2^128 - 1 */
763#define U128_BASE_8_ARRAY_LEN sizeof("3777777777777777777777777777777777777777777")
764
765static
766void u128_tostring_base_8(union int_value v, char str[U128_BASE_8_ARRAY_LEN])
767{
768 int d[43] = {}, i, j, str_i = 0;
769
770 for (i = 63; i > -1; i--) {
771 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
772 d[0]++;
773 for (j = 0; j < 43; j++)
774 d[j] *= 2;
775 for (j = 0; j < 42; j++) {
776 d[j + 1] += d[j] / 8;
777 d[j] %= 8;
778 }
779 }
780 for (i = 63; i > -1; i--) {
781 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
782 d[0]++;
783 if (i > 0) {
784 for (j = 0; j < 43; j++)
785 d[j] *= 2;
786 }
787 for (j = 0; j < 42; j++) {
788 d[j + 1] += d[j] / 8;
789 d[j] %= 8;
790 }
791 }
792 for (i = 42; i > 0; i--)
793 if (d[i] > 0)
794 break;
795 for (; i > -1; i--) {
796 str[str_i++] = '0' + d[i];
797 }
798 str[str_i] = '\0';
799}
800
4f5e1b67
MD
801static
802void tracer_print_type_integer(const char *separator,
67337c4a
MD
803 const struct side_type_integer *type_integer,
804 const union side_integer_value *value,
4f5e1b67
MD
805 uint16_t offset_bits,
806 enum tracer_display_base default_base)
807{
808 enum tracer_display_base base;
0cbdadb5 809 union int_value v;
4f5e1b67
MD
810 uint16_t len_bits;
811
0cbdadb5 812 v = tracer_load_integer_value(type_integer, value, offset_bits, &len_bits);
f0619c77 813 tracer_print_type_header("value", separator, side_ptr_get(type_integer->attr), type_integer->nr_attr);
12d787db 814 base = get_attr_display_base(side_ptr_get(type_integer->attr), type_integer->nr_attr, default_base);
56c21987
MD
815 switch (base) {
816 case TRACER_DISPLAY_BASE_2:
0cbdadb5 817 print_integer_binary(v.u, len_bits);
56c21987
MD
818 break;
819 case TRACER_DISPLAY_BASE_8:
f6a2a8ed 820 /* Clear sign bits beyond len_bits */
0cbdadb5
MD
821 if (len_bits < 64) {
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;
826 }
827 if (len_bits <= 64) {
828 printf("0o%" PRIo64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
829 } else {
830 char str[U128_BASE_8_ARRAY_LEN];
831
832 u128_tostring_base_8(v, str);
833 printf("0o%s", str);
834 }
56c21987
MD
835 break;
836 case TRACER_DISPLAY_BASE_10:
0cbdadb5
MD
837 if (len_bits <= 64) {
838 if (type_integer->signedness)
839 printf("%" PRId64, v.s[SIDE_INTEGER128_SPLIT_LOW]);
840 else
841 printf("%" PRIu64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
842 } else {
843 if (type_integer->signedness) {
844 char str[S128_BASE_10_ARRAY_LEN];
845 s128_tostring_base_10(v, str);
846 printf("%s", str);
847 } else {
848 char str[U128_BASE_10_ARRAY_LEN];
849 u128_tostring_base_10(v, str);
850 printf("%s", str);
851 }
852 }
56c21987
MD
853 break;
854 case TRACER_DISPLAY_BASE_16:
f6a2a8ed 855 /* Clear sign bits beyond len_bits */
0cbdadb5
MD
856 if (len_bits < 64) {
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;
861 }
862 if (len_bits <= 64 || v.u[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
863 printf("0x%" PRIx64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
864 } else {
865 printf("0x%" PRIx64 "%016" PRIx64,
866 v.u[SIDE_INTEGER128_SPLIT_HIGH],
867 v.u[SIDE_INTEGER128_SPLIT_LOW]);
868 }
56c21987
MD
869 break;
870 default:
871 abort();
872 }
873}
874
3aa7ca5e
MD
875static
876void tracer_print_type_float(const char *separator,
67337c4a
MD
877 const struct side_type_float *type_float,
878 const union side_float_value *value)
3aa7ca5e
MD
879{
880 bool reverse_bo;
881
f0619c77 882 tracer_print_type_header("value", separator, side_ptr_get(type_float->attr), type_float->nr_attr);
3bc9ba43 883 reverse_bo = side_enum_get(type_float->byte_order) != SIDE_TYPE_FLOAT_WORD_ORDER_HOST;
88bab79c
MD
884 switch (type_float->float_size) {
885 case 2:
3aa7ca5e
MD
886 {
887#if __HAVE_FLOAT16
888 union {
889 _Float16 f;
890 uint16_t u;
891 } float16 = {
67337c4a 892 .f = value->side_float_binary16,
3aa7ca5e
MD
893 };
894
895 if (reverse_bo)
67337c4a 896 float16.u = side_bswap_16(float16.u);
3aa7ca5e
MD
897 printf("%g", (double) float16.f);
898 break;
899#else
900 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
901 abort();
902#endif
903 }
88bab79c 904 case 4:
3aa7ca5e
MD
905 {
906#if __HAVE_FLOAT32
907 union {
908 _Float32 f;
909 uint32_t u;
910 } float32 = {
67337c4a 911 .f = value->side_float_binary32,
3aa7ca5e
MD
912 };
913
914 if (reverse_bo)
67337c4a 915 float32.u = side_bswap_32(float32.u);
3aa7ca5e
MD
916 printf("%g", (double) float32.f);
917 break;
918#else
919 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
920 abort();
921#endif
922 }
88bab79c 923 case 8:
3aa7ca5e
MD
924 {
925#if __HAVE_FLOAT64
926 union {
927 _Float64 f;
928 uint64_t u;
929 } float64 = {
67337c4a 930 .f = value->side_float_binary64,
3aa7ca5e
MD
931 };
932
933 if (reverse_bo)
67337c4a 934 float64.u = side_bswap_64(float64.u);
3aa7ca5e
MD
935 printf("%g", (double) float64.f);
936 break;
937#else
938 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
939 abort();
940#endif
941 }
88bab79c 942 case 16:
3aa7ca5e
MD
943 {
944#if __HAVE_FLOAT128
945 union {
946 _Float128 f;
947 char arr[16];
948 } float128 = {
67337c4a 949 .f = value->side_float_binary128,
3aa7ca5e
MD
950 };
951
952 if (reverse_bo)
67337c4a 953 side_bswap_128p(float128.arr);
3aa7ca5e
MD
954 printf("%Lg", (long double) float128.f);
955 break;
956#else
957 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
958 abort();
959#endif
960 }
961 default:
962 fprintf(stderr, "ERROR: Unknown float size\n");
963 abort();
964 }
965}
966
f611d0c3 967static
cf80fbf9 968void push_nesting(struct print_ctx *ctx)
f611d0c3 969{
cf80fbf9
MD
970 if (++ctx->nesting >= MAX_NESTING) {
971 fprintf(stderr, "ERROR: Nesting too deep.\n");
972 abort();
973 }
974 ctx->item_nr[ctx->nesting] = 0;
975}
d8be25de 976
cf80fbf9
MD
977static
978void pop_nesting(struct print_ctx *ctx)
979{
980 ctx->item_nr[ctx->nesting] = 0;
981 if (ctx->nesting-- <= 0) {
982 fprintf(stderr, "ERROR: Nesting underflow.\n");
983 abort();
984 }
985}
45392033 986
cf80fbf9
MD
987static
988int get_nested_item_nr(struct print_ctx *ctx)
989{
990 return ctx->item_nr[ctx->nesting];
991}
d8be25de 992
cf80fbf9
MD
993static
994void inc_nested_item_nr(struct print_ctx *ctx)
995{
996 ctx->item_nr[ctx->nesting]++;
997}
0519cb86 998
cf80fbf9 999static
d7a0f92e 1000void tracer_before_print_event(const struct side_event_description *desc,
cf80fbf9
MD
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)))
1004{
1005 uint32_t side_sav_len = side_arg_vec->len;
66de373e 1006
cf80fbf9
MD
1007 if (desc->nr_fields != side_sav_len) {
1008 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1009 abort();
f611d0c3 1010 }
d8be25de 1011
d7a0f92e
MD
1012 if (print_caller)
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);
cf80fbf9 1018}
56c21987 1019
cf80fbf9 1020static
d7a0f92e
MD
1021void 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)))
1025{
1026 printf("\n");
1027}
1028
1029static
1030void tracer_before_print_static_fields(const struct side_arg_vec *side_arg_vec, void *priv)
cf80fbf9
MD
1031{
1032 struct print_ctx *ctx = (struct print_ctx *) priv;
1033 uint32_t side_sav_len = side_arg_vec->len;
79f677ba 1034
d7a0f92e
MD
1035 printf("%s", side_sav_len ? ", fields: {" : "");
1036 push_nesting(ctx);
cf80fbf9 1037}
3aa7ca5e 1038
d7a0f92e 1039
cf80fbf9 1040static
d7a0f92e
MD
1041void tracer_after_print_static_fields(const struct side_arg_vec *side_arg_vec, void *priv)
1042{
1043 struct print_ctx *ctx = (struct print_ctx *) priv;
1044 uint32_t side_sav_len = side_arg_vec->len;
1045
1046 pop_nesting(ctx);
1047 if (side_sav_len)
1048 printf(" }");
1049}
1050
1051static
1052void tracer_before_print_variadic_fields(const struct side_arg_dynamic_struct *var_struct,
cf80fbf9
MD
1053 void *priv)
1054{
1055 struct print_ctx *ctx = (struct print_ctx *) priv;
1056 uint32_t var_struct_len = var_struct->len;
55fb50b7 1057
d7a0f92e
MD
1058 print_attributes(", attr ", "::", side_ptr_get(var_struct->attr), var_struct->nr_attr);
1059 printf("%s", var_struct_len ? ", fields:: {" : "");
1060 push_nesting(ctx);
cf80fbf9 1061}
55fb50b7 1062
cf80fbf9 1063static
d7a0f92e 1064void tracer_after_print_variadic_fields(const struct side_arg_dynamic_struct *var_struct, void *priv)
cf80fbf9
MD
1065{
1066 struct print_ctx *ctx = (struct print_ctx *) priv;
d7a0f92e 1067 uint32_t var_struct_len = var_struct->len;
55fb50b7 1068
d7a0f92e
MD
1069 pop_nesting(ctx);
1070 if (var_struct_len)
cf80fbf9 1071 printf(" }");
cf80fbf9 1072}
55fb50b7 1073
cf80fbf9 1074static
d7a0f92e 1075void tracer_before_print_field(const struct side_event_field *item_desc, void *priv)
cf80fbf9
MD
1076{
1077 struct print_ctx *ctx = (struct print_ctx *) priv;
66de373e 1078
d7a0f92e
MD
1079 if (get_nested_item_nr(ctx) != 0)
1080 printf(",");
1081 printf(" %s: { ", side_ptr_get(item_desc->field_name));
1082}
1083
1084static
1085void tracer_after_print_field(const struct side_event_field *item_desc __attribute__((unused)), void *priv)
1086{
1087 struct print_ctx *ctx = (struct print_ctx *) priv;
1088
1089 printf(" }");
1090 inc_nested_item_nr(ctx);
1091}
1092
1093static
1094void tracer_before_print_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1095{
1096 struct print_ctx *ctx = (struct print_ctx *) priv;
1097
1098 if (get_nested_item_nr(ctx) != 0)
1099 printf(", { ");
1100 else
1101 printf(" { ");
1102}
1103
1104static
1105void tracer_after_print_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1106{
1107 struct print_ctx *ctx = (struct print_ctx *) priv;
1108
1109 printf(" }");
1110 inc_nested_item_nr(ctx);
f611d0c3
MD
1111}
1112
1113static
cf80fbf9
MD
1114void tracer_print_null(const struct side_type *type_desc,
1115 const struct side_arg *item __attribute__((unused)),
1116 void *priv __attribute__((unused)))
f611d0c3 1117{
f0619c77 1118 tracer_print_type_header("value", ":", side_ptr_get(type_desc->u.side_null.attr),
cf80fbf9
MD
1119 type_desc->u.side_null.nr_attr);
1120 printf("<NULL TYPE>");
f611d0c3
MD
1121}
1122
1123static
cf80fbf9
MD
1124void tracer_print_bool(const struct side_type *type_desc,
1125 const struct side_arg *item,
1126 void *priv __attribute__((unused)))
f611d0c3 1127{
cf80fbf9
MD
1128 tracer_print_type_bool(":", &type_desc->u.side_bool, &item->u.side_static.bool_value, 0);
1129}
f611d0c3 1130
cf80fbf9
MD
1131static
1132void tracer_print_integer(const struct side_type *type_desc,
1133 const struct side_arg *item,
1134 void *priv __attribute__((unused)))
1135{
1136 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0, TRACER_DISPLAY_BASE_10);
f611d0c3
MD
1137}
1138
5530345d 1139static
cf80fbf9
MD
1140void tracer_print_byte(const struct side_type *type_desc __attribute__((unused)),
1141 const struct side_arg *item,
1142 void *priv __attribute__((unused)))
5530345d 1143{
f0619c77 1144 tracer_print_type_header("value", ":", side_ptr_get(type_desc->u.side_byte.attr), type_desc->u.side_byte.nr_attr);
cf80fbf9
MD
1145 printf("0x%" PRIx8, item->u.side_static.byte_value);
1146}
5530345d 1147
7a1cb105 1148static
cf80fbf9
MD
1149void tracer_print_pointer(const struct side_type *type_desc,
1150 const struct side_arg *item,
1151 void *priv __attribute__((unused)))
d9359cfa 1152{
cf80fbf9 1153 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0, TRACER_DISPLAY_BASE_16);
d9359cfa
MD
1154}
1155
1156static
cf80fbf9
MD
1157void tracer_print_float(const struct side_type *type_desc,
1158 const struct side_arg *item,
1159 void *priv __attribute__((unused)))
d9359cfa 1160{
cf80fbf9 1161 tracer_print_type_float(":", &type_desc->u.side_float, &item->u.side_static.float_value);
d9359cfa
MD
1162}
1163
dd7947bf 1164static
cf80fbf9
MD
1165void tracer_print_string(const struct side_type *type_desc,
1166 const struct side_arg *item,
1167 void *priv __attribute__((unused)))
dd7947bf 1168{
f0619c77 1169 tracer_print_type_header("value", ":", side_ptr_get(type_desc->u.side_string.attr), type_desc->u.side_string.nr_attr);
cf80fbf9
MD
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);
dd7947bf
MD
1173}
1174
1175static
d7a0f92e 1176void tracer_before_print_struct(const struct side_type_struct *side_struct,
cf80fbf9 1177 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
dd7947bf 1178{
cf80fbf9
MD
1179 struct print_ctx *ctx = (struct print_ctx *) priv;
1180
d7a0f92e
MD
1181 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1182 printf("%s", side_struct->nr_attr ? ", " : "");
1183 printf("fields: {");
1184 push_nesting(ctx);
dd7947bf
MD
1185}
1186
d7a0f92e 1187
d9359cfa 1188static
d7a0f92e 1189void tracer_after_print_struct(const struct side_type_struct *side_struct __attribute__((unused)),
cf80fbf9 1190 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
7a1cb105 1191{
cf80fbf9 1192 struct print_ctx *ctx = (struct print_ctx *) priv;
65b8734a 1193
d7a0f92e
MD
1194 pop_nesting(ctx);
1195 printf(" }");
65b8734a
MD
1196}
1197
8ad2f385 1198static
d7a0f92e 1199void tracer_before_print_array(const struct side_type_array *side_array,
cf80fbf9 1200 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
8ad2f385 1201{
cf80fbf9 1202 struct print_ctx *ctx = (struct print_ctx *) priv;
8ad2f385 1203
d7a0f92e
MD
1204 print_attributes("attr", ":", side_ptr_get(side_array->attr), side_array->nr_attr);
1205 printf("%s", side_array->nr_attr ? ", " : "");
1206 printf("elements: [");
1207 push_nesting(ctx);
1208}
1209
1210static
1211void 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)
1213{
1214 struct print_ctx *ctx = (struct print_ctx *) priv;
1215
1216 pop_nesting(ctx);
1217 printf(" ]");
8ad2f385
MD
1218}
1219
f0619c77 1220static
d7a0f92e
MD
1221void 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)
1223{
1224 struct print_ctx *ctx = (struct print_ctx *) priv;
1225
1226 print_attributes("attr", ":", side_ptr_get(side_vla->attr), side_vla->nr_attr);
1227 printf("%s", side_vla->nr_attr ? ", " : "");
1228 printf("elements: [");
1229 push_nesting(ctx);
1230}
1231
1232
1233static
1234void 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)
1236{
1237 struct print_ctx *ctx = (struct print_ctx *) priv;
1238
1239 pop_nesting(ctx);
1240 printf(" ]");
1241}
1242
1243static
1244void tracer_before_print_vla(const struct side_type_vla *side_vla,
f0619c77
MD
1245 const struct side_arg_vec *side_arg_vec, void *priv)
1246{
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:
1258 break;
1259 default:
1260 fprintf(stderr, "ERROR: Unexpected vla length type\n");
1261 abort();
1262 }
d7a0f92e 1263 do_tracer_before_print_vla(side_vla, side_arg_vec, priv);
f0619c77
MD
1264}
1265
d69918cc 1266static
d7a0f92e
MD
1267void tracer_after_print_vla(const struct side_type_vla *side_vla,
1268 const struct side_arg_vec *side_arg_vec, void *priv)
1269{
1270 do_tracer_after_print_vla(side_vla, side_arg_vec, priv);
1271}
1272
1273static
1274void tracer_before_print_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor,
cf80fbf9 1275 const struct side_arg_vla_visitor *side_arg_vla_visitor __attribute__((unused)), void *priv)
d69918cc 1276{
cf80fbf9 1277 struct print_ctx *ctx = (struct print_ctx *) priv;
d69918cc 1278
f0619c77
MD
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:
1290 break;
1291 default:
1292 fprintf(stderr, "ERROR: Unexpected vla visitor length type\n");
1293 abort();
1294 }
1295
d7a0f92e
MD
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: [");
1299 push_nesting(ctx);
1300}
1301
1302static
1303void 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)
1305{
1306 struct print_ctx *ctx = (struct print_ctx *) priv;
1307
1308 pop_nesting(ctx);
1309 printf(" ]");
d69918cc
MD
1310}
1311
cf80fbf9
MD
1312static void tracer_print_enum(const struct side_type *type_desc,
1313 const struct side_arg *item, void *priv)
65b8734a 1314{
cf80fbf9
MD
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);
1317 union int_value v;
7a1cb105 1318
cf80fbf9
MD
1319 if (side_enum_get(elem_type->type) != side_enum_get(item->type)) {
1320 fprintf(stderr, "ERROR: Unexpected enum element type\n");
33956c71
MD
1321 abort();
1322 }
cf80fbf9
MD
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 ? ", " : "");
1327 printf("{ ");
1328 tracer_print_integer(elem_type, item, priv);
1329 printf(" }");
1330 print_enum_labels(mappings, v);
33956c71 1331}
9b641221 1332
cf80fbf9
MD
1333static void tracer_print_enum_bitmap(const struct side_type *type_desc,
1334 const struct side_arg *item, void *priv __attribute__((unused)))
905f68e3 1335{
cf80fbf9
MD
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;
905f68e3 1340
cf80fbf9
MD
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;
1354 array_item = item;
1355 nr_items = 1;
1356 break;
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;
1361 break;
1362 case SIDE_TYPE_VLA:
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;
905f68e3
MD
1366 break;
1367 default:
cf80fbf9 1368 fprintf(stderr, "ERROR: Unexpected enum element type\n");
905f68e3
MD
1369 abort();
1370 }
cf80fbf9 1371 stride_bit = elem_type_to_stride(elem_type);
905f68e3 1372
cf80fbf9
MD
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];
1378 bool match = false;
1379 uint64_t bit;
7d34edfc 1380
cf80fbf9
MD
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);
1384 abort();
1385 }
1386 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
1387 if (bit > (nr_items * stride_bit) - 1)
1388 break;
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))) {
1392 match = true;
1393 goto match;
1394 }
1395 } else {
1396 union int_value v = {};
1397
1398 v = tracer_load_integer_value(&elem_type->u.side_integer,
1399 &array_item[bit / stride_bit].u.side_static.integer_value,
1400 0, NULL);
1401 side_check_value_u64(v);
1402 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (bit % stride_bit))) {
1403 match = true;
1404 goto match;
1405 }
1406 }
1407 }
1408match:
1409 if (match) {
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);
1413 }
7d34edfc 1414 }
cf80fbf9
MD
1415 if (!print_count)
1416 printf("<NO LABEL>");
1417 printf(" ]");
7d34edfc
MD
1418}
1419
33956c71 1420static
cf80fbf9
MD
1421void tracer_print_gather_bool(const struct side_type_gather_bool *type,
1422 const union side_bool_value *value,
1423 void *priv __attribute__((unused)))
33956c71 1424{
cf80fbf9
MD
1425 tracer_print_type_bool(":", &type->type, value, type->offset_bits);
1426}
d9359cfa 1427
cf80fbf9
MD
1428static
1429void tracer_print_gather_byte(const struct side_type_gather_byte *type,
1430 const uint8_t *_ptr,
1431 void *priv __attribute__((unused)))
1432{
f0619c77 1433 tracer_print_type_header("value", ":", side_ptr_get(type->type.attr),
cf80fbf9
MD
1434 type->type.nr_attr);
1435 printf("0x%" PRIx8, *_ptr);
1436}
55fb50b7 1437
cf80fbf9
MD
1438static
1439void tracer_print_gather_integer(const struct side_type_gather_integer *type,
1440 const union side_integer_value *value,
1441 void *priv __attribute__((unused)))
1442{
1443 tracer_print_type_integer(":", &type->type, value, type->offset_bits, TRACER_DISPLAY_BASE_10);
1444}
0519cb86 1445
cf80fbf9
MD
1446static
1447void tracer_print_gather_pointer(const struct side_type_gather_integer *type,
1448 const union side_integer_value *value,
1449 void *priv __attribute__((unused)))
1450{
1451 tracer_print_type_integer(":", &type->type, value, type->offset_bits, TRACER_DISPLAY_BASE_16);
7a1cb105
MD
1452}
1453
0519cb86 1454static
cf80fbf9
MD
1455void tracer_print_gather_float(const struct side_type_gather_float *type,
1456 const union side_float_value *value,
1457 void *priv __attribute__((unused)))
0519cb86 1458{
cf80fbf9
MD
1459 tracer_print_type_float(":", &type->type, value);
1460}
0519cb86 1461
cf80fbf9
MD
1462static
1463void 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)))
1468{
1469 //TODO use strlen_with_null input
f0619c77 1470 tracer_print_type_header("value", ":", side_ptr_get(type->type.attr),
cf80fbf9
MD
1471 type->type.nr_attr);
1472 tracer_print_type_string(p, unit_size, byte_order, NULL);
0519cb86
MD
1473}
1474
7a1cb105 1475static
d7a0f92e 1476void tracer_before_print_gather_struct(const struct side_type_struct *side_struct, void *priv)
7a1cb105 1477{
d7a0f92e 1478 tracer_before_print_struct(side_struct, NULL, priv);
7a1cb105
MD
1479}
1480
1481static
d7a0f92e 1482void tracer_after_print_gather_struct(const struct side_type_struct *side_struct, void *priv)
7a1cb105 1483{
d7a0f92e 1484 tracer_after_print_struct(side_struct, NULL, priv);
cf80fbf9 1485}
7a1cb105 1486
cf80fbf9 1487static
d7a0f92e
MD
1488void tracer_before_print_gather_array(const struct side_type_array *side_array, void *priv)
1489{
1490 tracer_before_print_array(side_array, NULL, priv);
1491}
1492
1493static
1494void tracer_after_print_gather_array(const struct side_type_array *side_array, void *priv)
1495{
1496 tracer_after_print_array(side_array, NULL, priv);
1497}
1498
1499static
1500void tracer_before_print_gather_vla(const struct side_type_vla *side_vla,
1501 uint32_t length __attribute__((unused)), void *priv)
cf80fbf9 1502{
f0619c77
MD
1503 switch (side_enum_get(side_ptr_get(side_vla->length_type)->type)) {
1504 case SIDE_TYPE_GATHER_INTEGER:
1505 break;
1506 default:
1507 fprintf(stderr, "ERROR: Unexpected vla length type\n");
1508 abort();
1509 }
d7a0f92e
MD
1510 do_tracer_before_print_vla(side_vla, NULL, priv);
1511}
1512
1513
1514static
1515void tracer_after_print_gather_vla(const struct side_type_vla *side_vla,
1516 uint32_t length __attribute__((unused)), void *priv)
1517{
1518 do_tracer_after_print_vla(side_vla, NULL, priv);
7a1cb105
MD
1519}
1520
f611d0c3 1521static
cf80fbf9
MD
1522void tracer_print_gather_enum(const struct side_type_gather_enum *type,
1523 const union side_integer_value *value,
1524 void *priv __attribute__((unused)))
f611d0c3 1525{
cf80fbf9
MD
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;
1529 union int_value v;
f611d0c3 1530
cf80fbf9
MD
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 ? ", " : "");
1534 printf("{ ");
1535 tracer_print_type_integer(":", &side_integer->type, value, 0, TRACER_DISPLAY_BASE_10);
1536 printf(" }");
1537 print_enum_labels(mappings, v);
65b8734a
MD
1538}
1539
1540static
d7a0f92e 1541void tracer_before_print_dynamic_field(const struct side_arg_dynamic_field *field, void *priv)
65b8734a 1542{
cf80fbf9 1543 struct print_ctx *ctx = (struct print_ctx *) priv;
65b8734a 1544
d7a0f92e
MD
1545 if (get_nested_item_nr(ctx) != 0)
1546 printf(",");
1547 printf(" %s:: { ", side_ptr_get(field->field_name));
f611d0c3
MD
1548}
1549
352a4b77 1550static
d7a0f92e 1551void tracer_after_print_dynamic_field(const struct side_arg_dynamic_field *field __attribute__((unused)), void *priv)
352a4b77 1552{
d7a0f92e
MD
1553 struct print_ctx *ctx = (struct print_ctx *) priv;
1554
1555 printf(" }");
1556 inc_nested_item_nr(ctx);
1557}
1558
1559static
1560void tracer_before_print_dynamic_elem(const struct side_arg *dynamic_item __attribute__((unused)), void *priv)
1561{
1562 tracer_before_print_elem(NULL, priv);
1563}
1564
1565static
1566void tracer_after_print_dynamic_elem(const struct side_arg *dynamic_item __attribute__((unused)), void *priv)
1567{
1568 tracer_after_print_elem(NULL, priv);
352a4b77
MD
1569}
1570
f611d0c3 1571static
cf80fbf9
MD
1572void tracer_print_dynamic_null(const struct side_arg *item,
1573 void *priv __attribute__((unused)))
f611d0c3 1574{
f0619c77 1575 tracer_print_type_header("value", "::", side_ptr_get(item->u.side_dynamic.side_null.attr),
cf80fbf9
MD
1576 item->u.side_dynamic.side_null.nr_attr);
1577 printf("<NULL TYPE>");
f611d0c3
MD
1578}
1579
a2e2357e 1580static
cf80fbf9
MD
1581void tracer_print_dynamic_bool(const struct side_arg *item,
1582 void *priv __attribute__((unused)))
a2e2357e 1583{
cf80fbf9 1584 tracer_print_type_bool("::", &item->u.side_dynamic.side_bool.type, &item->u.side_dynamic.side_bool.value, 0);
a2e2357e
MD
1585}
1586
2b359235 1587static
cf80fbf9
MD
1588void tracer_print_dynamic_integer(const struct side_arg *item,
1589 void *priv __attribute__((unused)))
2b359235 1590{
cf80fbf9
MD
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);
2b359235
MD
1593}
1594
a2e2357e 1595static
cf80fbf9
MD
1596void tracer_print_dynamic_byte(const struct side_arg *item,
1597 void *priv __attribute__((unused)))
a2e2357e 1598{
f0619c77 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);
cf80fbf9 1600 printf("0x%" PRIx8, item->u.side_dynamic.side_byte.value);
a2e2357e
MD
1601}
1602
1603static
cf80fbf9
MD
1604void tracer_print_dynamic_pointer(const struct side_arg *item,
1605 void *priv __attribute__((unused)))
a2e2357e 1606{
cf80fbf9
MD
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);
1609}
a2e2357e 1610
cf80fbf9
MD
1611static
1612void tracer_print_dynamic_float(const struct side_arg *item,
1613 void *priv __attribute__((unused)))
1614{
1615 tracer_print_type_float("::", &item->u.side_dynamic.side_float.type,
1616 &item->u.side_dynamic.side_float.value);
a2e2357e
MD
1617}
1618
cf80fbf9
MD
1619static
1620void tracer_print_dynamic_string(const struct side_arg *item,
1621 void *priv __attribute__((unused)))
1622{
f0619c77 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);
cf80fbf9
MD
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);
1627}
8ceca0cd
MD
1628
1629static
d7a0f92e 1630void tracer_before_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct,
cf80fbf9 1631 void *priv)
8ceca0cd 1632{
cf80fbf9 1633 struct print_ctx *ctx = (struct print_ctx *) priv;
8ceca0cd 1634
d7a0f92e
MD
1635 print_attributes("attr", "::", side_ptr_get(dynamic_struct->attr), dynamic_struct->nr_attr);
1636 printf("%s", dynamic_struct->nr_attr ? ", " : "");
1637 printf("fields:: {");
1638 push_nesting(ctx);
8ceca0cd
MD
1639}
1640
a2e2357e 1641static
d7a0f92e 1642void tracer_after_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct __attribute__((unused)),
cf80fbf9 1643 void *priv)
d7a0f92e
MD
1644{
1645 struct print_ctx *ctx = (struct print_ctx *) priv;
1646
1647 pop_nesting(ctx);
1648 printf(" }");
1649}
1650
1651static
1652void tracer_before_print_dynamic_struct_visitor(const struct side_arg *item, void *priv)
a2e2357e 1653{
cf80fbf9
MD
1654 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
1655 struct print_ctx *ctx = (struct print_ctx *) priv;
8ceca0cd 1656
cf80fbf9
MD
1657 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
1658 if (!dynamic_struct_visitor)
8ceca0cd 1659 abort();
cf80fbf9 1660
d7a0f92e
MD
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:: {");
1664 push_nesting(ctx);
a2e2357e
MD
1665}
1666
1667static
d7a0f92e 1668void tracer_after_print_dynamic_struct_visitor(const struct side_arg *item, void *priv)
a2e2357e 1669{
d7a0f92e 1670 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
cf80fbf9 1671 struct print_ctx *ctx = (struct print_ctx *) priv;
55fb50b7 1672
d7a0f92e
MD
1673 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
1674 if (!dynamic_struct_visitor)
1675 abort();
1676
1677 pop_nesting(ctx);
1678 printf(" }");
a2e2357e
MD
1679}
1680
68f8cfbe 1681static
d7a0f92e
MD
1682void tracer_before_print_dynamic_vla(const struct side_arg_dynamic_vla *dynamic_vla, void *priv)
1683{
1684 struct print_ctx *ctx = (struct print_ctx *) priv;
1685
1686 print_attributes("attr", "::", side_ptr_get(dynamic_vla->attr), dynamic_vla->nr_attr);
1687 printf("%s", dynamic_vla->nr_attr ? ", " : "");
1688 printf("elements:: [");
1689 push_nesting(ctx);
1690}
1691
1692static
1693void tracer_after_print_dynamic_vla(const struct side_arg_dynamic_vla *dynamic_vla __attribute__((unused)), void *priv)
1694{
1695 struct print_ctx *ctx = (struct print_ctx *) priv;
1696
1697 pop_nesting(ctx);
1698 printf(" ]");
1699}
1700
1701static
1702void tracer_before_print_dynamic_vla_visitor(const struct side_arg *item, void *priv)
f611d0c3 1703{
cf80fbf9
MD
1704 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
1705 struct print_ctx *ctx = (struct print_ctx *) priv;
f611d0c3 1706
cf80fbf9
MD
1707 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
1708 if (!dynamic_vla_visitor)
f611d0c3 1709 abort();
cf80fbf9 1710
d7a0f92e
MD
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:: [");
1714 push_nesting(ctx);
1715}
1716
1717static
1718void tracer_after_print_dynamic_vla_visitor(const struct side_arg *item, void *priv)
1719{
1720 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
1721 struct print_ctx *ctx = (struct print_ctx *) priv;
1722
1723 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
1724 if (!dynamic_vla_visitor)
1725 abort();
1726
1727 pop_nesting(ctx);
1728 printf(" ]");
68f8cfbe
MD
1729}
1730
cf80fbf9 1731static struct side_type_visitor type_visitor = {
d7a0f92e
MD
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,
cf80fbf9
MD
1738
1739 /* Stack-copy basic types. */
d7a0f92e
MD
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,
cf80fbf9
MD
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,
1751
1752 /* Stack-copy compound types. */
d7a0f92e
MD
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,
cf80fbf9
MD
1761
1762 /* Stack-copy enumeration types. */
1763 .enum_type_func = tracer_print_enum,
1764 .enum_bitmap_type_func = tracer_print_enum_bitmap,
1765
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,
1773
1774 /* Gather compound types. */
d7a0f92e
MD
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,
cf80fbf9
MD
1781
1782 /* Gather enumeration types. */
1783 .gather_enum_type_func = tracer_print_gather_enum,
1784
1785 /* Dynamic basic types. */
d7a0f92e
MD
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,
cf80fbf9
MD
1790
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,
1798
1799 /* Dynamic compound types. */
d7a0f92e
MD
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,
cf80fbf9
MD
1808};
1809
9365e936 1810static
67337c4a
MD
1811void tracer_call(const struct side_event_description *desc,
1812 const struct side_arg_vec *side_arg_vec,
5e523511
MD
1813 void *priv __attribute__((unused)),
1814 void *caller_addr)
68f8cfbe 1815{
cf80fbf9 1816 struct print_ctx ctx = {};
a848763d 1817
cf80fbf9 1818 type_visitor_event(&type_visitor, desc, side_arg_vec, NULL, caller_addr, &ctx);
f611d0c3 1819}
19fa6aa2 1820
9365e936 1821static
67337c4a
MD
1822void 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,
5e523511
MD
1825 void *priv __attribute__((unused)),
1826 void *caller_addr)
19fa6aa2 1827{
cf80fbf9 1828 struct print_ctx ctx = {};
68f8cfbe 1829
cf80fbf9 1830 type_visitor_event(&type_visitor, desc, side_arg_vec, var_struct, caller_addr, &ctx);
19fa6aa2 1831}
1e8aec23 1832
f0619c77 1833static
10134383 1834void before_print_description_event(const struct side_event_description *desc, void *priv __attribute__((unused)))
f0619c77 1835{
10134383
MD
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);
f0619c77
MD
1838}
1839
1840static
10134383
MD
1841void after_print_description_event(const struct side_event_description *desc, void *priv __attribute__((unused)))
1842{
1843 if (desc->flags & SIDE_EVENT_FLAG_VARIADIC)
1844 printf(", <variadic fields>");
1845 printf("\n");
1846}
1847
1848static
1849void before_print_description_static_fields(const struct side_event_description *desc, void *priv)
f0619c77
MD
1850{
1851 struct print_ctx *ctx = (struct print_ctx *) priv;
1852 uint32_t len = desc->nr_fields;
1853
10134383
MD
1854 printf("%s", len ? ", fields: {" : "");
1855 push_nesting(ctx);
f0619c77
MD
1856}
1857
1858static
10134383 1859void after_print_description_static_fields(const struct side_event_description *desc, void *priv)
f0619c77
MD
1860{
1861 struct print_ctx *ctx = (struct print_ctx *) priv;
10134383 1862 uint32_t len = desc->nr_fields;
f0619c77 1863
10134383
MD
1864 pop_nesting(ctx);
1865 if (len)
f0619c77 1866 printf(" }");
f0619c77
MD
1867}
1868
1869static
10134383 1870void before_print_description_field(const struct side_event_field *item_desc, void *priv)
f0619c77
MD
1871{
1872 struct print_ctx *ctx = (struct print_ctx *) priv;
1873
10134383
MD
1874 if (get_nested_item_nr(ctx) != 0)
1875 printf(",");
1876 printf(" %s: { ", side_ptr_get(item_desc->field_name));
f0619c77
MD
1877}
1878
1879static
10134383 1880void after_print_description_field(const struct side_event_field *item_desc __attribute__((unused)), void *priv)
f0619c77
MD
1881{
1882 struct print_ctx *ctx = (struct print_ctx *) priv;
1883
10134383
MD
1884 printf(" }");
1885 inc_nested_item_nr(ctx);
1886}
1887
1888static
1889void before_print_description_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1890{
1891 struct print_ctx *ctx = (struct print_ctx *) priv;
1892
1893 if (get_nested_item_nr(ctx) != 0)
1894 printf(", { ");
1895 else
1896 printf(" { ");
1897}
1898
1899static
1900void after_print_description_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1901{
1902 struct print_ctx *ctx = (struct print_ctx *) priv;
1903
1904 printf(" }");
1905 inc_nested_item_nr(ctx);
1906}
1907
1908static
1909void before_print_description_option(const struct side_variant_option *option_desc, void *priv)
1910{
1911 struct print_ctx *ctx = (struct print_ctx *) priv;
1912
1913 if (get_nested_item_nr(ctx) != 0)
1914 printf(",");
1915 if (option_desc->range_begin == option_desc->range_end)
1916 printf(" [ %" PRIu64 " ]: { ",
1917 option_desc->range_begin);
1918 else
1919 printf(" [ %" PRIu64 " - %" PRIu64 " ]: { ",
1920 option_desc->range_begin,
1921 option_desc->range_end);
1922}
1923
1924static
1925void after_print_description_option(const struct side_variant_option *option_desc __attribute__((unused)), void *priv)
1926{
1927 struct print_ctx *ctx = (struct print_ctx *) priv;
1928
1929 printf(" }");
1930 inc_nested_item_nr(ctx);
f0619c77
MD
1931}
1932
1933static
1934void print_description_null(const struct side_type *type_desc,
1935 void *priv __attribute__((unused)))
1936{
1937 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_null.attr),
1938 type_desc->u.side_null.nr_attr);
1939 printf("null");
1940}
1941
1942static
1943void print_description_bool(const struct side_type *type_desc,
1944 void *priv __attribute__((unused)))
1945{
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);
1951 printf(" }");
1952}
1953
1954static
1955void print_description_integer(const struct side_type *type_desc,
1956 void *priv __attribute__((unused)))
1957{
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);
1966 printf(" }");
1967}
1968
1969static
1970void print_description_byte(const struct side_type *type_desc,
1971 void *priv __attribute__((unused)))
1972{
1973 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_byte.attr),
1974 type_desc->u.side_byte.nr_attr);
1975 printf("byte");
1976}
1977
1978static
1979void print_description_pointer(const struct side_type *type_desc,
1980 void *priv __attribute__((unused)))
1981{
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);
1990 printf(" }");
1991}
1992
1993static
1994void print_description_float(const struct side_type *type_desc,
1995 void *priv __attribute__((unused)))
1996{
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");
2002 printf(" }");
2003}
2004
2005static
2006void print_description_string(const struct side_type *type_desc,
2007 void *priv __attribute__((unused)))
2008{
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");
2016 printf(" }");
2017}
2018
2019static
10134383 2020void before_print_description_struct(const struct side_type_struct *side_struct, void *priv)
f0619c77
MD
2021{
2022 struct print_ctx *ctx = (struct print_ctx *) priv;
2023
10134383
MD
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: {");
2027 push_nesting(ctx);
f0619c77
MD
2028}
2029
10134383 2030
f0619c77 2031static
10134383 2032void after_print_description_struct(const struct side_type_struct *side_struct __attribute__((unused)), void *priv)
f0619c77
MD
2033{
2034 struct print_ctx *ctx = (struct print_ctx *) priv;
2035
10134383
MD
2036 pop_nesting(ctx);
2037 printf(" } }");
f0619c77
MD
2038}
2039
2040static
10134383 2041void before_print_description_variant(const struct side_type_variant *side_variant, void *priv)
f0619c77
MD
2042{
2043 struct print_ctx *ctx = (struct print_ctx *) priv;
2044
10134383
MD
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: {");
2048 push_nesting(ctx);
f0619c77
MD
2049}
2050
2051static
10134383 2052void after_print_description_variant(const struct side_type_variant *side_variant __attribute__((unused)), void *priv)
f0619c77
MD
2053{
2054 struct print_ctx *ctx = (struct print_ctx *) priv;
2055
10134383
MD
2056 pop_nesting(ctx);
2057 printf(" } }");
f0619c77
MD
2058}
2059
2060static
10134383 2061void before_print_description_array(const struct side_type_array *side_array, void *priv)
f0619c77
MD
2062{
2063 struct print_ctx *ctx = (struct print_ctx *) priv;
2064
10134383
MD
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);
2068 push_nesting(ctx);
f0619c77
MD
2069}
2070
10134383 2071
f0619c77 2072static
10134383 2073void after_print_description_array(const struct side_type_array *side_array __attribute__((unused)), void *priv)
f0619c77 2074{
10134383 2075 struct print_ctx *ctx = (struct print_ctx *) priv;
f0619c77 2076
10134383
MD
2077 pop_nesting(ctx);
2078 printf(" }");
2079}
f0619c77 2080
10134383
MD
2081static
2082void before_print_description_vla(const struct side_type_vla *side_vla, void *priv)
2083{
2084 struct print_ctx *ctx = (struct print_ctx *) priv;
f0619c77 2085
10134383
MD
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:");
2089 push_nesting(ctx);
2090}
2091
2092static
2093void after_length_print_description_vla(const struct side_type_vla *side_vla __attribute__((unused)), void *priv)
2094{
2095 struct print_ctx *ctx = (struct print_ctx *) priv;
2096
2097 pop_nesting(ctx);
2098 printf(", element:");
2099 push_nesting(ctx);
2100}
2101
2102static
2103void after_element_print_description_vla(const struct side_type_vla *side_vla __attribute__((unused)), void *priv)
2104{
2105 struct print_ctx *ctx = (struct print_ctx *) priv;
2106
2107 pop_nesting(ctx);
2108 printf(" }");
2109}
2110
2111static
2112void before_print_description_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor, void *priv)
2113{
2114 struct print_ctx *ctx = (struct print_ctx *) priv;
2115
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:");
2119 push_nesting(ctx);
2120}
2121
2122static
2123void after_length_print_description_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor __attribute__((unused)), void *priv)
2124{
2125 struct print_ctx *ctx = (struct print_ctx *) priv;
2126
2127 pop_nesting(ctx);
2128 printf(", element:");
2129 push_nesting(ctx);
2130}
2131
2132static
2133void after_element_print_description_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor __attribute__((unused)), void *priv)
2134{
2135 struct print_ctx *ctx = (struct print_ctx *) priv;
2136
2137 pop_nesting(ctx);
2138 printf(" }");
2139}
2140
2141static
2142void do_before_print_description_enum(const char *type_name, const struct side_enum_mappings *mappings, void *priv __attribute__((unused)))
2143{
2144 uint32_t i, print_count = 0;
2145
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];
2150
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);
2154 abort();
2155 }
2156 printf("%s", print_count++ ? ", " : "");
2157 if (mapping->range_begin == mapping->range_end)
2158 printf("[ %" PRIu64 " ]: ", mapping->range_begin);
2159 else
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);
f0619c77 2164 }
10134383
MD
2165 if (!print_count)
2166 printf("<NO LABEL>");
2167
2168 printf(" }, element: { ");
f0619c77
MD
2169}
2170
10134383 2171
f0619c77 2172static
10134383
MD
2173void do_after_print_description_enum(const char *type_name __attribute__((unused)), const struct side_enum_mappings *mappings __attribute__((unused)), void *priv __attribute__((unused)))
2174{
2175 printf(" }");
2176}
2177
2178static
2179void before_print_description_enum(const struct side_type *type_desc, void *priv)
f0619c77
MD
2180{
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);
2183
2184 switch (side_enum_get(elem_type->type)) {
2185 case SIDE_TYPE_U8:
2186 case SIDE_TYPE_U16:
2187 case SIDE_TYPE_U32:
2188 case SIDE_TYPE_U64:
2189 case SIDE_TYPE_U128:
2190 case SIDE_TYPE_S8:
2191 case SIDE_TYPE_S16:
2192 case SIDE_TYPE_S32:
2193 case SIDE_TYPE_S64:
2194 case SIDE_TYPE_S128:
2195 break;
2196 default:
2197 fprintf(stderr, "Unsupported enum element type.\n");
2198 abort();
2199 }
10134383 2200 do_before_print_description_enum("enum", mappings, priv);
f0619c77
MD
2201}
2202
2203static
10134383 2204void after_print_description_enum(const struct side_type *type_desc, void *priv)
f0619c77 2205{
10134383
MD
2206 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
2207
2208 do_after_print_description_enum("enum", mappings, priv);
2209}
f0619c77 2210
10134383
MD
2211static
2212void before_print_description_enum_bitmap(const struct side_type *type_desc, void *priv __attribute__((unused)))
2213{
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;
2217
2218 switch (side_enum_get(elem_type->type)) {
2219 case SIDE_TYPE_BYTE:
2220 case SIDE_TYPE_U8:
2221 case SIDE_TYPE_U16:
2222 case SIDE_TYPE_U32:
2223 case SIDE_TYPE_U64:
2224 case SIDE_TYPE_U128:
2225 case SIDE_TYPE_ARRAY:
2226 case SIDE_TYPE_VLA:
f0619c77 2227 break;
10134383
MD
2228 default:
2229 fprintf(stderr, "Unsupported enum element type.\n");
2230 abort();
f0619c77 2231 }
10134383
MD
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];
2236
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);
2240 abort();
2241 }
2242 printf("%s", print_count++ ? ", " : "");
2243 if (mapping->range_begin == mapping->range_end)
2244 printf("[ %" PRIu64 " ]: ", mapping->range_begin);
2245 else
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);
f0619c77 2250 }
10134383
MD
2251 if (!print_count)
2252 printf("<NO LABEL>");
2253
2254 printf(" }, element: { ");
2255}
2256
2257static
2258void after_print_description_enum_bitmap(const struct side_type *type_desc __attribute__((unused)), void *priv __attribute__((unused)))
2259{
2260 printf(" }");
f0619c77
MD
2261}
2262
2263static
2264void print_description_gather_bool(const struct side_type_gather_bool *type,
2265 void *priv __attribute__((unused)))
2266{
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\"");
2275 printf(" }");
2276}
2277
2278static
2279void print_description_gather_byte(const struct side_type_gather_byte *type,
2280 void *priv __attribute__((unused)))
2281{
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 }",
2285 type->offset,
2286 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2287}
2288
2289static
2290void print_description_gather_integer(const struct side_type_gather_integer *type,
2291 void *priv __attribute__((unused)))
2292{
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\"");
2304 printf(" }");
2305}
2306
2307static
2308void print_description_gather_pointer(const struct side_type_gather_integer *type,
2309 void *priv __attribute__((unused)))
2310{
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\"");
2322 printf(" }");
2323}
2324
2325static
2326void print_description_gather_float(const struct side_type_gather_float *type,
2327 void *priv __attribute__((unused)))
2328{
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",
2335 type->offset,
2336 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2337 printf(" }");
2338}
2339
2340static
2341void print_description_gather_string(const struct side_type_gather_string *type,
2342 void *priv __attribute__((unused)))
2343{
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",
2352 type->offset,
2353 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2354 printf(" }");
2355}
2356
2357static
10134383 2358void before_print_description_gather_struct(const struct side_type_gather_struct *side_gather_struct, void *priv)
f0619c77
MD
2359{
2360 const struct side_type_struct *side_struct = side_ptr_get(side_gather_struct->type);
2361 struct print_ctx *ctx = (struct print_ctx *) priv;
2362
10134383
MD
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\"");
2368 push_nesting(ctx);
2369}
2370
2371static
2372void after_print_description_gather_struct(const struct side_type_gather_struct *side_gather_struct __attribute__((unused)), void *priv)
2373{
2374 struct print_ctx *ctx = (struct print_ctx *) priv;
2375
2376 pop_nesting(ctx);
2377 printf(" } }");
f0619c77
MD
2378}
2379
2380static
10134383 2381void before_print_description_gather_array(const struct side_type_gather_array *side_gather_array, void *priv)
f0619c77
MD
2382{
2383 const struct side_type_array *side_array = &side_gather_array->type;
2384 struct print_ctx *ctx = (struct print_ctx *) priv;
2385
10134383
MD
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\"");
2391 push_nesting(ctx);
2392}
2393
2394static
2395void after_print_description_gather_array(const struct side_type_gather_array *side_gather_array __attribute__((unused)), void *priv)
2396{
2397 struct print_ctx *ctx = (struct print_ctx *) priv;
2398
2399 pop_nesting(ctx);
2400 printf(" }");
f0619c77
MD
2401}
2402
2403static
10134383 2404void before_print_description_gather_vla(const struct side_type_gather_vla *side_gather_vla, void *priv)
f0619c77
MD
2405{
2406 const struct side_type_vla *side_vla = &side_gather_vla->type;
2407 struct print_ctx *ctx = (struct print_ctx *) priv;
2408
10134383
MD
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\"");
2414 push_nesting(ctx);
f0619c77
MD
2415}
2416
2417static
10134383
MD
2418void after_length_print_description_gather_vla(const struct side_type_gather_vla *side_gather_vla __attribute__((unused)), void *priv)
2419{
2420 struct print_ctx *ctx = (struct print_ctx *) priv;
2421
2422 pop_nesting(ctx);
2423 printf(", element:");
2424 push_nesting(ctx);
2425}
2426
2427static
2428void after_element_print_description_gather_vla(const struct side_type_gather_vla *side_gather_vla __attribute__((unused)), void *priv)
2429{
2430 struct print_ctx *ctx = (struct print_ctx *) priv;
2431
2432 pop_nesting(ctx);
2433 printf(" }");
2434}
2435
2436static
2437void before_print_description_gather_enum(const struct side_type_gather_enum *type, void *priv)
f0619c77
MD
2438{
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);
2441
2442 if (side_enum_get(elem_type->type) != SIDE_TYPE_GATHER_INTEGER) {
2443 fprintf(stderr, "Unsupported enum element type.\n");
2444 abort();
2445 }
10134383
MD
2446 do_before_print_description_enum("gather_enum", mappings, priv);
2447}
2448
2449static
2450void after_print_description_gather_enum(const struct side_type_gather_enum *type, void *priv)
2451{
2452 const struct side_enum_mappings *mappings = side_ptr_get(type->mappings);
2453
2454 do_after_print_description_enum("gather_enum", mappings, priv);
f0619c77
MD
2455}
2456
2457static
2458void print_description_dynamic(const struct side_type *type_desc __attribute__((unused)), void *priv __attribute__((unused)))
2459{
2460 printf("type: dynamic");
2461}
2462
2463static
2464struct side_description_visitor description_visitor = {
10134383
MD
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,
f0619c77
MD
2469
2470 /* Stack-copy basic types. */
10134383
MD
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,
f0619c77
MD
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,
2484
2485 /* Stack-copy compound types. */
10134383
MD
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,
f0619c77
MD
2498
2499 /* Stack-copy enumeration types. */
10134383
MD
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,
f0619c77
MD
2504
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,
2512
2513 /* Gather compound types. */
10134383
MD
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,
f0619c77
MD
2521
2522 /* Gather enumeration types. */
10134383
MD
2523 .before_gather_enum_type_func = before_print_description_gather_enum,
2524 .after_gather_enum_type_func = after_print_description_gather_enum,
f0619c77
MD
2525
2526 /* Dynamic types. */
2527 .dynamic_type_func = print_description_dynamic,
2528};
2529
2530static
2531void print_event_description(const struct side_event_description *desc)
2532{
2533 struct print_ctx ctx = {};
2534
2535 description_visitor_event(&description_visitor, desc, &ctx);
2536}
2537
9365e936 2538static
67337c4a
MD
2539void tracer_event_notification(enum side_tracer_notification notif,
2540 struct side_event_description **events, uint32_t nr_events,
9365e936 2541 void *priv __attribute__((unused)))
1e8aec23
MD
2542{
2543 uint32_t i;
314c22c3 2544 int ret;
1e8aec23
MD
2545
2546 printf("----------------------------------------------------------\n");
2547 printf("Tracer notified of events %s\n",
67337c4a 2548 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1e8aec23 2549 for (i = 0; i < nr_events; i++) {
67337c4a 2550 struct side_event_description *event = events[i];
1e8aec23
MD
2551
2552 /* Skip NULL pointers */
2553 if (!event)
2554 continue;
b2a84b9f
MD
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);
441235e7
MD
2558 return;
2559 }
1e8aec23 2560 printf("provider: %s, event: %s\n",
0b9e59d6 2561 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
441235e7 2562 if (event->struct_size != side_offsetofend(struct side_event_description, side_event_description_orig_abi_last)) {
b2a84b9f 2563 printf("Warning: Event %s.%s description contains fields unknown to the tracer\n",
441235e7
MD
2564 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
2565 }
78dd4cc3 2566 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
2d8e1a70
MD
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);
2571 }
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);
2576 }
f0619c77 2577 print_event_description(event);
67337c4a 2578 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
bffe9ae3 2579 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL, tracer_key);
314c22c3
MD
2580 if (ret)
2581 abort();
2582 } else {
bffe9ae3 2583 ret = side_tracer_callback_register(event, tracer_call, NULL, tracer_key);
314c22c3
MD
2584 if (ret)
2585 abort();
2586 }
2587 } else {
67337c4a 2588 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
bffe9ae3 2589 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL, tracer_key);
314c22c3
MD
2590 if (ret)
2591 abort();
2592 } else {
bffe9ae3 2593 ret = side_tracer_callback_unregister(event, tracer_call, NULL, tracer_key);
314c22c3
MD
2594 if (ret)
2595 abort();
2596 }
2597 }
1e8aec23
MD
2598 }
2599 printf("----------------------------------------------------------\n");
2600}
2601
2602static __attribute__((constructor))
2603void tracer_init(void);
2604static
2605void tracer_init(void)
2606{
bffe9ae3
MD
2607 if (side_tracer_request_key(&tracer_key))
2608 abort();
67337c4a 2609 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1e8aec23
MD
2610 if (!tracer_handle)
2611 abort();
2612}
2613
2614static __attribute__((destructor))
2615void tracer_exit(void);
2616static
2617void tracer_exit(void)
2618{
67337c4a 2619 side_tracer_event_notification_unregister(tracer_handle);
1e8aec23 2620}
This page took 0.165203 seconds and 4 git commands to generate.