pretty print tracer: Use argument vector visitor
[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
MD
16#include "visit-arg-vec.h"
17
0160d2c0
MD
18/* TODO: optionally print caller address. */
19static bool print_caller = false;
20
cf80fbf9
MD
21#define MAX_NESTING 32
22
1d9c515c
MD
23enum tracer_display_base {
24 TRACER_DISPLAY_BASE_2,
25 TRACER_DISPLAY_BASE_8,
26 TRACER_DISPLAY_BASE_10,
27 TRACER_DISPLAY_BASE_16,
28};
29
0cbdadb5
MD
30union int_value {
31 uint64_t u[NR_SIDE_INTEGER128_SPLIT];
32 int64_t s[NR_SIDE_INTEGER128_SPLIT];
4f5e1b67
MD
33};
34
cf80fbf9
MD
35struct print_ctx {
36 int nesting; /* Keep track of nesting, useful for tabulations. */
37 int item_nr[MAX_NESTING]; /* Item number in current nesting level, useful for comma-separated lists. */
38};
39
67337c4a 40static struct side_tracer_handle *tracer_handle;
1e8aec23 41
bffe9ae3
MD
42static uint64_t tracer_key;
43
52990f65 44static
67337c4a 45void tracer_convert_string_to_utf8(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
9ceac3e2
MD
46 size_t *strlen_with_null,
47 char **output_str)
52990f65 48{
3e60053f 49 size_t ret, inbytesleft = 0, outbytesleft, bufsize, input_size;
52990f65
MD
50 const char *str = p, *fromcode;
51 char *inbuf = (char *) p, *outbuf, *buf;
52 iconv_t cd;
53
54 switch (unit_size) {
55 case 1:
52990f65
MD
56 if (strlen_with_null)
57 *strlen_with_null = strlen(str) + 1;
9ceac3e2 58 *output_str = (char *) str;
52990f65
MD
59 return;
60 case 2:
61 {
62 const uint16_t *p16 = p;
63
64 switch (byte_order) {
67337c4a 65 case SIDE_TYPE_BYTE_ORDER_LE:
52990f65
MD
66 {
67 fromcode = "UTF-16LE";
68 break;
69 }
67337c4a 70 case SIDE_TYPE_BYTE_ORDER_BE:
52990f65
MD
71 {
72 fromcode = "UTF-16BE";
73 break;
74 }
75 default:
76 fprintf(stderr, "Unknown byte order\n");
77 abort();
78 }
79 for (; *p16; p16++)
80 inbytesleft += 2;
3e60053f 81 input_size = inbytesleft + 2;
52990f65
MD
82 /*
83 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
84 * { ef, bf, bf } UTF-8 (3 bytes).
85 */
86 bufsize = inbytesleft / 2 * 3 + 1;
87 break;
88 }
89 case 4:
90 {
91 const uint32_t *p32 = p;
92
93 switch (byte_order) {
67337c4a 94 case SIDE_TYPE_BYTE_ORDER_LE:
52990f65
MD
95 {
96 fromcode = "UTF-32LE";
97 break;
98 }
67337c4a 99 case SIDE_TYPE_BYTE_ORDER_BE:
52990f65
MD
100 {
101 fromcode = "UTF-32BE";
102 break;
103 }
104 default:
105 fprintf(stderr, "Unknown byte order\n");
106 abort();
107 }
108 for (; *p32; p32++)
109 inbytesleft += 4;
3e60053f 110 input_size = inbytesleft + 4;
52990f65
MD
111 /*
112 * Each 4-byte UTF-32 character converts to at most a
113 * 4-byte UTF-8 character.
114 */
115 bufsize = inbytesleft + 1;
116 break;
117 }
118 default:
119 fprintf(stderr, "Unknown string unit size %" PRIu8 "\n", unit_size);
120 abort();
121 }
122
123 cd = iconv_open("UTF8", fromcode);
124 if (cd == (iconv_t) -1) {
125 perror("iconv_open");
126 abort();
127 }
128 buf = malloc(bufsize);
129 if (!buf) {
130 abort();
131 }
132 outbuf = (char *) buf;
133 outbytesleft = bufsize;
134 ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
135 if (ret == (size_t) -1) {
136 perror("iconv");
137 abort();
138 }
139 if (inbytesleft) {
140 fprintf(stderr, "Buffer too small to convert string input\n");
141 abort();
142 }
143 (*outbuf++) = '\0';
52990f65
MD
144 if (iconv_close(cd) == -1) {
145 perror("iconv_close");
146 abort();
147 }
9ceac3e2 148 if (strlen_with_null)
3e60053f 149 *strlen_with_null = input_size;
9ceac3e2
MD
150 *output_str = buf;
151}
152
153static
cf80fbf9 154void tracer_print_type_string(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
9ceac3e2
MD
155 size_t *strlen_with_null)
156{
157 char *output_str = NULL;
158
159 tracer_convert_string_to_utf8(p, unit_size, byte_order, strlen_with_null, &output_str);
160 printf("\"%s\"", output_str);
161 if (output_str != p)
162 free(output_str);
52990f65
MD
163}
164
1d9c515c 165static
0cbdadb5
MD
166void side_check_value_u64(union int_value v)
167{
168 if (v.u[SIDE_INTEGER128_SPLIT_HIGH]) {
169 fprintf(stderr, "Unexpected integer value\n");
170 abort();
171 }
172}
173
174static
175void side_check_value_s64(union int_value v)
176{
177 if (v.s[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << 63)) {
178 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] != ~0LL) {
179 fprintf(stderr, "Unexpected integer value\n");
180 abort();
181 }
182 } else {
183 if (v.s[SIDE_INTEGER128_SPLIT_HIGH]) {
184 fprintf(stderr, "Unexpected integer value\n");
185 abort();
186 }
187 }
188}
189
190static
191int64_t get_attr_integer64_value(const struct side_attr *attr)
1d9c515c
MD
192{
193 int64_t val;
194
15f17024 195 switch (side_enum_get(attr->value.type)) {
67337c4a
MD
196 case SIDE_ATTR_TYPE_U8:
197 val = attr->value.u.integer_value.side_u8;
1d9c515c 198 break;
67337c4a
MD
199 case SIDE_ATTR_TYPE_U16:
200 val = attr->value.u.integer_value.side_u16;
1d9c515c 201 break;
67337c4a
MD
202 case SIDE_ATTR_TYPE_U32:
203 val = attr->value.u.integer_value.side_u32;
1d9c515c 204 break;
67337c4a
MD
205 case SIDE_ATTR_TYPE_U64:
206 val = attr->value.u.integer_value.side_u64;
1d9c515c 207 break;
0cbdadb5
MD
208 case SIDE_ATTR_TYPE_U128:
209 {
210 union int_value v = {
211 .u = {
212 [SIDE_INTEGER128_SPLIT_LOW] = attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW],
213 [SIDE_INTEGER128_SPLIT_HIGH] = attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH],
214 },
215 };
216 side_check_value_u64(v);
217 val = v.u[SIDE_INTEGER128_SPLIT_LOW];
218 break;
219 }
67337c4a
MD
220 case SIDE_ATTR_TYPE_S8:
221 val = attr->value.u.integer_value.side_s8;
1d9c515c 222 break;
67337c4a
MD
223 case SIDE_ATTR_TYPE_S16:
224 val = attr->value.u.integer_value.side_s16;
1d9c515c 225 break;
67337c4a
MD
226 case SIDE_ATTR_TYPE_S32:
227 val = attr->value.u.integer_value.side_s32;
1d9c515c 228 break;
67337c4a
MD
229 case SIDE_ATTR_TYPE_S64:
230 val = attr->value.u.integer_value.side_s64;
1d9c515c 231 break;
0cbdadb5
MD
232 case SIDE_ATTR_TYPE_S128:
233 {
234 union int_value v = {
235 .s = {
236 [SIDE_INTEGER128_SPLIT_LOW] = attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW],
237 [SIDE_INTEGER128_SPLIT_HIGH] = attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH],
238 },
239 };
240 side_check_value_s64(v);
241 val = v.s[SIDE_INTEGER128_SPLIT_LOW];
242 break;
243 }
1d9c515c
MD
244 default:
245 fprintf(stderr, "Unexpected attribute type\n");
246 abort();
247 }
248 return val;
249}
250
251static
67337c4a 252enum tracer_display_base get_attr_display_base(const struct side_attr *_attr, uint32_t nr_attr,
f0dafd60 253 enum tracer_display_base default_base)
1d9c515c
MD
254{
255 uint32_t i;
256
257 for (i = 0; i < nr_attr; i++) {
67337c4a 258 const struct side_attr *attr = &_attr[i];
9ceac3e2
MD
259 char *utf8_str = NULL;
260 bool cmp;
1d9c515c 261
3db2d8a1 262 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
3bc9ba43 263 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
9ceac3e2 264 cmp = strcmp(utf8_str, "std.integer.base");
3db2d8a1 265 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2
MD
266 free(utf8_str);
267 if (!cmp) {
0cbdadb5 268 int64_t val = get_attr_integer64_value(attr);
1d9c515c
MD
269
270 switch (val) {
271 case 2:
272 return TRACER_DISPLAY_BASE_2;
273 case 8:
274 return TRACER_DISPLAY_BASE_8;
275 case 10:
276 return TRACER_DISPLAY_BASE_10;
277 case 16:
278 return TRACER_DISPLAY_BASE_16;
279 default:
280 fprintf(stderr, "Unexpected integer display base: %" PRId64 "\n", val);
281 abort();
282 }
283 }
284 }
f0dafd60 285 return default_base; /* Default */
1d9c515c
MD
286}
287
bc3c89b3 288static
67337c4a 289void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
bc3c89b3 290{
9ceac3e2
MD
291 char *utf8_str = NULL;
292
3db2d8a1 293 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
3bc9ba43 294 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
9ceac3e2 295 printf("{ key%s \"%s\", value%s ", separator, utf8_str, separator);
3db2d8a1 296 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2 297 free(utf8_str);
15f17024 298 switch (side_enum_get(attr->value.type)) {
67337c4a 299 case SIDE_ATTR_TYPE_BOOL:
5f82db91 300 printf("%s", attr->value.u.bool_value ? "true" : "false");
bc3c89b3 301 break;
67337c4a
MD
302 case SIDE_ATTR_TYPE_U8:
303 printf("%" PRIu8, attr->value.u.integer_value.side_u8);
bc3c89b3 304 break;
67337c4a
MD
305 case SIDE_ATTR_TYPE_U16:
306 printf("%" PRIu16, attr->value.u.integer_value.side_u16);
bc3c89b3 307 break;
67337c4a
MD
308 case SIDE_ATTR_TYPE_U32:
309 printf("%" PRIu32, attr->value.u.integer_value.side_u32);
bc3c89b3 310 break;
67337c4a
MD
311 case SIDE_ATTR_TYPE_U64:
312 printf("%" PRIu64, attr->value.u.integer_value.side_u64);
bc3c89b3 313 break;
0cbdadb5
MD
314 case SIDE_ATTR_TYPE_U128:
315 if (attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
316 printf("0x%" PRIx64, attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW]);
317 } else {
318 printf("0x%" PRIx64 "%016" PRIx64,
319 attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH],
320 attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW]);
321 }
322 break;
67337c4a
MD
323 case SIDE_ATTR_TYPE_S8:
324 printf("%" PRId8, attr->value.u.integer_value.side_s8);
bc3c89b3 325 break;
67337c4a
MD
326 case SIDE_ATTR_TYPE_S16:
327 printf("%" PRId16, attr->value.u.integer_value.side_s16);
bc3c89b3 328 break;
67337c4a
MD
329 case SIDE_ATTR_TYPE_S32:
330 printf("%" PRId32, attr->value.u.integer_value.side_s32);
bc3c89b3 331 break;
67337c4a
MD
332 case SIDE_ATTR_TYPE_S64:
333 printf("%" PRId64, attr->value.u.integer_value.side_s64);
bc3c89b3 334 break;
0cbdadb5
MD
335 case SIDE_ATTR_TYPE_S128:
336 if (attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
337 printf("0x%" PRIx64, attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW]);
338 } else {
339 printf("0x%" PRIx64 "%016" PRIx64,
340 attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH],
341 attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW]);
342 }
343 break;
67337c4a 344 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
bc3c89b3 345#if __HAVE_FLOAT16
67337c4a 346 printf("%g", (double) attr->value.u.float_value.side_float_binary16);
bc3c89b3
MD
347 break;
348#else
de1b3cd2 349 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
bc3c89b3
MD
350 abort();
351#endif
67337c4a 352 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
bc3c89b3 353#if __HAVE_FLOAT32
67337c4a 354 printf("%g", (double) attr->value.u.float_value.side_float_binary32);
bc3c89b3
MD
355 break;
356#else
de1b3cd2 357 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
bc3c89b3
MD
358 abort();
359#endif
67337c4a 360 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
bc3c89b3 361#if __HAVE_FLOAT64
67337c4a 362 printf("%g", (double) attr->value.u.float_value.side_float_binary64);
bc3c89b3
MD
363 break;
364#else
de1b3cd2 365 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
bc3c89b3
MD
366 abort();
367#endif
67337c4a 368 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
bc3c89b3 369#if __HAVE_FLOAT128
67337c4a 370 printf("%Lg", (long double) attr->value.u.float_value.side_float_binary128);
bc3c89b3
MD
371 break;
372#else
de1b3cd2 373 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
bc3c89b3
MD
374 abort();
375#endif
67337c4a 376 case SIDE_ATTR_TYPE_STRING:
cf80fbf9 377 tracer_print_type_string(side_ptr_get(attr->value.u.string_value.p),
ab8a626e 378 attr->value.u.string_value.unit_size,
3bc9ba43 379 side_enum_get(attr->value.u.string_value.byte_order), NULL);
bc3c89b3
MD
380 break;
381 default:
de1b3cd2 382 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
bc3c89b3
MD
383 abort();
384 }
385 printf(" }");
386}
387
7d21cf51 388static
905c328e 389void print_attributes(const char *prefix_str, const char *separator,
67337c4a 390 const struct side_attr *attr, uint32_t nr_attr)
7d21cf51 391{
e65f9ce5 392 uint32_t i;
7d21cf51
MD
393
394 if (!nr_attr)
395 return;
cf80fbf9 396 printf("%s%s [", prefix_str, separator);
7d21cf51 397 for (i = 0; i < nr_attr; i++) {
cf80fbf9 398 printf("%s", i ? ", " : " ");
905c328e 399 tracer_print_attr_type(separator, &attr[i]);
7d21cf51
MD
400 }
401 printf(" ]");
402}
403
79f677ba 404static
0cbdadb5 405union int_value tracer_load_integer_value(const struct side_type_integer *type_integer,
67337c4a 406 const union side_integer_value *value,
f6a2a8ed 407 uint16_t offset_bits, uint16_t *_len_bits)
79f677ba 408{
0cbdadb5 409 union int_value v = {};
f6a2a8ed
MD
410 uint16_t len_bits;
411 bool reverse_bo;
79f677ba 412
f6a2a8ed
MD
413 if (!type_integer->len_bits)
414 len_bits = type_integer->integer_size * CHAR_BIT;
415 else
416 len_bits = type_integer->len_bits;
417 if (len_bits + offset_bits > type_integer->integer_size * CHAR_BIT)
d8be25de 418 abort();
3bc9ba43 419 reverse_bo = side_enum_get(type_integer->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
f6a2a8ed
MD
420 switch (type_integer->integer_size) {
421 case 1:
422 if (type_integer->signedness)
0cbdadb5 423 v.s[SIDE_INTEGER128_SPLIT_LOW] = value->side_s8;
f6a2a8ed 424 else
0cbdadb5 425 v.u[SIDE_INTEGER128_SPLIT_LOW] = value->side_u8;
d8be25de 426 break;
f6a2a8ed
MD
427 case 2:
428 if (type_integer->signedness) {
67337c4a 429 int16_t side_s16;
8bdd5c12 430
67337c4a 431 side_s16 = value->side_s16;
f6a2a8ed 432 if (reverse_bo)
67337c4a 433 side_s16 = side_bswap_16(side_s16);
0cbdadb5 434 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s16;
f6a2a8ed 435 } else {
67337c4a 436 uint16_t side_u16;
8bdd5c12 437
67337c4a 438 side_u16 = value->side_u16;
f6a2a8ed 439 if (reverse_bo)
67337c4a 440 side_u16 = side_bswap_16(side_u16);
0cbdadb5 441 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u16;
f6a2a8ed 442 }
d8be25de 443 break;
f6a2a8ed
MD
444 case 4:
445 if (type_integer->signedness) {
67337c4a 446 int32_t side_s32;
8bdd5c12 447
67337c4a 448 side_s32 = value->side_s32;
f6a2a8ed 449 if (reverse_bo)
67337c4a 450 side_s32 = side_bswap_32(side_s32);
0cbdadb5 451 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s32;
f6a2a8ed 452 } else {
67337c4a 453 uint32_t side_u32;
8bdd5c12 454
67337c4a 455 side_u32 = value->side_u32;
f6a2a8ed 456 if (reverse_bo)
67337c4a 457 side_u32 = side_bswap_32(side_u32);
0cbdadb5 458 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u32;
f6a2a8ed 459 }
d8be25de 460 break;
f6a2a8ed
MD
461 case 8:
462 if (type_integer->signedness) {
67337c4a 463 int64_t side_s64;
8bdd5c12 464
67337c4a 465 side_s64 = value->side_s64;
f6a2a8ed 466 if (reverse_bo)
67337c4a 467 side_s64 = side_bswap_64(side_s64);
0cbdadb5 468 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64;
f6a2a8ed 469 } else {
67337c4a 470 uint64_t side_u64;
8bdd5c12 471
67337c4a 472 side_u64 = value->side_u64;
f6a2a8ed 473 if (reverse_bo)
67337c4a 474 side_u64 = side_bswap_64(side_u64);
0cbdadb5
MD
475 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64;
476 }
477 break;
478 case 16:
479 if (type_integer->signedness) {
480 int64_t side_s64[NR_SIDE_INTEGER128_SPLIT];
481
482 side_s64[SIDE_INTEGER128_SPLIT_LOW] = value->side_s128_split[SIDE_INTEGER128_SPLIT_LOW];
483 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_s128_split[SIDE_INTEGER128_SPLIT_HIGH];
484 if (reverse_bo) {
485 side_s64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_LOW]);
486 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_HIGH]);
487 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
488 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
489 } else {
490 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
491 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
492 }
493 } else {
494 uint64_t side_u64[NR_SIDE_INTEGER128_SPLIT];
495
496 side_u64[SIDE_INTEGER128_SPLIT_LOW] = value->side_u128_split[SIDE_INTEGER128_SPLIT_LOW];
497 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_u128_split[SIDE_INTEGER128_SPLIT_HIGH];
498 if (reverse_bo) {
499 side_u64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_LOW]);
500 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_HIGH]);
501 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
502 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
503 } else {
504 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
505 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
506 }
f6a2a8ed 507 }
d8be25de
MD
508 break;
509 default:
d8be25de
MD
510 abort();
511 }
0cbdadb5
MD
512 if (type_integer->integer_size <= 8) {
513 v.u[SIDE_INTEGER128_SPLIT_LOW] >>= offset_bits;
514 if (len_bits < 64) {
515 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
516 if (type_integer->signedness) {
517 /* Sign-extend. */
518 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (len_bits - 1))) {
519 v.u[SIDE_INTEGER128_SPLIT_LOW] |= ~((1ULL << len_bits) - 1);
520 v.u[SIDE_INTEGER128_SPLIT_HIGH] = ~0ULL;
521 }
522 }
f6a2a8ed 523 }
0cbdadb5
MD
524 } else {
525 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
526 if (len_bits < 128 || offset_bits != 0)
527 abort();
f6a2a8ed
MD
528 }
529 if (_len_bits)
530 *_len_bits = len_bits;
0cbdadb5 531 return v;
f6a2a8ed
MD
532}
533
534static
0cbdadb5 535void print_enum_labels(const struct side_enum_mappings *mappings, union int_value v)
f6a2a8ed 536{
f6a2a8ed
MD
537 uint32_t i, print_count = 0;
538
0cbdadb5 539 side_check_value_s64(v);
d8be25de
MD
540 printf(", labels: [ ");
541 for (i = 0; i < mappings->nr_mappings; i++) {
64037418 542 const struct side_enum_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
79f677ba 543
ea32e5fc 544 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 545 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
546 mapping->range_begin, mapping->range_end);
547 abort();
548 }
0cbdadb5 549 if (v.s[SIDE_INTEGER128_SPLIT_LOW] >= mapping->range_begin && v.s[SIDE_INTEGER128_SPLIT_LOW] <= mapping->range_end) {
79f677ba 550 printf("%s", print_count++ ? ", " : "");
cf80fbf9 551 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
3bc9ba43 552 side_enum_get(mapping->label.byte_order), NULL);
79f677ba
MD
553 }
554 }
555 if (!print_count)
556 printf("<NO LABEL>");
557 printf(" ]");
558}
559
ea32e5fc 560static
67337c4a 561uint32_t elem_type_to_stride(const struct side_type *elem_type)
ea32e5fc 562{
af6aa6e1
MD
563 uint32_t stride_bit;
564
3ce69bfa 565 switch (side_enum_get(elem_type->type)) {
67337c4a 566 case SIDE_TYPE_BYTE:
af6aa6e1
MD
567 stride_bit = 8;
568 break;
8625d674 569
67337c4a
MD
570 case SIDE_TYPE_U8:
571 case SIDE_TYPE_U16:
572 case SIDE_TYPE_U32:
573 case SIDE_TYPE_U64:
0cbdadb5 574 case SIDE_TYPE_U128:
67337c4a
MD
575 case SIDE_TYPE_S8:
576 case SIDE_TYPE_S16:
577 case SIDE_TYPE_S32:
578 case SIDE_TYPE_S64:
0cbdadb5 579 case SIDE_TYPE_S128:
67337c4a 580 return elem_type->u.side_integer.integer_size * CHAR_BIT;
af6aa6e1 581 default:
8625d674 582 fprintf(stderr, "ERROR: Unexpected enum bitmap element type\n");
af6aa6e1
MD
583 abort();
584 }
585 return stride_bit;
586}
587
1d9c515c 588static
0cbdadb5 589void print_integer_binary(uint64_t v[NR_SIDE_INTEGER128_SPLIT], int bits)
1d9c515c 590{
0cbdadb5 591 int bit;
1d9c515c
MD
592
593 printf("0b");
0cbdadb5
MD
594 if (bits > 64) {
595 bits -= 64;
596 v[SIDE_INTEGER128_SPLIT_HIGH] <<= 64 - bits;
597 for (bit = 0; bit < bits; bit++) {
598 printf("%c", v[SIDE_INTEGER128_SPLIT_HIGH] & (1ULL << 63) ? '1' : '0');
599 v[SIDE_INTEGER128_SPLIT_HIGH] <<= 1;
600 }
601 bits = 64;
602 }
603 v[SIDE_INTEGER128_SPLIT_LOW] <<= 64 - bits;
604 for (bit = 0; bit < bits; bit++) {
605 printf("%c", v[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << 63) ? '1' : '0');
606 v[SIDE_INTEGER128_SPLIT_LOW] <<= 1;
1d9c515c
MD
607 }
608}
609
0e9be766 610static
aac52685 611void tracer_print_type_header(const char *separator,
67337c4a 612 const struct side_attr *attr, uint32_t nr_attr)
ac81c466 613{
aac52685
MD
614 print_attributes("attr", separator, attr, nr_attr);
615 printf("%s", nr_attr ? ", " : "");
616 printf("value%s ", separator);
ac81c466
MD
617}
618
8ad2f385
MD
619static
620void tracer_print_type_bool(const char *separator,
67337c4a
MD
621 const struct side_type_bool *type_bool,
622 const union side_bool_value *value,
8ad2f385
MD
623 uint16_t offset_bits)
624{
88bab79c 625 uint32_t len_bits;
8ad2f385
MD
626 bool reverse_bo;
627 uint64_t v;
628
88bab79c
MD
629 if (!type_bool->len_bits)
630 len_bits = type_bool->bool_size * CHAR_BIT;
631 else
632 len_bits = type_bool->len_bits;
633 if (len_bits + offset_bits > type_bool->bool_size * CHAR_BIT)
8ad2f385 634 abort();
3bc9ba43 635 reverse_bo = side_enum_get(type_bool->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
88bab79c
MD
636 switch (type_bool->bool_size) {
637 case 1:
67337c4a 638 v = value->side_bool8;
8ad2f385 639 break;
88bab79c 640 case 2:
8ad2f385 641 {
67337c4a 642 uint16_t side_u16;
8ad2f385 643
67337c4a 644 side_u16 = value->side_bool16;
8ad2f385 645 if (reverse_bo)
67337c4a
MD
646 side_u16 = side_bswap_16(side_u16);
647 v = side_u16;
8ad2f385
MD
648 break;
649 }
88bab79c 650 case 4:
8ad2f385 651 {
67337c4a 652 uint32_t side_u32;
8ad2f385 653
67337c4a 654 side_u32 = value->side_bool32;
8ad2f385 655 if (reverse_bo)
67337c4a
MD
656 side_u32 = side_bswap_32(side_u32);
657 v = side_u32;
8ad2f385
MD
658 break;
659 }
88bab79c 660 case 8:
8ad2f385 661 {
67337c4a 662 uint64_t side_u64;
8ad2f385 663
67337c4a 664 side_u64 = value->side_bool64;
8ad2f385 665 if (reverse_bo)
67337c4a
MD
666 side_u64 = side_bswap_64(side_u64);
667 v = side_u64;
8ad2f385
MD
668 break;
669 }
670 default:
671 abort();
672 }
673 v >>= offset_bits;
88bab79c
MD
674 if (len_bits < 64)
675 v &= (1ULL << len_bits) - 1;
db8df9b5 676 tracer_print_type_header(separator, side_ptr_get(type_bool->attr), type_bool->nr_attr);
8ad2f385
MD
677 printf("%s", v ? "true" : "false");
678}
679
0cbdadb5
MD
680/* 2^128 - 1 */
681#define U128_BASE_10_ARRAY_LEN sizeof("340282366920938463463374607431768211455")
682/* -2^127 */
683#define S128_BASE_10_ARRAY_LEN sizeof("-170141183460469231731687303715884105728")
684
685/*
686 * u128_tostring_base_10 is inspired from https://stackoverflow.com/a/4364365
687 */
688static
689void u128_tostring_base_10(union int_value v, char str[U128_BASE_10_ARRAY_LEN])
690{
691 int d[39] = {}, i, j, str_i = 0;
692
693 for (i = 63; i > -1; i--) {
694 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
695 d[0]++;
696 for (j = 0; j < 39; j++)
697 d[j] *= 2;
698 for (j = 0; j < 38; j++) {
699 d[j + 1] += d[j] / 10;
700 d[j] %= 10;
701 }
702 }
703 for (i = 63; i > -1; i--) {
704 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
705 d[0]++;
706 if (i > 0) {
707 for (j = 0; j < 39; j++)
708 d[j] *= 2;
709 }
710 for (j = 0; j < 38; j++) {
711 d[j + 1] += d[j] / 10;
712 d[j] %= 10;
713 }
714 }
715 for (i = 38; i > 0; i--)
716 if (d[i] > 0)
717 break;
718 for (; i > -1; i--) {
719 str[str_i++] = '0' + d[i];
720 }
721 str[str_i] = '\0';
722}
723
724static
725void s128_tostring_base_10(union int_value v, char str[S128_BASE_10_ARRAY_LEN])
726{
727 uint64_t low, high, tmp;
728
729 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] >= 0) {
730 /* Positive. */
731 v.u[SIDE_INTEGER128_SPLIT_LOW] = (uint64_t) v.s[SIDE_INTEGER128_SPLIT_LOW];
732 v.u[SIDE_INTEGER128_SPLIT_HIGH] = (uint64_t) v.s[SIDE_INTEGER128_SPLIT_HIGH];
733 u128_tostring_base_10(v, str);
734 return;
735 }
736
737 /* Negative. */
738
739 /* Special-case minimum value, which has no positive signed representation. */
740 if ((v.s[SIDE_INTEGER128_SPLIT_HIGH] == INT64_MIN) && (v.s[SIDE_INTEGER128_SPLIT_LOW] == 0)) {
741 memcpy(str, "-170141183460469231731687303715884105728", S128_BASE_10_ARRAY_LEN);
742 return;
743 }
744 /* Convert from two's complement. */
745 high = ~(uint64_t) v.s[SIDE_INTEGER128_SPLIT_HIGH];
746 low = ~(uint64_t) v.s[SIDE_INTEGER128_SPLIT_LOW];
747 tmp = low + 1;
748 if (tmp < low) {
749 high++;
750 /* Clear overflow to sign bit. */
751 high &= ~0x8000000000000000ULL;
752 }
753 v.u[SIDE_INTEGER128_SPLIT_LOW] = tmp;
754 v.u[SIDE_INTEGER128_SPLIT_HIGH] = high;
755 str[0] = '-';
756 u128_tostring_base_10(v, str + 1);
757}
758
759/* 2^128 - 1 */
760#define U128_BASE_8_ARRAY_LEN sizeof("3777777777777777777777777777777777777777777")
761
762static
763void u128_tostring_base_8(union int_value v, char str[U128_BASE_8_ARRAY_LEN])
764{
765 int d[43] = {}, i, j, str_i = 0;
766
767 for (i = 63; i > -1; i--) {
768 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
769 d[0]++;
770 for (j = 0; j < 43; j++)
771 d[j] *= 2;
772 for (j = 0; j < 42; j++) {
773 d[j + 1] += d[j] / 8;
774 d[j] %= 8;
775 }
776 }
777 for (i = 63; i > -1; i--) {
778 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
779 d[0]++;
780 if (i > 0) {
781 for (j = 0; j < 43; j++)
782 d[j] *= 2;
783 }
784 for (j = 0; j < 42; j++) {
785 d[j + 1] += d[j] / 8;
786 d[j] %= 8;
787 }
788 }
789 for (i = 42; i > 0; i--)
790 if (d[i] > 0)
791 break;
792 for (; i > -1; i--) {
793 str[str_i++] = '0' + d[i];
794 }
795 str[str_i] = '\0';
796}
797
4f5e1b67
MD
798static
799void tracer_print_type_integer(const char *separator,
67337c4a
MD
800 const struct side_type_integer *type_integer,
801 const union side_integer_value *value,
4f5e1b67
MD
802 uint16_t offset_bits,
803 enum tracer_display_base default_base)
804{
805 enum tracer_display_base base;
0cbdadb5 806 union int_value v;
4f5e1b67
MD
807 uint16_t len_bits;
808
0cbdadb5 809 v = tracer_load_integer_value(type_integer, value, offset_bits, &len_bits);
12d787db
MD
810 tracer_print_type_header(separator, side_ptr_get(type_integer->attr), type_integer->nr_attr);
811 base = get_attr_display_base(side_ptr_get(type_integer->attr), type_integer->nr_attr, default_base);
56c21987
MD
812 switch (base) {
813 case TRACER_DISPLAY_BASE_2:
0cbdadb5 814 print_integer_binary(v.u, len_bits);
56c21987
MD
815 break;
816 case TRACER_DISPLAY_BASE_8:
f6a2a8ed 817 /* Clear sign bits beyond len_bits */
0cbdadb5
MD
818 if (len_bits < 64) {
819 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
820 v.u[SIDE_INTEGER128_SPLIT_HIGH] = 0;
821 } else if (len_bits < 128) {
822 v.u[SIDE_INTEGER128_SPLIT_HIGH] &= (1ULL << (len_bits - 64)) - 1;
823 }
824 if (len_bits <= 64) {
825 printf("0o%" PRIo64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
826 } else {
827 char str[U128_BASE_8_ARRAY_LEN];
828
829 u128_tostring_base_8(v, str);
830 printf("0o%s", str);
831 }
56c21987
MD
832 break;
833 case TRACER_DISPLAY_BASE_10:
0cbdadb5
MD
834 if (len_bits <= 64) {
835 if (type_integer->signedness)
836 printf("%" PRId64, v.s[SIDE_INTEGER128_SPLIT_LOW]);
837 else
838 printf("%" PRIu64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
839 } else {
840 if (type_integer->signedness) {
841 char str[S128_BASE_10_ARRAY_LEN];
842 s128_tostring_base_10(v, str);
843 printf("%s", str);
844 } else {
845 char str[U128_BASE_10_ARRAY_LEN];
846 u128_tostring_base_10(v, str);
847 printf("%s", str);
848 }
849 }
56c21987
MD
850 break;
851 case TRACER_DISPLAY_BASE_16:
f6a2a8ed 852 /* Clear sign bits beyond len_bits */
0cbdadb5
MD
853 if (len_bits < 64) {
854 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
855 v.u[SIDE_INTEGER128_SPLIT_HIGH] = 0;
856 } else if (len_bits < 128) {
857 v.u[SIDE_INTEGER128_SPLIT_HIGH] &= (1ULL << (len_bits - 64)) - 1;
858 }
859 if (len_bits <= 64 || v.u[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
860 printf("0x%" PRIx64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
861 } else {
862 printf("0x%" PRIx64 "%016" PRIx64,
863 v.u[SIDE_INTEGER128_SPLIT_HIGH],
864 v.u[SIDE_INTEGER128_SPLIT_LOW]);
865 }
56c21987
MD
866 break;
867 default:
868 abort();
869 }
870}
871
3aa7ca5e
MD
872static
873void tracer_print_type_float(const char *separator,
67337c4a
MD
874 const struct side_type_float *type_float,
875 const union side_float_value *value)
3aa7ca5e
MD
876{
877 bool reverse_bo;
878
12d787db 879 tracer_print_type_header(separator, side_ptr_get(type_float->attr), type_float->nr_attr);
3bc9ba43 880 reverse_bo = side_enum_get(type_float->byte_order) != SIDE_TYPE_FLOAT_WORD_ORDER_HOST;
88bab79c
MD
881 switch (type_float->float_size) {
882 case 2:
3aa7ca5e
MD
883 {
884#if __HAVE_FLOAT16
885 union {
886 _Float16 f;
887 uint16_t u;
888 } float16 = {
67337c4a 889 .f = value->side_float_binary16,
3aa7ca5e
MD
890 };
891
892 if (reverse_bo)
67337c4a 893 float16.u = side_bswap_16(float16.u);
3aa7ca5e
MD
894 printf("%g", (double) float16.f);
895 break;
896#else
897 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
898 abort();
899#endif
900 }
88bab79c 901 case 4:
3aa7ca5e
MD
902 {
903#if __HAVE_FLOAT32
904 union {
905 _Float32 f;
906 uint32_t u;
907 } float32 = {
67337c4a 908 .f = value->side_float_binary32,
3aa7ca5e
MD
909 };
910
911 if (reverse_bo)
67337c4a 912 float32.u = side_bswap_32(float32.u);
3aa7ca5e
MD
913 printf("%g", (double) float32.f);
914 break;
915#else
916 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
917 abort();
918#endif
919 }
88bab79c 920 case 8:
3aa7ca5e
MD
921 {
922#if __HAVE_FLOAT64
923 union {
924 _Float64 f;
925 uint64_t u;
926 } float64 = {
67337c4a 927 .f = value->side_float_binary64,
3aa7ca5e
MD
928 };
929
930 if (reverse_bo)
67337c4a 931 float64.u = side_bswap_64(float64.u);
3aa7ca5e
MD
932 printf("%g", (double) float64.f);
933 break;
934#else
935 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
936 abort();
937#endif
938 }
88bab79c 939 case 16:
3aa7ca5e
MD
940 {
941#if __HAVE_FLOAT128
942 union {
943 _Float128 f;
944 char arr[16];
945 } float128 = {
67337c4a 946 .f = value->side_float_binary128,
3aa7ca5e
MD
947 };
948
949 if (reverse_bo)
67337c4a 950 side_bswap_128p(float128.arr);
3aa7ca5e
MD
951 printf("%Lg", (long double) float128.f);
952 break;
953#else
954 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
955 abort();
956#endif
957 }
958 default:
959 fprintf(stderr, "ERROR: Unknown float size\n");
960 abort();
961 }
962}
963
f611d0c3 964static
cf80fbf9 965void push_nesting(struct print_ctx *ctx)
f611d0c3 966{
cf80fbf9
MD
967 if (++ctx->nesting >= MAX_NESTING) {
968 fprintf(stderr, "ERROR: Nesting too deep.\n");
969 abort();
970 }
971 ctx->item_nr[ctx->nesting] = 0;
972}
d8be25de 973
cf80fbf9
MD
974static
975void pop_nesting(struct print_ctx *ctx)
976{
977 ctx->item_nr[ctx->nesting] = 0;
978 if (ctx->nesting-- <= 0) {
979 fprintf(stderr, "ERROR: Nesting underflow.\n");
980 abort();
981 }
982}
45392033 983
cf80fbf9
MD
984static
985int get_nested_item_nr(struct print_ctx *ctx)
986{
987 return ctx->item_nr[ctx->nesting];
988}
d8be25de 989
cf80fbf9
MD
990static
991void inc_nested_item_nr(struct print_ctx *ctx)
992{
993 ctx->item_nr[ctx->nesting]++;
994}
0519cb86 995
cf80fbf9
MD
996static
997void tracer_print_event(enum side_type_visitor_location loc,
998 const struct side_event_description *desc,
999 const struct side_arg_vec *side_arg_vec,
1000 const struct side_arg_dynamic_struct *var_struct __attribute__((unused)),
1001 void *caller_addr, void *priv __attribute__((unused)))
1002{
1003 uint32_t side_sav_len = side_arg_vec->len;
66de373e 1004
cf80fbf9
MD
1005 if (desc->nr_fields != side_sav_len) {
1006 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1007 abort();
f611d0c3 1008 }
d8be25de 1009
cf80fbf9
MD
1010 switch (loc) {
1011 case SIDE_TYPE_VISITOR_BEFORE:
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);
4f40d951 1018 break;
cf80fbf9
MD
1019 case SIDE_TYPE_VISITOR_AFTER:
1020 printf("\n");
f611d0c3 1021 break;
cf80fbf9
MD
1022 }
1023}
56c21987 1024
cf80fbf9
MD
1025static
1026void tracer_print_static_fields(enum side_type_visitor_location loc,
1027 const struct side_arg_vec *side_arg_vec,
1028 void *priv)
1029{
1030 struct print_ctx *ctx = (struct print_ctx *) priv;
1031 uint32_t side_sav_len = side_arg_vec->len;
79f677ba 1032
cf80fbf9
MD
1033 switch (loc) {
1034 case SIDE_TYPE_VISITOR_BEFORE:
1035 printf("%s", side_sav_len ? ", fields: {" : "");
1036 push_nesting(ctx);
ea32e5fc 1037 break;
cf80fbf9
MD
1038 case SIDE_TYPE_VISITOR_AFTER:
1039 pop_nesting(ctx);
1040 if (side_sav_len)
1041 printf(" }");
fb25b355 1042 break;
cf80fbf9
MD
1043 }
1044}
3aa7ca5e 1045
cf80fbf9
MD
1046static
1047void tracer_print_variadic_fields(enum side_type_visitor_location loc,
1048 const struct side_arg_dynamic_struct *var_struct,
1049 void *priv)
1050{
1051 struct print_ctx *ctx = (struct print_ctx *) priv;
1052 uint32_t var_struct_len = var_struct->len;
55fb50b7 1053
cf80fbf9
MD
1054 switch (loc) {
1055 case SIDE_TYPE_VISITOR_BEFORE:
1056 print_attributes(", attr ", "::", side_ptr_get(var_struct->attr), var_struct->nr_attr);
1057 printf("%s", var_struct_len ? ", fields:: {" : "");
1058 push_nesting(ctx);
f611d0c3 1059 break;
cf80fbf9
MD
1060 case SIDE_TYPE_VISITOR_AFTER:
1061 pop_nesting(ctx);
1062 if (var_struct_len)
1063 printf(" }");
80429681 1064 break;
cf80fbf9
MD
1065 }
1066}
55fb50b7 1067
cf80fbf9
MD
1068static
1069void tracer_print_field(enum side_type_visitor_location loc, const struct side_event_field *item_desc, void *priv)
1070{
1071 struct print_ctx *ctx = (struct print_ctx *) priv;
55fb50b7 1072
cf80fbf9
MD
1073 switch (loc) {
1074 case SIDE_TYPE_VISITOR_BEFORE:
1075 if (get_nested_item_nr(ctx) != 0)
1076 printf(",");
1077 printf(" %s: { ", side_ptr_get(item_desc->field_name));
55fb50b7 1078 break;
cf80fbf9
MD
1079 case SIDE_TYPE_VISITOR_AFTER:
1080 printf(" }");
1081 inc_nested_item_nr(ctx);
7d34edfc 1082 break;
cf80fbf9
MD
1083 }
1084}
55fb50b7 1085
cf80fbf9
MD
1086static
1087void tracer_print_elem(enum side_type_visitor_location loc, const struct side_type *type_desc __attribute__((unused)), void *priv)
1088{
1089 struct print_ctx *ctx = (struct print_ctx *) priv;
66de373e 1090
cf80fbf9
MD
1091 switch (loc) {
1092 case SIDE_TYPE_VISITOR_BEFORE:
1093 if (get_nested_item_nr(ctx) != 0)
1094 printf(", { ");
1095 else
1096 printf(" { ");
0519cb86 1097 break;
cf80fbf9
MD
1098 case SIDE_TYPE_VISITOR_AFTER:
1099 printf(" }");
1100 inc_nested_item_nr(ctx);
a2e2357e 1101 break;
f611d0c3
MD
1102 }
1103}
1104
1105static
cf80fbf9
MD
1106void tracer_print_null(const struct side_type *type_desc,
1107 const struct side_arg *item __attribute__((unused)),
1108 void *priv __attribute__((unused)))
f611d0c3 1109{
cf80fbf9
MD
1110 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_null.attr),
1111 type_desc->u.side_null.nr_attr);
1112 printf("<NULL TYPE>");
f611d0c3
MD
1113}
1114
1115static
cf80fbf9
MD
1116void tracer_print_bool(const struct side_type *type_desc,
1117 const struct side_arg *item,
1118 void *priv __attribute__((unused)))
f611d0c3 1119{
cf80fbf9
MD
1120 tracer_print_type_bool(":", &type_desc->u.side_bool, &item->u.side_static.bool_value, 0);
1121}
f611d0c3 1122
cf80fbf9
MD
1123static
1124void tracer_print_integer(const struct side_type *type_desc,
1125 const struct side_arg *item,
1126 void *priv __attribute__((unused)))
1127{
1128 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0, TRACER_DISPLAY_BASE_10);
f611d0c3
MD
1129}
1130
5530345d 1131static
cf80fbf9
MD
1132void tracer_print_byte(const struct side_type *type_desc __attribute__((unused)),
1133 const struct side_arg *item,
1134 void *priv __attribute__((unused)))
5530345d 1135{
cf80fbf9
MD
1136 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_byte.attr), type_desc->u.side_byte.nr_attr);
1137 printf("0x%" PRIx8, item->u.side_static.byte_value);
1138}
5530345d 1139
7a1cb105 1140static
cf80fbf9
MD
1141void tracer_print_pointer(const struct side_type *type_desc,
1142 const struct side_arg *item,
1143 void *priv __attribute__((unused)))
d9359cfa 1144{
cf80fbf9 1145 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0, TRACER_DISPLAY_BASE_16);
d9359cfa
MD
1146}
1147
1148static
cf80fbf9
MD
1149void tracer_print_float(const struct side_type *type_desc,
1150 const struct side_arg *item,
1151 void *priv __attribute__((unused)))
d9359cfa 1152{
cf80fbf9 1153 tracer_print_type_float(":", &type_desc->u.side_float, &item->u.side_static.float_value);
d9359cfa
MD
1154}
1155
dd7947bf 1156static
cf80fbf9
MD
1157void tracer_print_string(const struct side_type *type_desc,
1158 const struct side_arg *item,
1159 void *priv __attribute__((unused)))
dd7947bf 1160{
cf80fbf9
MD
1161 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_string.attr), type_desc->u.side_string.nr_attr);
1162 tracer_print_type_string(side_ptr_get(item->u.side_static.string_value),
1163 type_desc->u.side_string.unit_size,
1164 side_enum_get(type_desc->u.side_string.byte_order), NULL);
dd7947bf
MD
1165}
1166
1167static
cf80fbf9
MD
1168void tracer_print_struct(enum side_type_visitor_location loc,
1169 const struct side_type_struct *side_struct,
1170 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
dd7947bf 1171{
cf80fbf9
MD
1172 struct print_ctx *ctx = (struct print_ctx *) priv;
1173
1174 switch (loc) {
1175 case SIDE_TYPE_VISITOR_BEFORE:
1176 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1177 printf("%s", side_struct->nr_attr ? ", " : "");
1178 printf("fields: {");
1179 push_nesting(ctx);
1180 break;
1181 case SIDE_TYPE_VISITOR_AFTER:
1182 pop_nesting(ctx);
1183 printf(" }");
1184 break;
dd7947bf
MD
1185 }
1186}
1187
d9359cfa 1188static
cf80fbf9
MD
1189void tracer_print_array(enum side_type_visitor_location loc,
1190 const struct side_type_array *side_array,
1191 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
7a1cb105 1192{
cf80fbf9 1193 struct print_ctx *ctx = (struct print_ctx *) priv;
65b8734a 1194
cf80fbf9
MD
1195 switch (loc) {
1196 case SIDE_TYPE_VISITOR_BEFORE:
1197 print_attributes("attr", ":", side_ptr_get(side_array->attr), side_array->nr_attr);
1198 printf("%s", side_array->nr_attr ? ", " : "");
1199 printf("elements: [");
1200 push_nesting(ctx);
1201 break;
1202 case SIDE_TYPE_VISITOR_AFTER:
1203 pop_nesting(ctx);
1204 printf(" ]");
1205 break;
1206 }
65b8734a
MD
1207}
1208
8ad2f385 1209static
cf80fbf9
MD
1210void tracer_print_vla(enum side_type_visitor_location loc,
1211 const struct side_type_vla *side_vla,
1212 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
8ad2f385 1213{
cf80fbf9 1214 struct print_ctx *ctx = (struct print_ctx *) priv;
8ad2f385 1215
cf80fbf9
MD
1216 switch (loc) {
1217 case SIDE_TYPE_VISITOR_BEFORE:
1218 print_attributes("attr", ":", side_ptr_get(side_vla->attr), side_vla->nr_attr);
1219 printf("%s", side_vla->nr_attr ? ", " : "");
1220 printf("elements: [");
1221 push_nesting(ctx);
1222 break;
1223 case SIDE_TYPE_VISITOR_AFTER:
1224 pop_nesting(ctx);
1225 printf(" ]");
8ad2f385 1226 break;
8ad2f385 1227 }
8ad2f385
MD
1228}
1229
d69918cc 1230static
cf80fbf9
MD
1231void tracer_print_vla_visitor(enum side_type_visitor_location loc,
1232 const struct side_type_vla_visitor *side_vla_visitor,
1233 const struct side_arg_vla_visitor *side_arg_vla_visitor __attribute__((unused)), void *priv)
d69918cc 1234{
cf80fbf9 1235 struct print_ctx *ctx = (struct print_ctx *) priv;
d69918cc 1236
cf80fbf9
MD
1237 switch (loc) {
1238 case SIDE_TYPE_VISITOR_BEFORE:
1239 print_attributes("attr", ":", side_ptr_get(side_vla_visitor->attr), side_vla_visitor->nr_attr);
1240 printf("%s", side_vla_visitor->nr_attr ? ", " : "");
1241 printf("elements: [");
1242 push_nesting(ctx);
1243 break;
1244 case SIDE_TYPE_VISITOR_AFTER:
1245 pop_nesting(ctx);
1246 printf(" ]");
1247 break;
1248 }
d69918cc
MD
1249}
1250
cf80fbf9
MD
1251static void tracer_print_enum(const struct side_type *type_desc,
1252 const struct side_arg *item, void *priv)
65b8734a 1253{
cf80fbf9
MD
1254 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
1255 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum.elem_type);
1256 union int_value v;
7a1cb105 1257
cf80fbf9
MD
1258 if (side_enum_get(elem_type->type) != side_enum_get(item->type)) {
1259 fprintf(stderr, "ERROR: Unexpected enum element type\n");
33956c71
MD
1260 abort();
1261 }
cf80fbf9
MD
1262 v = tracer_load_integer_value(&elem_type->u.side_integer,
1263 &item->u.side_static.integer_value, 0, NULL);
1264 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
1265 printf("%s", mappings->nr_attr ? ", " : "");
1266 printf("{ ");
1267 tracer_print_integer(elem_type, item, priv);
1268 printf(" }");
1269 print_enum_labels(mappings, v);
33956c71 1270}
9b641221 1271
cf80fbf9
MD
1272static void tracer_print_enum_bitmap(const struct side_type *type_desc,
1273 const struct side_arg *item, void *priv __attribute__((unused)))
905f68e3 1274{
cf80fbf9
MD
1275 const struct side_enum_bitmap_mappings *side_enum_mappings = side_ptr_get(type_desc->u.side_enum_bitmap.mappings);
1276 const struct side_type *enum_elem_type = side_ptr_get(type_desc->u.side_enum_bitmap.elem_type), *elem_type;
1277 uint32_t i, print_count = 0, stride_bit, nr_items;
1278 const struct side_arg *array_item;
905f68e3 1279
cf80fbf9
MD
1280 switch (side_enum_get(enum_elem_type->type)) {
1281 case SIDE_TYPE_U8: /* Fall-through */
1282 case SIDE_TYPE_BYTE: /* Fall-through */
1283 case SIDE_TYPE_U16: /* Fall-through */
1284 case SIDE_TYPE_U32: /* Fall-through */
1285 case SIDE_TYPE_U64: /* Fall-through */
1286 case SIDE_TYPE_U128: /* Fall-through */
1287 case SIDE_TYPE_S8: /* Fall-through */
1288 case SIDE_TYPE_S16: /* Fall-through */
1289 case SIDE_TYPE_S32: /* Fall-through */
1290 case SIDE_TYPE_S64: /* Fall-through */
1291 case SIDE_TYPE_S128:
1292 elem_type = enum_elem_type;
1293 array_item = item;
1294 nr_items = 1;
1295 break;
1296 case SIDE_TYPE_ARRAY:
1297 elem_type = side_ptr_get(enum_elem_type->u.side_array.elem_type);
1298 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_array)->sav);
1299 nr_items = type_desc->u.side_array.length;
1300 break;
1301 case SIDE_TYPE_VLA:
1302 elem_type = side_ptr_get(enum_elem_type->u.side_vla.elem_type);
1303 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_vla)->sav);
1304 nr_items = side_ptr_get(item->u.side_static.side_vla)->len;
905f68e3
MD
1305 break;
1306 default:
cf80fbf9 1307 fprintf(stderr, "ERROR: Unexpected enum element type\n");
905f68e3
MD
1308 abort();
1309 }
cf80fbf9 1310 stride_bit = elem_type_to_stride(elem_type);
905f68e3 1311
cf80fbf9
MD
1312 print_attributes("attr", ":", side_ptr_get(side_enum_mappings->attr), side_enum_mappings->nr_attr);
1313 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
1314 printf("labels: [ ");
1315 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
1316 const struct side_enum_bitmap_mapping *mapping = &side_ptr_get(side_enum_mappings->mappings)[i];
1317 bool match = false;
1318 uint64_t bit;
7d34edfc 1319
cf80fbf9
MD
1320 if (mapping->range_end < mapping->range_begin) {
1321 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
1322 mapping->range_begin, mapping->range_end);
1323 abort();
1324 }
1325 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
1326 if (bit > (nr_items * stride_bit) - 1)
1327 break;
1328 if (side_enum_get(elem_type->type) == SIDE_TYPE_BYTE) {
1329 uint8_t v = array_item[bit / 8].u.side_static.byte_value;
1330 if (v & (1ULL << (bit % 8))) {
1331 match = true;
1332 goto match;
1333 }
1334 } else {
1335 union int_value v = {};
1336
1337 v = tracer_load_integer_value(&elem_type->u.side_integer,
1338 &array_item[bit / stride_bit].u.side_static.integer_value,
1339 0, NULL);
1340 side_check_value_u64(v);
1341 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (bit % stride_bit))) {
1342 match = true;
1343 goto match;
1344 }
1345 }
1346 }
1347match:
1348 if (match) {
1349 printf("%s", print_count++ ? ", " : "");
1350 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
1351 side_enum_get(mapping->label.byte_order), NULL);
1352 }
7d34edfc 1353 }
cf80fbf9
MD
1354 if (!print_count)
1355 printf("<NO LABEL>");
1356 printf(" ]");
7d34edfc
MD
1357}
1358
33956c71 1359static
cf80fbf9
MD
1360void tracer_print_gather_bool(const struct side_type_gather_bool *type,
1361 const union side_bool_value *value,
1362 void *priv __attribute__((unused)))
33956c71 1363{
cf80fbf9
MD
1364 tracer_print_type_bool(":", &type->type, value, type->offset_bits);
1365}
d9359cfa 1366
cf80fbf9
MD
1367static
1368void tracer_print_gather_byte(const struct side_type_gather_byte *type,
1369 const uint8_t *_ptr,
1370 void *priv __attribute__((unused)))
1371{
1372 tracer_print_type_header(":", side_ptr_get(type->type.attr),
1373 type->type.nr_attr);
1374 printf("0x%" PRIx8, *_ptr);
1375}
55fb50b7 1376
cf80fbf9
MD
1377static
1378void tracer_print_gather_integer(const struct side_type_gather_integer *type,
1379 const union side_integer_value *value,
1380 void *priv __attribute__((unused)))
1381{
1382 tracer_print_type_integer(":", &type->type, value, type->offset_bits, TRACER_DISPLAY_BASE_10);
1383}
0519cb86 1384
cf80fbf9
MD
1385static
1386void tracer_print_gather_pointer(const struct side_type_gather_integer *type,
1387 const union side_integer_value *value,
1388 void *priv __attribute__((unused)))
1389{
1390 tracer_print_type_integer(":", &type->type, value, type->offset_bits, TRACER_DISPLAY_BASE_16);
7a1cb105
MD
1391}
1392
0519cb86 1393static
cf80fbf9
MD
1394void tracer_print_gather_float(const struct side_type_gather_float *type,
1395 const union side_float_value *value,
1396 void *priv __attribute__((unused)))
0519cb86 1397{
cf80fbf9
MD
1398 tracer_print_type_float(":", &type->type, value);
1399}
0519cb86 1400
cf80fbf9
MD
1401static
1402void tracer_print_gather_string(const struct side_type_gather_string *type,
1403 const void *p, uint8_t unit_size,
1404 enum side_type_label_byte_order byte_order,
1405 size_t strlen_with_null __attribute__((unused)),
1406 void *priv __attribute__((unused)))
1407{
1408 //TODO use strlen_with_null input
1409 tracer_print_type_header(":", side_ptr_get(type->type.attr),
1410 type->type.nr_attr);
1411 tracer_print_type_string(p, unit_size, byte_order, NULL);
0519cb86
MD
1412}
1413
7a1cb105 1414static
cf80fbf9
MD
1415void tracer_print_gather_struct(enum side_type_visitor_location loc,
1416 const struct side_type_struct *side_struct,
1417 void *priv)
7a1cb105 1418{
cf80fbf9 1419 tracer_print_struct(loc, side_struct, NULL, priv);
7a1cb105
MD
1420}
1421
1422static
cf80fbf9
MD
1423void tracer_print_gather_array(enum side_type_visitor_location loc,
1424 const struct side_type_array *side_array,
1425 void *priv)
7a1cb105 1426{
cf80fbf9
MD
1427 tracer_print_array(loc, side_array, NULL, priv);
1428}
7a1cb105 1429
cf80fbf9
MD
1430static
1431void tracer_print_gather_vla(enum side_type_visitor_location loc,
1432 const struct side_type_vla *side_vla,
1433 uint32_t length __attribute__((unused)),
1434 void *priv)
1435{
1436 tracer_print_vla(loc, side_vla, NULL, priv);
7a1cb105
MD
1437}
1438
f611d0c3 1439static
cf80fbf9
MD
1440void tracer_print_gather_enum(const struct side_type_gather_enum *type,
1441 const union side_integer_value *value,
1442 void *priv __attribute__((unused)))
f611d0c3 1443{
cf80fbf9
MD
1444 const struct side_enum_mappings *mappings = side_ptr_get(type->mappings);
1445 const struct side_type *enum_elem_type = side_ptr_get(type->elem_type);
1446 const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer;
1447 union int_value v;
f611d0c3 1448
cf80fbf9
MD
1449 v = tracer_load_integer_value(&side_integer->type, value, 0, NULL);
1450 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
1451 printf("%s", mappings->nr_attr ? ", " : "");
1452 printf("{ ");
1453 tracer_print_type_integer(":", &side_integer->type, value, 0, TRACER_DISPLAY_BASE_10);
1454 printf(" }");
1455 print_enum_labels(mappings, v);
65b8734a
MD
1456}
1457
1458static
cf80fbf9 1459void tracer_print_dynamic_field(enum side_type_visitor_location loc, const struct side_arg_dynamic_field *field, void *priv)
65b8734a 1460{
cf80fbf9 1461 struct print_ctx *ctx = (struct print_ctx *) priv;
65b8734a 1462
cf80fbf9
MD
1463 switch (loc) {
1464 case SIDE_TYPE_VISITOR_BEFORE:
1465 if (get_nested_item_nr(ctx) != 0)
1466 printf(",");
1467 printf(" %s:: { ", side_ptr_get(field->field_name));
1468 break;
1469 case SIDE_TYPE_VISITOR_AFTER:
1470 printf(" }");
1471 inc_nested_item_nr(ctx);
65b8734a 1472 break;
f611d0c3 1473 }
f611d0c3
MD
1474}
1475
352a4b77 1476static
cf80fbf9
MD
1477void tracer_print_dynamic_elem(enum side_type_visitor_location loc,
1478 const struct side_arg *dynamic_item __attribute__((unused)), void *priv)
352a4b77 1479{
cf80fbf9 1480 tracer_print_elem(loc, NULL, priv);
352a4b77
MD
1481}
1482
f611d0c3 1483static
cf80fbf9
MD
1484void tracer_print_dynamic_null(const struct side_arg *item,
1485 void *priv __attribute__((unused)))
f611d0c3 1486{
cf80fbf9
MD
1487 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_null.attr),
1488 item->u.side_dynamic.side_null.nr_attr);
1489 printf("<NULL TYPE>");
f611d0c3
MD
1490}
1491
a2e2357e 1492static
cf80fbf9
MD
1493void tracer_print_dynamic_bool(const struct side_arg *item,
1494 void *priv __attribute__((unused)))
a2e2357e 1495{
cf80fbf9 1496 tracer_print_type_bool("::", &item->u.side_dynamic.side_bool.type, &item->u.side_dynamic.side_bool.value, 0);
a2e2357e
MD
1497}
1498
2b359235 1499static
cf80fbf9
MD
1500void tracer_print_dynamic_integer(const struct side_arg *item,
1501 void *priv __attribute__((unused)))
2b359235 1502{
cf80fbf9
MD
1503 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
1504 TRACER_DISPLAY_BASE_10);
2b359235
MD
1505}
1506
a2e2357e 1507static
cf80fbf9
MD
1508void tracer_print_dynamic_byte(const struct side_arg *item,
1509 void *priv __attribute__((unused)))
a2e2357e 1510{
cf80fbf9
MD
1511 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_byte.type.attr), item->u.side_dynamic.side_byte.type.nr_attr);
1512 printf("0x%" PRIx8, item->u.side_dynamic.side_byte.value);
a2e2357e
MD
1513}
1514
1515static
cf80fbf9
MD
1516void tracer_print_dynamic_pointer(const struct side_arg *item,
1517 void *priv __attribute__((unused)))
a2e2357e 1518{
cf80fbf9
MD
1519 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
1520 TRACER_DISPLAY_BASE_16);
1521}
a2e2357e 1522
cf80fbf9
MD
1523static
1524void tracer_print_dynamic_float(const struct side_arg *item,
1525 void *priv __attribute__((unused)))
1526{
1527 tracer_print_type_float("::", &item->u.side_dynamic.side_float.type,
1528 &item->u.side_dynamic.side_float.value);
a2e2357e
MD
1529}
1530
cf80fbf9
MD
1531static
1532void tracer_print_dynamic_string(const struct side_arg *item,
1533 void *priv __attribute__((unused)))
1534{
1535 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_string.type.attr), item->u.side_dynamic.side_string.type.nr_attr);
1536 tracer_print_type_string((const char *)(uintptr_t) item->u.side_dynamic.side_string.value,
1537 item->u.side_dynamic.side_string.type.unit_size,
1538 side_enum_get(item->u.side_dynamic.side_string.type.byte_order), NULL);
1539}
8ceca0cd
MD
1540
1541static
cf80fbf9
MD
1542void tracer_print_dynamic_struct(enum side_type_visitor_location loc,
1543 const struct side_arg_dynamic_struct *dynamic_struct,
1544 void *priv)
8ceca0cd 1545{
cf80fbf9 1546 struct print_ctx *ctx = (struct print_ctx *) priv;
8ceca0cd 1547
cf80fbf9
MD
1548 switch (loc) {
1549 case SIDE_TYPE_VISITOR_BEFORE:
1550 print_attributes("attr", "::", side_ptr_get(dynamic_struct->attr), dynamic_struct->nr_attr);
1551 printf("%s", dynamic_struct->nr_attr ? ", " : "");
1552 printf("fields:: {");
1553 push_nesting(ctx);
1554 break;
1555 case SIDE_TYPE_VISITOR_AFTER:
1556 pop_nesting(ctx);
1557 printf(" }");
1558 break;
1559 }
8ceca0cd
MD
1560}
1561
a2e2357e 1562static
cf80fbf9
MD
1563void tracer_print_dynamic_struct_visitor(enum side_type_visitor_location loc,
1564 const struct side_arg *item,
1565 void *priv)
a2e2357e 1566{
cf80fbf9
MD
1567 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
1568 struct print_ctx *ctx = (struct print_ctx *) priv;
8ceca0cd 1569
cf80fbf9
MD
1570 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
1571 if (!dynamic_struct_visitor)
8ceca0cd 1572 abort();
cf80fbf9
MD
1573
1574 switch (loc) {
1575 case SIDE_TYPE_VISITOR_BEFORE:
1576 print_attributes("attr", "::", side_ptr_get(dynamic_struct_visitor->attr), dynamic_struct_visitor->nr_attr);
1577 printf("%s", dynamic_struct_visitor->nr_attr ? ", " : "");
1578 printf("fields:: {");
1579 push_nesting(ctx);
1580 break;
1581 case SIDE_TYPE_VISITOR_AFTER:
1582 pop_nesting(ctx);
1583 printf(" }");
1584 break;
8ceca0cd 1585 }
a2e2357e
MD
1586}
1587
1588static
cf80fbf9
MD
1589void tracer_print_dynamic_vla(enum side_type_visitor_location loc,
1590 const struct side_arg_dynamic_vla *dynamic_vla,
1591 void *priv)
a2e2357e 1592{
cf80fbf9 1593 struct print_ctx *ctx = (struct print_ctx *) priv;
55fb50b7 1594
cf80fbf9
MD
1595 switch (loc) {
1596 case SIDE_TYPE_VISITOR_BEFORE:
1597 print_attributes("attr", "::", side_ptr_get(dynamic_vla->attr), dynamic_vla->nr_attr);
1598 printf("%s", dynamic_vla->nr_attr ? ", " : "");
1599 printf("elements:: [");
1600 push_nesting(ctx);
a2e2357e 1601 break;
cf80fbf9
MD
1602 case SIDE_TYPE_VISITOR_AFTER:
1603 pop_nesting(ctx);
1604 printf(" ]");
a2e2357e 1605 break;
a2e2357e
MD
1606 }
1607}
1608
68f8cfbe 1609static
cf80fbf9
MD
1610void tracer_print_dynamic_vla_visitor(enum side_type_visitor_location loc,
1611 const struct side_arg *item,
1612 void *priv)
f611d0c3 1613{
cf80fbf9
MD
1614 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
1615 struct print_ctx *ctx = (struct print_ctx *) priv;
f611d0c3 1616
cf80fbf9
MD
1617 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
1618 if (!dynamic_vla_visitor)
f611d0c3 1619 abort();
cf80fbf9
MD
1620
1621 switch (loc) {
1622 case SIDE_TYPE_VISITOR_BEFORE:
1623 print_attributes("attr", "::", side_ptr_get(dynamic_vla_visitor->attr), dynamic_vla_visitor->nr_attr);
1624 printf("%s", dynamic_vla_visitor->nr_attr ? ", " : "");
1625 printf("elements:: [");
1626 push_nesting(ctx);
1627 break;
1628 case SIDE_TYPE_VISITOR_AFTER:
1629 pop_nesting(ctx);
1630 printf(" ]");
1631 break;
f611d0c3 1632 }
68f8cfbe
MD
1633}
1634
cf80fbf9
MD
1635static struct side_type_visitor type_visitor = {
1636 .event_func = tracer_print_event,
1637 .static_fields_func = tracer_print_static_fields,
1638 .variadic_fields_func = tracer_print_variadic_fields,
1639
1640 /* Stack-copy basic types. */
1641 .field_func = tracer_print_field,
1642 .elem_func = tracer_print_elem,
1643 .null_type_func = tracer_print_null,
1644 .bool_type_func = tracer_print_bool,
1645 .integer_type_func = tracer_print_integer,
1646 .byte_type_func = tracer_print_byte,
1647 .pointer_type_func = tracer_print_pointer,
1648 .float_type_func = tracer_print_float,
1649 .string_type_func = tracer_print_string,
1650
1651 /* Stack-copy compound types. */
1652 .struct_type_func = tracer_print_struct,
1653 .array_type_func = tracer_print_array,
1654 .vla_type_func = tracer_print_vla,
1655 .vla_visitor_type_func = tracer_print_vla_visitor,
1656
1657 /* Stack-copy enumeration types. */
1658 .enum_type_func = tracer_print_enum,
1659 .enum_bitmap_type_func = tracer_print_enum_bitmap,
1660
1661 /* Gather basic types. */
1662 .gather_bool_type_func = tracer_print_gather_bool,
1663 .gather_byte_type_func = tracer_print_gather_byte,
1664 .gather_integer_type_func = tracer_print_gather_integer,
1665 .gather_pointer_type_func = tracer_print_gather_pointer,
1666 .gather_float_type_func = tracer_print_gather_float,
1667 .gather_string_type_func = tracer_print_gather_string,
1668
1669 /* Gather compound types. */
1670 .gather_struct_type_func = tracer_print_gather_struct,
1671 .gather_array_type_func = tracer_print_gather_array,
1672 .gather_vla_type_func = tracer_print_gather_vla,
1673
1674 /* Gather enumeration types. */
1675 .gather_enum_type_func = tracer_print_gather_enum,
1676
1677 /* Dynamic basic types. */
1678 .dynamic_field_func = tracer_print_dynamic_field,
1679 .dynamic_elem_func = tracer_print_dynamic_elem,
1680
1681 .dynamic_null_func = tracer_print_dynamic_null,
1682 .dynamic_bool_func = tracer_print_dynamic_bool,
1683 .dynamic_integer_func = tracer_print_dynamic_integer,
1684 .dynamic_byte_func = tracer_print_dynamic_byte,
1685 .dynamic_pointer_func = tracer_print_dynamic_pointer,
1686 .dynamic_float_func = tracer_print_dynamic_float,
1687 .dynamic_string_func = tracer_print_dynamic_string,
1688
1689 /* Dynamic compound types. */
1690 .dynamic_struct_func = tracer_print_dynamic_struct,
1691 .dynamic_struct_visitor_func = tracer_print_dynamic_struct_visitor,
1692 .dynamic_vla_func = tracer_print_dynamic_vla,
1693 .dynamic_vla_visitor_func = tracer_print_dynamic_vla_visitor,
1694};
1695
9365e936 1696static
67337c4a
MD
1697void tracer_call(const struct side_event_description *desc,
1698 const struct side_arg_vec *side_arg_vec,
5e523511
MD
1699 void *priv __attribute__((unused)),
1700 void *caller_addr)
68f8cfbe 1701{
cf80fbf9 1702 struct print_ctx ctx = {};
a848763d 1703
cf80fbf9 1704 type_visitor_event(&type_visitor, desc, side_arg_vec, NULL, caller_addr, &ctx);
f611d0c3 1705}
19fa6aa2 1706
9365e936 1707static
67337c4a
MD
1708void tracer_call_variadic(const struct side_event_description *desc,
1709 const struct side_arg_vec *side_arg_vec,
1710 const struct side_arg_dynamic_struct *var_struct,
5e523511
MD
1711 void *priv __attribute__((unused)),
1712 void *caller_addr)
19fa6aa2 1713{
cf80fbf9 1714 struct print_ctx ctx = {};
68f8cfbe 1715
cf80fbf9 1716 type_visitor_event(&type_visitor, desc, side_arg_vec, var_struct, caller_addr, &ctx);
19fa6aa2 1717}
1e8aec23 1718
9365e936 1719static
67337c4a
MD
1720void tracer_event_notification(enum side_tracer_notification notif,
1721 struct side_event_description **events, uint32_t nr_events,
9365e936 1722 void *priv __attribute__((unused)))
1e8aec23
MD
1723{
1724 uint32_t i;
314c22c3 1725 int ret;
1e8aec23
MD
1726
1727 printf("----------------------------------------------------------\n");
1728 printf("Tracer notified of events %s\n",
67337c4a 1729 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1e8aec23 1730 for (i = 0; i < nr_events; i++) {
67337c4a 1731 struct side_event_description *event = events[i];
1e8aec23
MD
1732
1733 /* Skip NULL pointers */
1734 if (!event)
1735 continue;
b2a84b9f
MD
1736 if (event->version != SIDE_EVENT_DESCRIPTION_ABI_VERSION) {
1737 printf("Error: event description ABI version (%u) does not match the version supported by the tracer (%u)\n",
1738 event->version, SIDE_EVENT_DESCRIPTION_ABI_VERSION);
441235e7
MD
1739 return;
1740 }
1e8aec23 1741 printf("provider: %s, event: %s\n",
0b9e59d6 1742 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
441235e7 1743 if (event->struct_size != side_offsetofend(struct side_event_description, side_event_description_orig_abi_last)) {
b2a84b9f 1744 printf("Warning: Event %s.%s description contains fields unknown to the tracer\n",
441235e7
MD
1745 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
1746 }
78dd4cc3 1747 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
2d8e1a70
MD
1748 if (event->nr_side_type_label > _NR_SIDE_TYPE_LABEL) {
1749 printf("Warning: event %s:%s may contain unknown field types (%u unknown types)\n",
1750 side_ptr_get(event->provider_name), side_ptr_get(event->event_name),
1751 event->nr_side_type_label - _NR_SIDE_TYPE_LABEL);
1752 }
1753 if (event->nr_side_attr_type > _NR_SIDE_ATTR_TYPE) {
1754 printf("Warning: event %s:%s may contain unknown attribute types (%u unknown types)\n",
1755 side_ptr_get(event->provider_name), side_ptr_get(event->event_name),
1756 event->nr_side_attr_type - _NR_SIDE_ATTR_TYPE);
1757 }
67337c4a 1758 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
bffe9ae3 1759 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL, tracer_key);
314c22c3
MD
1760 if (ret)
1761 abort();
1762 } else {
bffe9ae3 1763 ret = side_tracer_callback_register(event, tracer_call, NULL, tracer_key);
314c22c3
MD
1764 if (ret)
1765 abort();
1766 }
1767 } else {
67337c4a 1768 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
bffe9ae3 1769 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL, tracer_key);
314c22c3
MD
1770 if (ret)
1771 abort();
1772 } else {
bffe9ae3 1773 ret = side_tracer_callback_unregister(event, tracer_call, NULL, tracer_key);
314c22c3
MD
1774 if (ret)
1775 abort();
1776 }
1777 }
1e8aec23
MD
1778 }
1779 printf("----------------------------------------------------------\n");
1780}
1781
1782static __attribute__((constructor))
1783void tracer_init(void);
1784static
1785void tracer_init(void)
1786{
bffe9ae3
MD
1787 if (side_tracer_request_key(&tracer_key))
1788 abort();
67337c4a 1789 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1e8aec23
MD
1790 if (!tracer_handle)
1791 abort();
1792}
1793
1794static __attribute__((destructor))
1795void tracer_exit(void);
1796static
1797void tracer_exit(void)
1798{
67337c4a 1799 side_tracer_event_notification_unregister(tracer_handle);
1e8aec23 1800}
This page took 0.135421 seconds and 4 git commands to generate.