Implement 128-bit integer support
[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
1d9c515c
MD
16enum tracer_display_base {
17 TRACER_DISPLAY_BASE_2,
18 TRACER_DISPLAY_BASE_8,
19 TRACER_DISPLAY_BASE_10,
20 TRACER_DISPLAY_BASE_16,
21};
22
0cbdadb5
MD
23union int_value {
24 uint64_t u[NR_SIDE_INTEGER128_SPLIT];
25 int64_t s[NR_SIDE_INTEGER128_SPLIT];
4f5e1b67
MD
26};
27
67337c4a 28static struct side_tracer_handle *tracer_handle;
1e8aec23 29
f611d0c3 30static
67337c4a 31void tracer_print_struct(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec);
f611d0c3 32static
5530345d
MD
33void tracer_print_variant(const struct side_type *type_desc, const struct side_arg_variant *side_arg_variant);
34static
67337c4a 35void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec);
f611d0c3 36static
67337c4a 37void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec);
f611d0c3 38static
67337c4a 39void tracer_print_vla_visitor(const struct side_type *type_desc, void *app_ctx);
ba845af5 40static
67337c4a 41void tracer_print_dynamic(const struct side_arg *dynamic_item);
d8be25de 42static
67337c4a 43uint32_t tracer_print_gather_bool_type(const struct side_type_gather *type_gather, const void *_ptr);
8ad2f385 44static
67337c4a 45uint32_t tracer_print_gather_byte_type(const struct side_type_gather *type_gather, const void *_ptr);
d9359cfa 46static
67337c4a 47uint32_t tracer_print_gather_integer_type(const struct side_type_gather *type_gather, const void *_ptr,
4e1b0e0e 48 enum tracer_display_base default_base);
d9359cfa 49static
67337c4a 50uint32_t tracer_print_gather_float_type(const struct side_type_gather *type_gather, const void *_ptr);
d9359cfa 51static
67337c4a 52uint32_t tracer_print_gather_string_type(const struct side_type_gather *type_gather, const void *_ptr);
7d34edfc 53static
67337c4a 54uint32_t tracer_print_gather_enum_type(const struct side_type_gather *type_gather, const void *_ptr);
0519cb86 55static
67337c4a 56uint32_t tracer_print_gather_struct(const struct side_type_gather *type_gather, const void *_ptr);
d69918cc 57static
67337c4a 58uint32_t tracer_print_gather_array(const struct side_type_gather *type_gather, const void *_ptr);
d9359cfa 59static
67337c4a 60uint32_t tracer_print_gather_vla(const struct side_type_gather *type_gather, const void *_ptr,
80429681 61 const void *_length_ptr);
65b8734a 62static
67337c4a 63void tracer_print_type(const struct side_type *type_desc, const struct side_arg *item);
f611d0c3 64
52990f65 65static
67337c4a 66void tracer_convert_string_to_utf8(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
9ceac3e2
MD
67 size_t *strlen_with_null,
68 char **output_str)
52990f65
MD
69{
70 size_t ret, inbytesleft = 0, outbytesleft, bufsize;
71 const char *str = p, *fromcode;
72 char *inbuf = (char *) p, *outbuf, *buf;
73 iconv_t cd;
74
75 switch (unit_size) {
76 case 1:
52990f65
MD
77 if (strlen_with_null)
78 *strlen_with_null = strlen(str) + 1;
9ceac3e2 79 *output_str = (char *) str;
52990f65
MD
80 return;
81 case 2:
82 {
83 const uint16_t *p16 = p;
84
85 switch (byte_order) {
67337c4a 86 case SIDE_TYPE_BYTE_ORDER_LE:
52990f65
MD
87 {
88 fromcode = "UTF-16LE";
89 break;
90 }
67337c4a 91 case SIDE_TYPE_BYTE_ORDER_BE:
52990f65
MD
92 {
93 fromcode = "UTF-16BE";
94 break;
95 }
96 default:
97 fprintf(stderr, "Unknown byte order\n");
98 abort();
99 }
100 for (; *p16; p16++)
101 inbytesleft += 2;
102 /*
103 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
104 * { ef, bf, bf } UTF-8 (3 bytes).
105 */
106 bufsize = inbytesleft / 2 * 3 + 1;
107 break;
108 }
109 case 4:
110 {
111 const uint32_t *p32 = p;
112
113 switch (byte_order) {
67337c4a 114 case SIDE_TYPE_BYTE_ORDER_LE:
52990f65
MD
115 {
116 fromcode = "UTF-32LE";
117 break;
118 }
67337c4a 119 case SIDE_TYPE_BYTE_ORDER_BE:
52990f65
MD
120 {
121 fromcode = "UTF-32BE";
122 break;
123 }
124 default:
125 fprintf(stderr, "Unknown byte order\n");
126 abort();
127 }
128 for (; *p32; p32++)
129 inbytesleft += 4;
130 /*
131 * Each 4-byte UTF-32 character converts to at most a
132 * 4-byte UTF-8 character.
133 */
134 bufsize = inbytesleft + 1;
135 break;
136 }
137 default:
138 fprintf(stderr, "Unknown string unit size %" PRIu8 "\n", unit_size);
139 abort();
140 }
141
142 cd = iconv_open("UTF8", fromcode);
143 if (cd == (iconv_t) -1) {
144 perror("iconv_open");
145 abort();
146 }
147 buf = malloc(bufsize);
148 if (!buf) {
149 abort();
150 }
151 outbuf = (char *) buf;
152 outbytesleft = bufsize;
153 ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
154 if (ret == (size_t) -1) {
155 perror("iconv");
156 abort();
157 }
158 if (inbytesleft) {
159 fprintf(stderr, "Buffer too small to convert string input\n");
160 abort();
161 }
162 (*outbuf++) = '\0';
52990f65
MD
163 if (iconv_close(cd) == -1) {
164 perror("iconv_close");
165 abort();
166 }
9ceac3e2
MD
167 if (strlen_with_null)
168 *strlen_with_null = outbuf - buf;
169 *output_str = buf;
170}
171
172static
67337c4a 173void tracer_print_string(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
9ceac3e2
MD
174 size_t *strlen_with_null)
175{
176 char *output_str = NULL;
177
178 tracer_convert_string_to_utf8(p, unit_size, byte_order, strlen_with_null, &output_str);
179 printf("\"%s\"", output_str);
180 if (output_str != p)
181 free(output_str);
52990f65
MD
182}
183
1d9c515c 184static
0cbdadb5
MD
185void side_check_value_u64(union int_value v)
186{
187 if (v.u[SIDE_INTEGER128_SPLIT_HIGH]) {
188 fprintf(stderr, "Unexpected integer value\n");
189 abort();
190 }
191}
192
193static
194void side_check_value_s64(union int_value v)
195{
196 if (v.s[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << 63)) {
197 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] != ~0LL) {
198 fprintf(stderr, "Unexpected integer value\n");
199 abort();
200 }
201 } else {
202 if (v.s[SIDE_INTEGER128_SPLIT_HIGH]) {
203 fprintf(stderr, "Unexpected integer value\n");
204 abort();
205 }
206 }
207}
208
209static
210int64_t get_attr_integer64_value(const struct side_attr *attr)
1d9c515c
MD
211{
212 int64_t val;
213
15f17024 214 switch (side_enum_get(attr->value.type)) {
67337c4a
MD
215 case SIDE_ATTR_TYPE_U8:
216 val = attr->value.u.integer_value.side_u8;
1d9c515c 217 break;
67337c4a
MD
218 case SIDE_ATTR_TYPE_U16:
219 val = attr->value.u.integer_value.side_u16;
1d9c515c 220 break;
67337c4a
MD
221 case SIDE_ATTR_TYPE_U32:
222 val = attr->value.u.integer_value.side_u32;
1d9c515c 223 break;
67337c4a
MD
224 case SIDE_ATTR_TYPE_U64:
225 val = attr->value.u.integer_value.side_u64;
1d9c515c 226 break;
0cbdadb5
MD
227 case SIDE_ATTR_TYPE_U128:
228 {
229 union int_value v = {
230 .u = {
231 [SIDE_INTEGER128_SPLIT_LOW] = attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW],
232 [SIDE_INTEGER128_SPLIT_HIGH] = attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH],
233 },
234 };
235 side_check_value_u64(v);
236 val = v.u[SIDE_INTEGER128_SPLIT_LOW];
237 break;
238 }
67337c4a
MD
239 case SIDE_ATTR_TYPE_S8:
240 val = attr->value.u.integer_value.side_s8;
1d9c515c 241 break;
67337c4a
MD
242 case SIDE_ATTR_TYPE_S16:
243 val = attr->value.u.integer_value.side_s16;
1d9c515c 244 break;
67337c4a
MD
245 case SIDE_ATTR_TYPE_S32:
246 val = attr->value.u.integer_value.side_s32;
1d9c515c 247 break;
67337c4a
MD
248 case SIDE_ATTR_TYPE_S64:
249 val = attr->value.u.integer_value.side_s64;
1d9c515c 250 break;
0cbdadb5
MD
251 case SIDE_ATTR_TYPE_S128:
252 {
253 union int_value v = {
254 .s = {
255 [SIDE_INTEGER128_SPLIT_LOW] = attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW],
256 [SIDE_INTEGER128_SPLIT_HIGH] = attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH],
257 },
258 };
259 side_check_value_s64(v);
260 val = v.s[SIDE_INTEGER128_SPLIT_LOW];
261 break;
262 }
1d9c515c
MD
263 default:
264 fprintf(stderr, "Unexpected attribute type\n");
265 abort();
266 }
267 return val;
268}
269
270static
67337c4a 271enum tracer_display_base get_attr_display_base(const struct side_attr *_attr, uint32_t nr_attr,
f0dafd60 272 enum tracer_display_base default_base)
1d9c515c
MD
273{
274 uint32_t i;
275
276 for (i = 0; i < nr_attr; i++) {
67337c4a 277 const struct side_attr *attr = &_attr[i];
9ceac3e2
MD
278 char *utf8_str = NULL;
279 bool cmp;
1d9c515c 280
3db2d8a1 281 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
3bc9ba43 282 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
9ceac3e2 283 cmp = strcmp(utf8_str, "std.integer.base");
3db2d8a1 284 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2
MD
285 free(utf8_str);
286 if (!cmp) {
0cbdadb5 287 int64_t val = get_attr_integer64_value(attr);
1d9c515c
MD
288
289 switch (val) {
290 case 2:
291 return TRACER_DISPLAY_BASE_2;
292 case 8:
293 return TRACER_DISPLAY_BASE_8;
294 case 10:
295 return TRACER_DISPLAY_BASE_10;
296 case 16:
297 return TRACER_DISPLAY_BASE_16;
298 default:
299 fprintf(stderr, "Unexpected integer display base: %" PRId64 "\n", val);
300 abort();
301 }
302 }
303 }
f0dafd60 304 return default_base; /* Default */
1d9c515c
MD
305}
306
bc3c89b3 307static
67337c4a 308void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
bc3c89b3 309{
9ceac3e2
MD
310 char *utf8_str = NULL;
311
3db2d8a1 312 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
3bc9ba43 313 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
9ceac3e2 314 printf("{ key%s \"%s\", value%s ", separator, utf8_str, separator);
3db2d8a1 315 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2 316 free(utf8_str);
15f17024 317 switch (side_enum_get(attr->value.type)) {
67337c4a 318 case SIDE_ATTR_TYPE_BOOL:
5f82db91 319 printf("%s", attr->value.u.bool_value ? "true" : "false");
bc3c89b3 320 break;
67337c4a
MD
321 case SIDE_ATTR_TYPE_U8:
322 printf("%" PRIu8, attr->value.u.integer_value.side_u8);
bc3c89b3 323 break;
67337c4a
MD
324 case SIDE_ATTR_TYPE_U16:
325 printf("%" PRIu16, attr->value.u.integer_value.side_u16);
bc3c89b3 326 break;
67337c4a
MD
327 case SIDE_ATTR_TYPE_U32:
328 printf("%" PRIu32, attr->value.u.integer_value.side_u32);
bc3c89b3 329 break;
67337c4a
MD
330 case SIDE_ATTR_TYPE_U64:
331 printf("%" PRIu64, attr->value.u.integer_value.side_u64);
bc3c89b3 332 break;
0cbdadb5
MD
333 case SIDE_ATTR_TYPE_U128:
334 if (attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
335 printf("0x%" PRIx64, attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW]);
336 } else {
337 printf("0x%" PRIx64 "%016" PRIx64,
338 attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH],
339 attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW]);
340 }
341 break;
67337c4a
MD
342 case SIDE_ATTR_TYPE_S8:
343 printf("%" PRId8, attr->value.u.integer_value.side_s8);
bc3c89b3 344 break;
67337c4a
MD
345 case SIDE_ATTR_TYPE_S16:
346 printf("%" PRId16, attr->value.u.integer_value.side_s16);
bc3c89b3 347 break;
67337c4a
MD
348 case SIDE_ATTR_TYPE_S32:
349 printf("%" PRId32, attr->value.u.integer_value.side_s32);
bc3c89b3 350 break;
67337c4a
MD
351 case SIDE_ATTR_TYPE_S64:
352 printf("%" PRId64, attr->value.u.integer_value.side_s64);
bc3c89b3 353 break;
0cbdadb5
MD
354 case SIDE_ATTR_TYPE_S128:
355 if (attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
356 printf("0x%" PRIx64, attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW]);
357 } else {
358 printf("0x%" PRIx64 "%016" PRIx64,
359 attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH],
360 attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW]);
361 }
362 break;
67337c4a 363 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
bc3c89b3 364#if __HAVE_FLOAT16
67337c4a 365 printf("%g", (double) attr->value.u.float_value.side_float_binary16);
bc3c89b3
MD
366 break;
367#else
de1b3cd2 368 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
bc3c89b3
MD
369 abort();
370#endif
67337c4a 371 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
bc3c89b3 372#if __HAVE_FLOAT32
67337c4a 373 printf("%g", (double) attr->value.u.float_value.side_float_binary32);
bc3c89b3
MD
374 break;
375#else
de1b3cd2 376 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
bc3c89b3
MD
377 abort();
378#endif
67337c4a 379 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
bc3c89b3 380#if __HAVE_FLOAT64
67337c4a 381 printf("%g", (double) attr->value.u.float_value.side_float_binary64);
bc3c89b3
MD
382 break;
383#else
de1b3cd2 384 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
bc3c89b3
MD
385 abort();
386#endif
67337c4a 387 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
bc3c89b3 388#if __HAVE_FLOAT128
67337c4a 389 printf("%Lg", (long double) attr->value.u.float_value.side_float_binary128);
bc3c89b3
MD
390 break;
391#else
de1b3cd2 392 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
bc3c89b3
MD
393 abort();
394#endif
67337c4a 395 case SIDE_ATTR_TYPE_STRING:
3db2d8a1 396 tracer_print_string(side_ptr_get(attr->value.u.string_value.p),
ab8a626e 397 attr->value.u.string_value.unit_size,
3bc9ba43 398 side_enum_get(attr->value.u.string_value.byte_order), NULL);
bc3c89b3
MD
399 break;
400 default:
de1b3cd2 401 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
bc3c89b3
MD
402 abort();
403 }
404 printf(" }");
405}
406
7d21cf51 407static
905c328e 408void print_attributes(const char *prefix_str, const char *separator,
67337c4a 409 const struct side_attr *attr, uint32_t nr_attr)
7d21cf51 410{
e65f9ce5 411 uint32_t i;
7d21cf51
MD
412
413 if (!nr_attr)
414 return;
905c328e 415 printf("%s%s [ ", prefix_str, separator);
7d21cf51
MD
416 for (i = 0; i < nr_attr; i++) {
417 printf("%s", i ? ", " : "");
905c328e 418 tracer_print_attr_type(separator, &attr[i]);
7d21cf51
MD
419 }
420 printf(" ]");
421}
422
79f677ba 423static
0cbdadb5 424union int_value tracer_load_integer_value(const struct side_type_integer *type_integer,
67337c4a 425 const union side_integer_value *value,
f6a2a8ed 426 uint16_t offset_bits, uint16_t *_len_bits)
79f677ba 427{
0cbdadb5 428 union int_value v = {};
f6a2a8ed
MD
429 uint16_t len_bits;
430 bool reverse_bo;
79f677ba 431
f6a2a8ed
MD
432 if (!type_integer->len_bits)
433 len_bits = type_integer->integer_size * CHAR_BIT;
434 else
435 len_bits = type_integer->len_bits;
436 if (len_bits + offset_bits > type_integer->integer_size * CHAR_BIT)
d8be25de 437 abort();
3bc9ba43 438 reverse_bo = side_enum_get(type_integer->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
f6a2a8ed
MD
439 switch (type_integer->integer_size) {
440 case 1:
441 if (type_integer->signedness)
0cbdadb5 442 v.s[SIDE_INTEGER128_SPLIT_LOW] = value->side_s8;
f6a2a8ed 443 else
0cbdadb5 444 v.u[SIDE_INTEGER128_SPLIT_LOW] = value->side_u8;
d8be25de 445 break;
f6a2a8ed
MD
446 case 2:
447 if (type_integer->signedness) {
67337c4a 448 int16_t side_s16;
8bdd5c12 449
67337c4a 450 side_s16 = value->side_s16;
f6a2a8ed 451 if (reverse_bo)
67337c4a 452 side_s16 = side_bswap_16(side_s16);
0cbdadb5 453 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s16;
f6a2a8ed 454 } else {
67337c4a 455 uint16_t side_u16;
8bdd5c12 456
67337c4a 457 side_u16 = value->side_u16;
f6a2a8ed 458 if (reverse_bo)
67337c4a 459 side_u16 = side_bswap_16(side_u16);
0cbdadb5 460 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u16;
f6a2a8ed 461 }
d8be25de 462 break;
f6a2a8ed
MD
463 case 4:
464 if (type_integer->signedness) {
67337c4a 465 int32_t side_s32;
8bdd5c12 466
67337c4a 467 side_s32 = value->side_s32;
f6a2a8ed 468 if (reverse_bo)
67337c4a 469 side_s32 = side_bswap_32(side_s32);
0cbdadb5 470 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s32;
f6a2a8ed 471 } else {
67337c4a 472 uint32_t side_u32;
8bdd5c12 473
67337c4a 474 side_u32 = value->side_u32;
f6a2a8ed 475 if (reverse_bo)
67337c4a 476 side_u32 = side_bswap_32(side_u32);
0cbdadb5 477 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u32;
f6a2a8ed 478 }
d8be25de 479 break;
f6a2a8ed
MD
480 case 8:
481 if (type_integer->signedness) {
67337c4a 482 int64_t side_s64;
8bdd5c12 483
67337c4a 484 side_s64 = value->side_s64;
f6a2a8ed 485 if (reverse_bo)
67337c4a 486 side_s64 = side_bswap_64(side_s64);
0cbdadb5 487 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64;
f6a2a8ed 488 } else {
67337c4a 489 uint64_t side_u64;
8bdd5c12 490
67337c4a 491 side_u64 = value->side_u64;
f6a2a8ed 492 if (reverse_bo)
67337c4a 493 side_u64 = side_bswap_64(side_u64);
0cbdadb5
MD
494 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64;
495 }
496 break;
497 case 16:
498 if (type_integer->signedness) {
499 int64_t side_s64[NR_SIDE_INTEGER128_SPLIT];
500
501 side_s64[SIDE_INTEGER128_SPLIT_LOW] = value->side_s128_split[SIDE_INTEGER128_SPLIT_LOW];
502 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_s128_split[SIDE_INTEGER128_SPLIT_HIGH];
503 if (reverse_bo) {
504 side_s64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_LOW]);
505 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_HIGH]);
506 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
507 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
508 } else {
509 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
510 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
511 }
512 } else {
513 uint64_t side_u64[NR_SIDE_INTEGER128_SPLIT];
514
515 side_u64[SIDE_INTEGER128_SPLIT_LOW] = value->side_u128_split[SIDE_INTEGER128_SPLIT_LOW];
516 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_u128_split[SIDE_INTEGER128_SPLIT_HIGH];
517 if (reverse_bo) {
518 side_u64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_LOW]);
519 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_HIGH]);
520 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
521 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
522 } else {
523 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
524 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
525 }
f6a2a8ed 526 }
d8be25de
MD
527 break;
528 default:
d8be25de
MD
529 abort();
530 }
0cbdadb5
MD
531 if (type_integer->integer_size <= 8) {
532 v.u[SIDE_INTEGER128_SPLIT_LOW] >>= offset_bits;
533 if (len_bits < 64) {
534 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
535 if (type_integer->signedness) {
536 /* Sign-extend. */
537 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (len_bits - 1))) {
538 v.u[SIDE_INTEGER128_SPLIT_LOW] |= ~((1ULL << len_bits) - 1);
539 v.u[SIDE_INTEGER128_SPLIT_HIGH] = ~0ULL;
540 }
541 }
f6a2a8ed 542 }
0cbdadb5
MD
543 } else {
544 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
545 if (len_bits < 128 || offset_bits != 0)
546 abort();
f6a2a8ed
MD
547 }
548 if (_len_bits)
549 *_len_bits = len_bits;
0cbdadb5 550 return v;
f6a2a8ed
MD
551}
552
553static
0cbdadb5 554void print_enum_labels(const struct side_enum_mappings *mappings, union int_value v)
f6a2a8ed 555{
f6a2a8ed
MD
556 uint32_t i, print_count = 0;
557
0cbdadb5 558 side_check_value_s64(v);
d8be25de
MD
559 printf(", labels: [ ");
560 for (i = 0; i < mappings->nr_mappings; i++) {
64037418 561 const struct side_enum_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
79f677ba 562
ea32e5fc 563 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 564 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
565 mapping->range_begin, mapping->range_end);
566 abort();
567 }
0cbdadb5 568 if (v.s[SIDE_INTEGER128_SPLIT_LOW] >= mapping->range_begin && v.s[SIDE_INTEGER128_SPLIT_LOW] <= mapping->range_end) {
79f677ba 569 printf("%s", print_count++ ? ", " : "");
3bc9ba43
MD
570 tracer_print_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
571 side_enum_get(mapping->label.byte_order), NULL);
79f677ba
MD
572 }
573 }
574 if (!print_count)
575 printf("<NO LABEL>");
576 printf(" ]");
577}
578
f6a2a8ed 579static
67337c4a 580void tracer_print_enum(const struct side_type *type_desc, const struct side_arg *item)
f6a2a8ed 581{
64037418 582 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
c5789285 583 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum.elem_type);
0cbdadb5 584 union int_value v;
f6a2a8ed 585
3ce69bfa 586 if (side_enum_get(elem_type->type) != side_enum_get(item->type)) {
f6a2a8ed
MD
587 fprintf(stderr, "ERROR: Unexpected enum element type\n");
588 abort();
589 }
0cbdadb5 590 v = tracer_load_integer_value(&elem_type->u.side_integer,
67337c4a 591 &item->u.side_static.integer_value, 0, NULL);
12d787db 592 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
f6a2a8ed
MD
593 printf("%s", mappings->nr_attr ? ", " : "");
594 tracer_print_type(elem_type, item);
0cbdadb5 595 print_enum_labels(mappings, v);
f6a2a8ed
MD
596}
597
ea32e5fc 598static
67337c4a 599uint32_t elem_type_to_stride(const struct side_type *elem_type)
ea32e5fc 600{
af6aa6e1
MD
601 uint32_t stride_bit;
602
3ce69bfa 603 switch (side_enum_get(elem_type->type)) {
67337c4a 604 case SIDE_TYPE_BYTE:
af6aa6e1
MD
605 stride_bit = 8;
606 break;
8625d674 607
67337c4a
MD
608 case SIDE_TYPE_U8:
609 case SIDE_TYPE_U16:
610 case SIDE_TYPE_U32:
611 case SIDE_TYPE_U64:
0cbdadb5 612 case SIDE_TYPE_U128:
67337c4a
MD
613 case SIDE_TYPE_S8:
614 case SIDE_TYPE_S16:
615 case SIDE_TYPE_S32:
616 case SIDE_TYPE_S64:
0cbdadb5 617 case SIDE_TYPE_S128:
67337c4a 618 return elem_type->u.side_integer.integer_size * CHAR_BIT;
af6aa6e1 619 default:
8625d674 620 fprintf(stderr, "ERROR: Unexpected enum bitmap element type\n");
af6aa6e1
MD
621 abort();
622 }
623 return stride_bit;
624}
625
626static
67337c4a
MD
627void tracer_print_enum_bitmap(const struct side_type *type_desc,
628 const struct side_arg *item)
af6aa6e1 629{
64037418 630 const struct side_enum_bitmap_mappings *side_enum_mappings = side_ptr_get(type_desc->u.side_enum_bitmap.mappings);
c5789285 631 const struct side_type *enum_elem_type = side_ptr_get(type_desc->u.side_enum_bitmap.elem_type), *elem_type;
e65f9ce5 632 uint32_t i, print_count = 0, stride_bit, nr_items;
67337c4a 633 const struct side_arg *array_item;
af6aa6e1 634
3ce69bfa 635 switch (side_enum_get(enum_elem_type->type)) {
67337c4a
MD
636 case SIDE_TYPE_U8: /* Fall-through */
637 case SIDE_TYPE_BYTE: /* Fall-through */
638 case SIDE_TYPE_U16: /* Fall-through */
639 case SIDE_TYPE_U32: /* Fall-through */
640 case SIDE_TYPE_U64: /* Fall-through */
0cbdadb5 641 case SIDE_TYPE_U128: /* Fall-through */
67337c4a
MD
642 case SIDE_TYPE_S8: /* Fall-through */
643 case SIDE_TYPE_S16: /* Fall-through */
644 case SIDE_TYPE_S32: /* Fall-through */
0cbdadb5
MD
645 case SIDE_TYPE_S64: /* Fall-through */
646 case SIDE_TYPE_S128:
7f8e7e97 647 elem_type = enum_elem_type;
af6aa6e1
MD
648 array_item = item;
649 nr_items = 1;
af6aa6e1 650 break;
67337c4a 651 case SIDE_TYPE_ARRAY:
c5789285 652 elem_type = side_ptr_get(enum_elem_type->u.side_array.elem_type);
f13253cb 653 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_array)->sav);
67337c4a 654 nr_items = type_desc->u.side_array.length;
af6aa6e1 655 break;
67337c4a 656 case SIDE_TYPE_VLA:
c5789285 657 elem_type = side_ptr_get(enum_elem_type->u.side_vla.elem_type);
f13253cb 658 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_vla)->sav);
bac71609 659 nr_items = side_ptr_get(item->u.side_static.side_vla)->len;
af6aa6e1
MD
660 break;
661 default:
de1b3cd2 662 fprintf(stderr, "ERROR: Unexpected enum element type\n");
af6aa6e1
MD
663 abort();
664 }
7f8e7e97 665 stride_bit = elem_type_to_stride(elem_type);
ea32e5fc 666
12d787db 667 print_attributes("attr", ":", side_ptr_get(side_enum_mappings->attr), side_enum_mappings->nr_attr);
67337c4a 668 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
af6aa6e1 669 printf("labels: [ ");
67337c4a 670 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
64037418 671 const struct side_enum_bitmap_mapping *mapping = &side_ptr_get(side_enum_mappings->mappings)[i];
ea32e5fc 672 bool match = false;
9ff49ee4 673 uint64_t bit;
ea32e5fc 674
9ff49ee4 675 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 676 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
677 mapping->range_begin, mapping->range_end);
678 abort();
679 }
680 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
af6aa6e1
MD
681 if (bit > (nr_items * stride_bit) - 1)
682 break;
3ce69bfa 683 if (side_enum_get(elem_type->type) == SIDE_TYPE_BYTE) {
67337c4a 684 uint8_t v = array_item[bit / 8].u.side_static.byte_value;
af6aa6e1
MD
685 if (v & (1ULL << (bit % 8))) {
686 match = true;
687 goto match;
688 }
7f8e7e97 689 } else {
0cbdadb5 690 union int_value v = {};
7f8e7e97 691
0cbdadb5 692 v = tracer_load_integer_value(&elem_type->u.side_integer,
67337c4a 693 &array_item[bit / stride_bit].u.side_static.integer_value,
7f8e7e97 694 0, NULL);
0cbdadb5
MD
695 side_check_value_u64(v);
696 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (bit % stride_bit))) {
af6aa6e1
MD
697 match = true;
698 goto match;
699 }
af6aa6e1 700 }
ea32e5fc 701 }
af6aa6e1 702match:
ea32e5fc
MD
703 if (match) {
704 printf("%s", print_count++ ? ", " : "");
3bc9ba43
MD
705 tracer_print_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
706 side_enum_get(mapping->label.byte_order), NULL);
ea32e5fc
MD
707 }
708 }
709 if (!print_count)
710 printf("<NO LABEL>");
711 printf(" ]");
712}
713
1d9c515c 714static
0cbdadb5 715void print_integer_binary(uint64_t v[NR_SIDE_INTEGER128_SPLIT], int bits)
1d9c515c 716{
0cbdadb5 717 int bit;
1d9c515c
MD
718
719 printf("0b");
0cbdadb5
MD
720 if (bits > 64) {
721 bits -= 64;
722 v[SIDE_INTEGER128_SPLIT_HIGH] <<= 64 - bits;
723 for (bit = 0; bit < bits; bit++) {
724 printf("%c", v[SIDE_INTEGER128_SPLIT_HIGH] & (1ULL << 63) ? '1' : '0');
725 v[SIDE_INTEGER128_SPLIT_HIGH] <<= 1;
726 }
727 bits = 64;
728 }
729 v[SIDE_INTEGER128_SPLIT_LOW] <<= 64 - bits;
730 for (bit = 0; bit < bits; bit++) {
731 printf("%c", v[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << 63) ? '1' : '0');
732 v[SIDE_INTEGER128_SPLIT_LOW] <<= 1;
1d9c515c
MD
733 }
734}
735
0e9be766 736static
aac52685 737void tracer_print_type_header(const char *separator,
67337c4a 738 const struct side_attr *attr, uint32_t nr_attr)
ac81c466 739{
aac52685
MD
740 print_attributes("attr", separator, attr, nr_attr);
741 printf("%s", nr_attr ? ", " : "");
742 printf("value%s ", separator);
ac81c466
MD
743}
744
8ad2f385
MD
745static
746void tracer_print_type_bool(const char *separator,
67337c4a
MD
747 const struct side_type_bool *type_bool,
748 const union side_bool_value *value,
8ad2f385
MD
749 uint16_t offset_bits)
750{
88bab79c 751 uint32_t len_bits;
8ad2f385
MD
752 bool reverse_bo;
753 uint64_t v;
754
88bab79c
MD
755 if (!type_bool->len_bits)
756 len_bits = type_bool->bool_size * CHAR_BIT;
757 else
758 len_bits = type_bool->len_bits;
759 if (len_bits + offset_bits > type_bool->bool_size * CHAR_BIT)
8ad2f385 760 abort();
3bc9ba43 761 reverse_bo = side_enum_get(type_bool->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
88bab79c
MD
762 switch (type_bool->bool_size) {
763 case 1:
67337c4a 764 v = value->side_bool8;
8ad2f385 765 break;
88bab79c 766 case 2:
8ad2f385 767 {
67337c4a 768 uint16_t side_u16;
8ad2f385 769
67337c4a 770 side_u16 = value->side_bool16;
8ad2f385 771 if (reverse_bo)
67337c4a
MD
772 side_u16 = side_bswap_16(side_u16);
773 v = side_u16;
8ad2f385
MD
774 break;
775 }
88bab79c 776 case 4:
8ad2f385 777 {
67337c4a 778 uint32_t side_u32;
8ad2f385 779
67337c4a 780 side_u32 = value->side_bool32;
8ad2f385 781 if (reverse_bo)
67337c4a
MD
782 side_u32 = side_bswap_32(side_u32);
783 v = side_u32;
8ad2f385
MD
784 break;
785 }
88bab79c 786 case 8:
8ad2f385 787 {
67337c4a 788 uint64_t side_u64;
8ad2f385 789
67337c4a 790 side_u64 = value->side_bool64;
8ad2f385 791 if (reverse_bo)
67337c4a
MD
792 side_u64 = side_bswap_64(side_u64);
793 v = side_u64;
8ad2f385
MD
794 break;
795 }
796 default:
797 abort();
798 }
799 v >>= offset_bits;
88bab79c
MD
800 if (len_bits < 64)
801 v &= (1ULL << len_bits) - 1;
db8df9b5 802 tracer_print_type_header(separator, side_ptr_get(type_bool->attr), type_bool->nr_attr);
8ad2f385
MD
803 printf("%s", v ? "true" : "false");
804}
805
0cbdadb5
MD
806/* 2^128 - 1 */
807#define U128_BASE_10_ARRAY_LEN sizeof("340282366920938463463374607431768211455")
808/* -2^127 */
809#define S128_BASE_10_ARRAY_LEN sizeof("-170141183460469231731687303715884105728")
810
811/*
812 * u128_tostring_base_10 is inspired from https://stackoverflow.com/a/4364365
813 */
814static
815void u128_tostring_base_10(union int_value v, char str[U128_BASE_10_ARRAY_LEN])
816{
817 int d[39] = {}, i, j, str_i = 0;
818
819 for (i = 63; i > -1; i--) {
820 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
821 d[0]++;
822 for (j = 0; j < 39; j++)
823 d[j] *= 2;
824 for (j = 0; j < 38; j++) {
825 d[j + 1] += d[j] / 10;
826 d[j] %= 10;
827 }
828 }
829 for (i = 63; i > -1; i--) {
830 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
831 d[0]++;
832 if (i > 0) {
833 for (j = 0; j < 39; j++)
834 d[j] *= 2;
835 }
836 for (j = 0; j < 38; j++) {
837 d[j + 1] += d[j] / 10;
838 d[j] %= 10;
839 }
840 }
841 for (i = 38; i > 0; i--)
842 if (d[i] > 0)
843 break;
844 for (; i > -1; i--) {
845 str[str_i++] = '0' + d[i];
846 }
847 str[str_i] = '\0';
848}
849
850static
851void s128_tostring_base_10(union int_value v, char str[S128_BASE_10_ARRAY_LEN])
852{
853 uint64_t low, high, tmp;
854
855 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] >= 0) {
856 /* Positive. */
857 v.u[SIDE_INTEGER128_SPLIT_LOW] = (uint64_t) v.s[SIDE_INTEGER128_SPLIT_LOW];
858 v.u[SIDE_INTEGER128_SPLIT_HIGH] = (uint64_t) v.s[SIDE_INTEGER128_SPLIT_HIGH];
859 u128_tostring_base_10(v, str);
860 return;
861 }
862
863 /* Negative. */
864
865 /* Special-case minimum value, which has no positive signed representation. */
866 if ((v.s[SIDE_INTEGER128_SPLIT_HIGH] == INT64_MIN) && (v.s[SIDE_INTEGER128_SPLIT_LOW] == 0)) {
867 memcpy(str, "-170141183460469231731687303715884105728", S128_BASE_10_ARRAY_LEN);
868 return;
869 }
870 /* Convert from two's complement. */
871 high = ~(uint64_t) v.s[SIDE_INTEGER128_SPLIT_HIGH];
872 low = ~(uint64_t) v.s[SIDE_INTEGER128_SPLIT_LOW];
873 tmp = low + 1;
874 if (tmp < low) {
875 high++;
876 /* Clear overflow to sign bit. */
877 high &= ~0x8000000000000000ULL;
878 }
879 v.u[SIDE_INTEGER128_SPLIT_LOW] = tmp;
880 v.u[SIDE_INTEGER128_SPLIT_HIGH] = high;
881 str[0] = '-';
882 u128_tostring_base_10(v, str + 1);
883}
884
885/* 2^128 - 1 */
886#define U128_BASE_8_ARRAY_LEN sizeof("3777777777777777777777777777777777777777777")
887
888static
889void u128_tostring_base_8(union int_value v, char str[U128_BASE_8_ARRAY_LEN])
890{
891 int d[43] = {}, i, j, str_i = 0;
892
893 for (i = 63; i > -1; i--) {
894 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
895 d[0]++;
896 for (j = 0; j < 43; j++)
897 d[j] *= 2;
898 for (j = 0; j < 42; j++) {
899 d[j + 1] += d[j] / 8;
900 d[j] %= 8;
901 }
902 }
903 for (i = 63; i > -1; i--) {
904 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
905 d[0]++;
906 if (i > 0) {
907 for (j = 0; j < 43; j++)
908 d[j] *= 2;
909 }
910 for (j = 0; j < 42; j++) {
911 d[j + 1] += d[j] / 8;
912 d[j] %= 8;
913 }
914 }
915 for (i = 42; i > 0; i--)
916 if (d[i] > 0)
917 break;
918 for (; i > -1; i--) {
919 str[str_i++] = '0' + d[i];
920 }
921 str[str_i] = '\0';
922}
923
4f5e1b67
MD
924static
925void tracer_print_type_integer(const char *separator,
67337c4a
MD
926 const struct side_type_integer *type_integer,
927 const union side_integer_value *value,
4f5e1b67
MD
928 uint16_t offset_bits,
929 enum tracer_display_base default_base)
930{
931 enum tracer_display_base base;
0cbdadb5 932 union int_value v;
4f5e1b67
MD
933 uint16_t len_bits;
934
0cbdadb5 935 v = tracer_load_integer_value(type_integer, value, offset_bits, &len_bits);
12d787db
MD
936 tracer_print_type_header(separator, side_ptr_get(type_integer->attr), type_integer->nr_attr);
937 base = get_attr_display_base(side_ptr_get(type_integer->attr), type_integer->nr_attr, default_base);
56c21987
MD
938 switch (base) {
939 case TRACER_DISPLAY_BASE_2:
0cbdadb5 940 print_integer_binary(v.u, len_bits);
56c21987
MD
941 break;
942 case TRACER_DISPLAY_BASE_8:
f6a2a8ed 943 /* Clear sign bits beyond len_bits */
0cbdadb5
MD
944 if (len_bits < 64) {
945 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
946 v.u[SIDE_INTEGER128_SPLIT_HIGH] = 0;
947 } else if (len_bits < 128) {
948 v.u[SIDE_INTEGER128_SPLIT_HIGH] &= (1ULL << (len_bits - 64)) - 1;
949 }
950 if (len_bits <= 64) {
951 printf("0o%" PRIo64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
952 } else {
953 char str[U128_BASE_8_ARRAY_LEN];
954
955 u128_tostring_base_8(v, str);
956 printf("0o%s", str);
957 }
56c21987
MD
958 break;
959 case TRACER_DISPLAY_BASE_10:
0cbdadb5
MD
960 if (len_bits <= 64) {
961 if (type_integer->signedness)
962 printf("%" PRId64, v.s[SIDE_INTEGER128_SPLIT_LOW]);
963 else
964 printf("%" PRIu64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
965 } else {
966 if (type_integer->signedness) {
967 char str[S128_BASE_10_ARRAY_LEN];
968 s128_tostring_base_10(v, str);
969 printf("%s", str);
970 } else {
971 char str[U128_BASE_10_ARRAY_LEN];
972 u128_tostring_base_10(v, str);
973 printf("%s", str);
974 }
975 }
56c21987
MD
976 break;
977 case TRACER_DISPLAY_BASE_16:
f6a2a8ed 978 /* Clear sign bits beyond len_bits */
0cbdadb5
MD
979 if (len_bits < 64) {
980 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
981 v.u[SIDE_INTEGER128_SPLIT_HIGH] = 0;
982 } else if (len_bits < 128) {
983 v.u[SIDE_INTEGER128_SPLIT_HIGH] &= (1ULL << (len_bits - 64)) - 1;
984 }
985 if (len_bits <= 64 || v.u[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
986 printf("0x%" PRIx64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
987 } else {
988 printf("0x%" PRIx64 "%016" PRIx64,
989 v.u[SIDE_INTEGER128_SPLIT_HIGH],
990 v.u[SIDE_INTEGER128_SPLIT_LOW]);
991 }
56c21987
MD
992 break;
993 default:
994 abort();
995 }
996}
997
3aa7ca5e
MD
998static
999void tracer_print_type_float(const char *separator,
67337c4a
MD
1000 const struct side_type_float *type_float,
1001 const union side_float_value *value)
3aa7ca5e
MD
1002{
1003 bool reverse_bo;
1004
12d787db 1005 tracer_print_type_header(separator, side_ptr_get(type_float->attr), type_float->nr_attr);
3bc9ba43 1006 reverse_bo = side_enum_get(type_float->byte_order) != SIDE_TYPE_FLOAT_WORD_ORDER_HOST;
88bab79c
MD
1007 switch (type_float->float_size) {
1008 case 2:
3aa7ca5e
MD
1009 {
1010#if __HAVE_FLOAT16
1011 union {
1012 _Float16 f;
1013 uint16_t u;
1014 } float16 = {
67337c4a 1015 .f = value->side_float_binary16,
3aa7ca5e
MD
1016 };
1017
1018 if (reverse_bo)
67337c4a 1019 float16.u = side_bswap_16(float16.u);
3aa7ca5e
MD
1020 printf("%g", (double) float16.f);
1021 break;
1022#else
1023 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
1024 abort();
1025#endif
1026 }
88bab79c 1027 case 4:
3aa7ca5e
MD
1028 {
1029#if __HAVE_FLOAT32
1030 union {
1031 _Float32 f;
1032 uint32_t u;
1033 } float32 = {
67337c4a 1034 .f = value->side_float_binary32,
3aa7ca5e
MD
1035 };
1036
1037 if (reverse_bo)
67337c4a 1038 float32.u = side_bswap_32(float32.u);
3aa7ca5e
MD
1039 printf("%g", (double) float32.f);
1040 break;
1041#else
1042 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
1043 abort();
1044#endif
1045 }
88bab79c 1046 case 8:
3aa7ca5e
MD
1047 {
1048#if __HAVE_FLOAT64
1049 union {
1050 _Float64 f;
1051 uint64_t u;
1052 } float64 = {
67337c4a 1053 .f = value->side_float_binary64,
3aa7ca5e
MD
1054 };
1055
1056 if (reverse_bo)
67337c4a 1057 float64.u = side_bswap_64(float64.u);
3aa7ca5e
MD
1058 printf("%g", (double) float64.f);
1059 break;
1060#else
1061 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
1062 abort();
1063#endif
1064 }
88bab79c 1065 case 16:
3aa7ca5e
MD
1066 {
1067#if __HAVE_FLOAT128
1068 union {
1069 _Float128 f;
1070 char arr[16];
1071 } float128 = {
67337c4a 1072 .f = value->side_float_binary128,
3aa7ca5e
MD
1073 };
1074
1075 if (reverse_bo)
67337c4a 1076 side_bswap_128p(float128.arr);
3aa7ca5e
MD
1077 printf("%Lg", (long double) float128.f);
1078 break;
1079#else
1080 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
1081 abort();
1082#endif
1083 }
1084 default:
1085 fprintf(stderr, "ERROR: Unknown float size\n");
1086 abort();
1087 }
1088}
1089
f611d0c3 1090static
67337c4a 1091void tracer_print_type(const struct side_type *type_desc, const struct side_arg *item)
f611d0c3 1092{
67337c4a 1093 enum side_type_label type;
d8be25de 1094
3ce69bfa 1095 switch (side_enum_get(type_desc->type)) {
67337c4a 1096 case SIDE_TYPE_ENUM:
3ce69bfa 1097 switch (side_enum_get(item->type)) {
67337c4a
MD
1098 case SIDE_TYPE_U8:
1099 case SIDE_TYPE_U16:
1100 case SIDE_TYPE_U32:
1101 case SIDE_TYPE_U64:
0cbdadb5 1102 case SIDE_TYPE_U128:
67337c4a
MD
1103 case SIDE_TYPE_S8:
1104 case SIDE_TYPE_S16:
1105 case SIDE_TYPE_S32:
1106 case SIDE_TYPE_S64:
0cbdadb5 1107 case SIDE_TYPE_S128:
bab5d6e4
MD
1108 break;
1109 default:
de1b3cd2 1110 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
45392033
MD
1111 abort();
1112 break;
1113 }
1114 break;
1115
67337c4a 1116 case SIDE_TYPE_ENUM_BITMAP:
3ce69bfa 1117 switch (side_enum_get(item->type)) {
67337c4a
MD
1118 case SIDE_TYPE_U8:
1119 case SIDE_TYPE_BYTE:
1120 case SIDE_TYPE_U16:
1121 case SIDE_TYPE_U32:
1122 case SIDE_TYPE_U64:
0cbdadb5 1123 case SIDE_TYPE_U128:
67337c4a
MD
1124 case SIDE_TYPE_ARRAY:
1125 case SIDE_TYPE_VLA:
45392033
MD
1126 break;
1127 default:
de1b3cd2 1128 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
45392033
MD
1129 abort();
1130 break;
d8be25de
MD
1131 }
1132 break;
1133
67337c4a 1134 case SIDE_TYPE_GATHER_ENUM:
3ce69bfa 1135 switch (side_enum_get(item->type)) {
67337c4a 1136 case SIDE_TYPE_GATHER_INTEGER:
0519cb86
MD
1137 break;
1138 default:
1139 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
1140 abort();
1141 break;
1142 }
1143 break;
1144
67337c4a 1145 case SIDE_TYPE_DYNAMIC:
3ce69bfa 1146 switch (side_enum_get(item->type)) {
67337c4a
MD
1147 case SIDE_TYPE_DYNAMIC_NULL:
1148 case SIDE_TYPE_DYNAMIC_BOOL:
1149 case SIDE_TYPE_DYNAMIC_INTEGER:
1150 case SIDE_TYPE_DYNAMIC_BYTE:
1151 case SIDE_TYPE_DYNAMIC_POINTER:
1152 case SIDE_TYPE_DYNAMIC_FLOAT:
1153 case SIDE_TYPE_DYNAMIC_STRING:
1154 case SIDE_TYPE_DYNAMIC_STRUCT:
1155 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
1156 case SIDE_TYPE_DYNAMIC_VLA:
1157 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
66de373e
MD
1158 break;
1159 default:
1160 fprintf(stderr, "ERROR: Unexpected dynamic type\n");
1161 abort();
1162 break;
1163 }
1164 break;
1165
ba845af5 1166 default:
3ce69bfa 1167 if (side_enum_get(type_desc->type) != side_enum_get(item->type)) {
de1b3cd2 1168 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
ba845af5
MD
1169 abort();
1170 }
1171 break;
f611d0c3 1172 }
d8be25de 1173
3ce69bfa
MD
1174 if (side_enum_get(type_desc->type) == SIDE_TYPE_ENUM || side_enum_get(type_desc->type) == SIDE_TYPE_ENUM_BITMAP || side_enum_get(type_desc->type) == SIDE_TYPE_GATHER_ENUM)
1175 type = side_enum_get(type_desc->type);
d8be25de 1176 else
3ce69bfa 1177 type = side_enum_get(item->type);
d8be25de 1178
a848763d 1179 printf("{ ");
d8be25de 1180 switch (type) {
55fb50b7 1181 /* Stack-copy basic types */
67337c4a 1182 case SIDE_TYPE_NULL:
b313067b
MD
1183 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_null.attr),
1184 type_desc->u.side_null.nr_attr);
9b641221
MD
1185 printf("<NULL TYPE>");
1186 break;
1187
67337c4a
MD
1188 case SIDE_TYPE_BOOL:
1189 tracer_print_type_bool(":", &type_desc->u.side_bool, &item->u.side_static.bool_value, 0);
4f40d951 1190 break;
1d9c515c 1191
67337c4a
MD
1192 case SIDE_TYPE_U8:
1193 case SIDE_TYPE_U16:
1194 case SIDE_TYPE_U32:
1195 case SIDE_TYPE_U64:
0cbdadb5 1196 case SIDE_TYPE_U128:
67337c4a
MD
1197 case SIDE_TYPE_S8:
1198 case SIDE_TYPE_S16:
1199 case SIDE_TYPE_S32:
1200 case SIDE_TYPE_S64:
0cbdadb5 1201 case SIDE_TYPE_S128:
67337c4a 1202 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0,
f0dafd60 1203 TRACER_DISPLAY_BASE_10);
f611d0c3 1204 break;
56c21987 1205
67337c4a 1206 case SIDE_TYPE_BYTE:
12d787db 1207 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_byte.attr), type_desc->u.side_byte.nr_attr);
67337c4a 1208 printf("0x%" PRIx8, item->u.side_static.byte_value);
7aec0d09 1209 break;
79f677ba 1210
67337c4a
MD
1211 case SIDE_TYPE_POINTER:
1212 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0,
55fb50b7 1213 TRACER_DISPLAY_BASE_16);
ea32e5fc
MD
1214 break;
1215
67337c4a
MD
1216 case SIDE_TYPE_FLOAT_BINARY16:
1217 case SIDE_TYPE_FLOAT_BINARY32:
1218 case SIDE_TYPE_FLOAT_BINARY64:
1219 case SIDE_TYPE_FLOAT_BINARY128:
1220 tracer_print_type_float(":", &type_desc->u.side_float, &item->u.side_static.float_value);
fb25b355 1221 break;
3aa7ca5e 1222
67337c4a
MD
1223 case SIDE_TYPE_STRING_UTF8:
1224 case SIDE_TYPE_STRING_UTF16:
1225 case SIDE_TYPE_STRING_UTF32:
12d787db 1226 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_string.attr), type_desc->u.side_string.nr_attr);
6910c28c 1227 tracer_print_string(side_ptr_get(item->u.side_static.string_value),
3bc9ba43 1228 type_desc->u.side_string.unit_size, side_enum_get(type_desc->u.side_string.byte_order), NULL);
f611d0c3 1229 break;
55fb50b7
MD
1230
1231 /* Stack-copy compound types */
67337c4a 1232 case SIDE_TYPE_STRUCT:
bac71609 1233 tracer_print_struct(type_desc, side_ptr_get(item->u.side_static.side_struct));
f611d0c3 1234 break;
5530345d 1235 case SIDE_TYPE_VARIANT:
bac71609 1236 tracer_print_variant(type_desc, side_ptr_get(item->u.side_static.side_variant));
5530345d 1237 break;
67337c4a 1238 case SIDE_TYPE_ARRAY:
bac71609 1239 tracer_print_array(type_desc, side_ptr_get(item->u.side_static.side_array));
d9359cfa 1240 break;
67337c4a 1241 case SIDE_TYPE_VLA:
bac71609 1242 tracer_print_vla(type_desc, side_ptr_get(item->u.side_static.side_vla));
33956c71 1243 break;
67337c4a
MD
1244 case SIDE_TYPE_VLA_VISITOR:
1245 tracer_print_vla_visitor(type_desc, item->u.side_static.side_vla_app_visitor_ctx);
80429681 1246 break;
55fb50b7
MD
1247
1248 /* Stack-copy enumeration types */
67337c4a 1249 case SIDE_TYPE_ENUM:
f6a2a8ed 1250 tracer_print_enum(type_desc, item);
55fb50b7 1251 break;
67337c4a 1252 case SIDE_TYPE_ENUM_BITMAP:
7f8e7e97 1253 tracer_print_enum_bitmap(type_desc, item);
55fb50b7
MD
1254 break;
1255
1256 /* Gather basic types */
67337c4a 1257 case SIDE_TYPE_GATHER_BOOL:
155b1756 1258 (void) tracer_print_gather_bool_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_bool_gather_ptr));
8ad2f385 1259 break;
67337c4a 1260 case SIDE_TYPE_GATHER_INTEGER:
155b1756 1261 (void) tracer_print_gather_integer_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr),
55fb50b7
MD
1262 TRACER_DISPLAY_BASE_10);
1263 break;
67337c4a 1264 case SIDE_TYPE_GATHER_BYTE:
155b1756 1265 (void) tracer_print_gather_byte_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_byte_gather_ptr));
d69918cc 1266 break;
67337c4a 1267 case SIDE_TYPE_GATHER_POINTER:
155b1756 1268 (void) tracer_print_gather_integer_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr),
4e1b0e0e
MD
1269 TRACER_DISPLAY_BASE_16);
1270 break;
67337c4a 1271 case SIDE_TYPE_GATHER_FLOAT:
155b1756 1272 (void) tracer_print_gather_float_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_float_gather_ptr));
905f68e3 1273 break;
67337c4a 1274 case SIDE_TYPE_GATHER_STRING:
155b1756 1275 (void) tracer_print_gather_string_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_string_gather_ptr));
7d34edfc 1276 break;
55fb50b7
MD
1277
1278 /* Gather compound type */
67337c4a 1279 case SIDE_TYPE_GATHER_STRUCT:
155b1756 1280 (void) tracer_print_gather_struct(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_struct_gather_ptr));
f611d0c3 1281 break;
67337c4a 1282 case SIDE_TYPE_GATHER_ARRAY:
155b1756 1283 (void) tracer_print_gather_array(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_array_gather_ptr));
f611d0c3 1284 break;
67337c4a 1285 case SIDE_TYPE_GATHER_VLA:
155b1756
MD
1286 (void) tracer_print_gather_vla(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_vla_gather.ptr),
1287 side_ptr_get(item->u.side_static.side_vla_gather.length_ptr));
f611d0c3 1288 break;
66de373e 1289
0519cb86 1290 /* Gather enumeration types */
67337c4a 1291 case SIDE_TYPE_GATHER_ENUM:
155b1756 1292 (void) tracer_print_gather_enum_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr));
0519cb86
MD
1293 break;
1294
55fb50b7 1295 /* Dynamic basic types */
67337c4a
MD
1296 case SIDE_TYPE_DYNAMIC_NULL:
1297 case SIDE_TYPE_DYNAMIC_BOOL:
1298 case SIDE_TYPE_DYNAMIC_INTEGER:
1299 case SIDE_TYPE_DYNAMIC_BYTE:
1300 case SIDE_TYPE_DYNAMIC_POINTER:
1301 case SIDE_TYPE_DYNAMIC_FLOAT:
1302 case SIDE_TYPE_DYNAMIC_STRING:
55fb50b7
MD
1303
1304 /* Dynamic compound types */
67337c4a
MD
1305 case SIDE_TYPE_DYNAMIC_STRUCT:
1306 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
1307 case SIDE_TYPE_DYNAMIC_VLA:
1308 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
66de373e 1309 tracer_print_dynamic(item);
a2e2357e 1310 break;
f611d0c3 1311 default:
f6c02218 1312 fprintf(stderr, "<UNKNOWN TYPE>\n");
f611d0c3
MD
1313 abort();
1314 }
a848763d 1315 printf(" }");
f611d0c3
MD
1316}
1317
1318static
67337c4a 1319void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg *item)
f611d0c3 1320{
c5789285 1321 printf("%s: ", side_ptr_get(item_desc->field_name));
67337c4a 1322 tracer_print_type(&item_desc->side_type, item);
f611d0c3
MD
1323}
1324
1325static
67337c4a 1326void tracer_print_struct(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
f611d0c3 1327{
f13253cb 1328 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
c5789285 1329 const struct side_type_struct *side_struct = side_ptr_get(type_desc->u.side_struct);
67337c4a 1330 uint32_t i, side_sav_len = side_arg_vec->len;
f611d0c3 1331
c5789285 1332 if (side_struct->nr_fields != side_sav_len) {
de1b3cd2 1333 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n");
f611d0c3
MD
1334 abort();
1335 }
c5789285
MD
1336 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1337 printf("%s", side_struct->nr_attr ? ", " : "");
73b2b0c2 1338 printf("fields: { ");
67337c4a 1339 for (i = 0; i < side_sav_len; i++) {
f611d0c3 1340 printf("%s", i ? ", " : "");
c5789285 1341 tracer_print_field(&side_ptr_get(side_struct->fields)[i], &sav[i]);
f611d0c3 1342 }
d4328528 1343 printf(" }");
f611d0c3
MD
1344}
1345
5530345d
MD
1346static
1347void tracer_print_variant(const struct side_type *type_desc, const struct side_arg_variant *side_arg_variant)
1348{
c5789285 1349 const struct side_type_variant *side_type_variant = side_ptr_get(type_desc->u.side_variant);
5530345d 1350 const struct side_type *selector_type = &side_type_variant->selector;
0cbdadb5 1351 union int_value v;
5530345d
MD
1352 uint32_t i;
1353
3ce69bfa 1354 if (side_enum_get(selector_type->type) != side_enum_get(side_arg_variant->selector.type)) {
5530345d
MD
1355 fprintf(stderr, "ERROR: Unexpected variant selector type\n");
1356 abort();
1357 }
3ce69bfa 1358 switch (side_enum_get(selector_type->type)) {
5530345d
MD
1359 case SIDE_TYPE_U8:
1360 case SIDE_TYPE_U16:
1361 case SIDE_TYPE_U32:
1362 case SIDE_TYPE_U64:
0cbdadb5 1363 case SIDE_TYPE_U128:
5530345d
MD
1364 case SIDE_TYPE_S8:
1365 case SIDE_TYPE_S16:
1366 case SIDE_TYPE_S32:
1367 case SIDE_TYPE_S64:
0cbdadb5 1368 case SIDE_TYPE_S128:
5530345d
MD
1369 break;
1370 default:
1371 fprintf(stderr, "ERROR: Expecting integer variant selector type\n");
1372 abort();
1373 }
0cbdadb5 1374 v = tracer_load_integer_value(&selector_type->u.side_integer,
5530345d 1375 &side_arg_variant->selector.u.side_static.integer_value, 0, NULL);
0cbdadb5 1376 side_check_value_u64(v);
5530345d 1377 for (i = 0; i < side_type_variant->nr_options; i++) {
c5789285 1378 const struct side_variant_option *option = &side_ptr_get(side_type_variant->options)[i];
5530345d 1379
0cbdadb5 1380 if (v.s[SIDE_INTEGER128_SPLIT_LOW] >= option->range_begin && v.s[SIDE_INTEGER128_SPLIT_LOW] <= option->range_end) {
5530345d
MD
1381 tracer_print_type(&option->side_type, &side_arg_variant->option);
1382 return;
1383 }
1384 }
0cbdadb5 1385 fprintf(stderr, "ERROR: Variant selector value unknown %" PRId64 "\n", v.s[SIDE_INTEGER128_SPLIT_LOW]);
5530345d
MD
1386 abort();
1387}
1388
7a1cb105 1389static
67337c4a 1390void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
d9359cfa 1391{
f13253cb 1392 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
67337c4a 1393 uint32_t i, side_sav_len = side_arg_vec->len;
d9359cfa 1394
67337c4a 1395 if (type_desc->u.side_array.length != side_sav_len) {
d9359cfa
MD
1396 fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n");
1397 abort();
1398 }
12d787db 1399 print_attributes("attr", ":", side_ptr_get(type_desc->u.side_array.attr), type_desc->u.side_array.nr_attr);
67337c4a 1400 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
d9359cfa
MD
1401 printf("elements: ");
1402 printf("[ ");
67337c4a 1403 for (i = 0; i < side_sav_len; i++) {
d9359cfa 1404 printf("%s", i ? ", " : "");
c5789285 1405 tracer_print_type(side_ptr_get(type_desc->u.side_array.elem_type), &sav[i]);
d9359cfa
MD
1406 }
1407 printf(" ]");
1408}
1409
1410static
67337c4a 1411void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
d9359cfa 1412{
f13253cb 1413 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
67337c4a 1414 uint32_t i, side_sav_len = side_arg_vec->len;
d9359cfa 1415
12d787db 1416 print_attributes("attr", ":", side_ptr_get(type_desc->u.side_vla.attr), type_desc->u.side_vla.nr_attr);
67337c4a 1417 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
d9359cfa
MD
1418 printf("elements: ");
1419 printf("[ ");
67337c4a 1420 for (i = 0; i < side_sav_len; i++) {
d9359cfa 1421 printf("%s", i ? ", " : "");
c5789285 1422 tracer_print_type(side_ptr_get(type_desc->u.side_vla.elem_type), &sav[i]);
d9359cfa
MD
1423 }
1424 printf(" ]");
1425}
1426
dd7947bf 1427static
67337c4a 1428const char *tracer_gather_access(enum side_type_gather_access_mode access_mode, const char *ptr)
dd7947bf 1429{
65b8734a 1430 switch (access_mode) {
67337c4a 1431 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
dd7947bf 1432 return ptr;
67337c4a 1433 case SIDE_TYPE_GATHER_ACCESS_POINTER:
dd7947bf 1434 /* Dereference pointer */
dc9567a6 1435 memcpy(&ptr, ptr, sizeof(const char *));
dd7947bf
MD
1436 return ptr;
1437 default:
1438 abort();
1439 }
1440}
1441
1442static
67337c4a 1443uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode, uint32_t len)
dd7947bf 1444{
65b8734a 1445 switch (access_mode) {
67337c4a 1446 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
dd7947bf 1447 return len;
67337c4a 1448 case SIDE_TYPE_GATHER_ACCESS_POINTER:
dd7947bf
MD
1449 return sizeof(void *);
1450 default:
1451 abort();
1452 }
1453}
1454
d9359cfa 1455static
0cbdadb5 1456union int_value tracer_load_gather_integer_value(const struct side_type_gather_integer *side_integer,
0519cb86 1457 const void *_ptr)
7a1cb105 1458{
67337c4a
MD
1459 enum side_type_gather_access_mode access_mode =
1460 (enum side_type_gather_access_mode) side_integer->access_mode;
1461 uint32_t integer_size_bytes = side_integer->type.integer_size;
7a1cb105 1462 const char *ptr = (const char *) _ptr;
67337c4a 1463 union side_integer_value value;
65b8734a 1464
67337c4a 1465 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
65b8734a 1466 memcpy(&value, ptr, integer_size_bytes);
67337c4a
MD
1467 return tracer_load_integer_value(&side_integer->type, &value,
1468 side_integer->offset_bits, NULL);
65b8734a
MD
1469}
1470
8ad2f385 1471static
67337c4a 1472uint32_t tracer_print_gather_bool_type(const struct side_type_gather *type_gather, const void *_ptr)
8ad2f385 1473{
67337c4a
MD
1474 enum side_type_gather_access_mode access_mode =
1475 (enum side_type_gather_access_mode) type_gather->u.side_bool.access_mode;
1476 uint32_t bool_size_bytes = type_gather->u.side_bool.type.bool_size;
8ad2f385 1477 const char *ptr = (const char *) _ptr;
67337c4a 1478 union side_bool_value value;
8ad2f385 1479
88bab79c
MD
1480 switch (bool_size_bytes) {
1481 case 1:
1482 case 2:
1483 case 4:
8ad2f385 1484 case 8:
8ad2f385
MD
1485 break;
1486 default:
1487 abort();
1488 }
67337c4a 1489 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_bool.offset);
8ad2f385 1490 memcpy(&value, ptr, bool_size_bytes);
67337c4a
MD
1491 tracer_print_type_bool(":", &type_gather->u.side_bool.type, &value,
1492 type_gather->u.side_bool.offset_bits);
8ad2f385
MD
1493 return tracer_gather_size(access_mode, bool_size_bytes);
1494}
1495
d69918cc 1496static
67337c4a 1497uint32_t tracer_print_gather_byte_type(const struct side_type_gather *type_gather, const void *_ptr)
d69918cc 1498{
67337c4a
MD
1499 enum side_type_gather_access_mode access_mode =
1500 (enum side_type_gather_access_mode) type_gather->u.side_byte.access_mode;
d69918cc
MD
1501 const char *ptr = (const char *) _ptr;
1502 uint8_t value;
1503
67337c4a 1504 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_byte.offset);
d69918cc 1505 memcpy(&value, ptr, 1);
12d787db 1506 tracer_print_type_header(":", side_ptr_get(type_gather->u.side_byte.type.attr),
67337c4a 1507 type_gather->u.side_byte.type.nr_attr);
d69918cc
MD
1508 printf("0x%" PRIx8, value);
1509 return tracer_gather_size(access_mode, 1);
1510}
1511
65b8734a 1512static
67337c4a 1513uint32_t tracer_print_gather_integer_type(const struct side_type_gather *type_gather, const void *_ptr,
4e1b0e0e 1514 enum tracer_display_base default_base)
65b8734a 1515{
67337c4a
MD
1516 enum side_type_gather_access_mode access_mode =
1517 (enum side_type_gather_access_mode) type_gather->u.side_integer.access_mode;
1518 uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size;
65b8734a 1519 const char *ptr = (const char *) _ptr;
67337c4a 1520 union side_integer_value value;
7a1cb105 1521
88bab79c
MD
1522 switch (integer_size_bytes) {
1523 case 1:
1524 case 2:
1525 case 4:
33956c71 1526 case 8:
0cbdadb5 1527 case 16:
9b641221 1528 break;
33956c71
MD
1529 default:
1530 abort();
1531 }
67337c4a 1532 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset);
dd7947bf 1533 memcpy(&value, ptr, integer_size_bytes);
67337c4a
MD
1534 tracer_print_type_integer(":", &type_gather->u.side_integer.type, &value,
1535 type_gather->u.side_integer.offset_bits, default_base);
d41cb7ee 1536 return tracer_gather_size(access_mode, integer_size_bytes);
33956c71 1537}
9b641221 1538
905f68e3 1539static
67337c4a 1540uint32_t tracer_print_gather_float_type(const struct side_type_gather *type_gather, const void *_ptr)
905f68e3 1541{
67337c4a
MD
1542 enum side_type_gather_access_mode access_mode =
1543 (enum side_type_gather_access_mode) type_gather->u.side_float.access_mode;
1544 uint32_t float_size_bytes = type_gather->u.side_float.type.float_size;
905f68e3 1545 const char *ptr = (const char *) _ptr;
67337c4a 1546 union side_float_value value;
905f68e3 1547
88bab79c
MD
1548 switch (float_size_bytes) {
1549 case 2:
1550 case 4:
1551 case 8:
905f68e3 1552 case 16:
905f68e3
MD
1553 break;
1554 default:
1555 abort();
1556 }
67337c4a 1557 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_float.offset);
dd7947bf 1558 memcpy(&value, ptr, float_size_bytes);
67337c4a 1559 tracer_print_type_float(":", &type_gather->u.side_float.type, &value);
d41cb7ee 1560 return tracer_gather_size(access_mode, float_size_bytes);
905f68e3
MD
1561}
1562
7d34edfc 1563static
67337c4a 1564uint32_t tracer_print_gather_string_type(const struct side_type_gather *type_gather, const void *_ptr)
7d34edfc 1565{
67337c4a
MD
1566 enum side_type_gather_access_mode access_mode =
1567 (enum side_type_gather_access_mode) type_gather->u.side_string.access_mode;
7d34edfc
MD
1568 const char *ptr = (const char *) _ptr;
1569 size_t string_len;
1570
67337c4a 1571 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_string.offset);
12d787db 1572 tracer_print_type_header(":", side_ptr_get(type_gather->u.side_string.type.attr),
67337c4a 1573 type_gather->u.side_string.type.nr_attr);
7d34edfc 1574 if (ptr) {
67337c4a 1575 tracer_print_string(ptr, type_gather->u.side_string.type.unit_size,
3bc9ba43 1576 side_enum_get(type_gather->u.side_string.type.byte_order), &string_len);
7d34edfc
MD
1577 } else {
1578 printf("<NULL>");
67337c4a 1579 string_len = type_gather->u.side_string.type.unit_size;
7d34edfc
MD
1580 }
1581 return tracer_gather_size(access_mode, string_len);
1582}
1583
33956c71 1584static
67337c4a 1585uint32_t tracer_print_gather_type(const struct side_type *type_desc, const void *ptr)
33956c71 1586{
d9359cfa
MD
1587 uint32_t len;
1588
33956c71 1589 printf("{ ");
3ce69bfa 1590 switch (side_enum_get(type_desc->type)) {
55fb50b7 1591 /* Gather basic types */
67337c4a
MD
1592 case SIDE_TYPE_GATHER_BOOL:
1593 len = tracer_print_gather_bool_type(&type_desc->u.side_gather, ptr);
8ad2f385 1594 break;
67337c4a
MD
1595 case SIDE_TYPE_GATHER_INTEGER:
1596 len = tracer_print_gather_integer_type(&type_desc->u.side_gather, ptr,
55fb50b7
MD
1597 TRACER_DISPLAY_BASE_10);
1598 break;
67337c4a
MD
1599 case SIDE_TYPE_GATHER_BYTE:
1600 len = tracer_print_gather_byte_type(&type_desc->u.side_gather, ptr);
d69918cc 1601 break;
67337c4a
MD
1602 case SIDE_TYPE_GATHER_POINTER:
1603 len = tracer_print_gather_integer_type(&type_desc->u.side_gather, ptr,
4e1b0e0e
MD
1604 TRACER_DISPLAY_BASE_16);
1605 break;
67337c4a
MD
1606 case SIDE_TYPE_GATHER_FLOAT:
1607 len = tracer_print_gather_float_type(&type_desc->u.side_gather, ptr);
33956c71 1608 break;
67337c4a
MD
1609 case SIDE_TYPE_GATHER_STRING:
1610 len = tracer_print_gather_string_type(&type_desc->u.side_gather, ptr);
7d34edfc 1611 break;
55fb50b7 1612
0519cb86 1613 /* Gather enum types */
67337c4a
MD
1614 case SIDE_TYPE_GATHER_ENUM:
1615 len = tracer_print_gather_enum_type(&type_desc->u.side_gather, ptr);
0519cb86
MD
1616 break;
1617
55fb50b7 1618 /* Gather compound types */
67337c4a
MD
1619 case SIDE_TYPE_GATHER_STRUCT:
1620 len = tracer_print_gather_struct(&type_desc->u.side_gather, ptr);
d9359cfa 1621 break;
67337c4a
MD
1622 case SIDE_TYPE_GATHER_ARRAY:
1623 len = tracer_print_gather_array(&type_desc->u.side_gather, ptr);
9b641221 1624 break;
67337c4a
MD
1625 case SIDE_TYPE_GATHER_VLA:
1626 len = tracer_print_gather_vla(&type_desc->u.side_gather, ptr, ptr);
65b8734a 1627 break;
9b641221 1628 default:
d41cb7ee 1629 fprintf(stderr, "<UNKNOWN GATHER TYPE>");
9b641221 1630 abort();
7a1cb105
MD
1631 }
1632 printf(" }");
d9359cfa 1633 return len;
7a1cb105
MD
1634}
1635
0519cb86 1636static
67337c4a 1637uint32_t tracer_print_gather_enum_type(const struct side_type_gather *type_gather, const void *_ptr)
0519cb86 1638{
64037418 1639 const struct side_enum_mappings *mappings = side_ptr_get(type_gather->u.side_enum.mappings);
c5789285 1640 const struct side_type *enum_elem_type = side_ptr_get(type_gather->u.side_enum.elem_type);
67337c4a
MD
1641 const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer;
1642 enum side_type_gather_access_mode access_mode =
1643 (enum side_type_gather_access_mode) side_integer->access_mode;
1644 uint32_t integer_size_bytes = side_integer->type.integer_size;
0519cb86 1645 const char *ptr = (const char *) _ptr;
67337c4a 1646 union side_integer_value value;
0cbdadb5 1647 union int_value v;
0519cb86
MD
1648
1649 switch (integer_size_bytes) {
1650 case 1:
1651 case 2:
1652 case 4:
1653 case 8:
0cbdadb5 1654 case 16:
0519cb86
MD
1655 break;
1656 default:
1657 abort();
1658 }
67337c4a 1659 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
0519cb86 1660 memcpy(&value, ptr, integer_size_bytes);
0cbdadb5 1661 v = tracer_load_gather_integer_value(side_integer, &value);
12d787db 1662 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
0519cb86
MD
1663 printf("%s", mappings->nr_attr ? ", " : "");
1664 tracer_print_gather_type(enum_elem_type, ptr);
0cbdadb5 1665 print_enum_labels(mappings, v);
0519cb86
MD
1666 return tracer_gather_size(access_mode, integer_size_bytes);
1667}
1668
7a1cb105 1669static
67337c4a 1670void tracer_print_gather_field(const struct side_event_field *field, const void *ptr)
7a1cb105 1671{
c5789285 1672 printf("%s: ", side_ptr_get(field->field_name));
67337c4a 1673 (void) tracer_print_gather_type(&field->side_type, ptr);
7a1cb105
MD
1674}
1675
1676static
67337c4a 1677uint32_t tracer_print_gather_struct(const struct side_type_gather *type_gather, const void *_ptr)
7a1cb105 1678{
67337c4a
MD
1679 enum side_type_gather_access_mode access_mode =
1680 (enum side_type_gather_access_mode) type_gather->u.side_struct.access_mode;
c5789285 1681 const struct side_type_struct *side_struct = side_ptr_get(type_gather->u.side_struct.type);
dd7947bf 1682 const char *ptr = (const char *) _ptr;
e65f9ce5 1683 uint32_t i;
7a1cb105 1684
67337c4a 1685 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_struct.offset);
c5789285
MD
1686 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1687 printf("%s", side_struct->nr_attr ? ", " : "");
7a1cb105 1688 printf("fields: { ");
c5789285 1689 for (i = 0; i < side_struct->nr_fields; i++) {
7a1cb105 1690 printf("%s", i ? ", " : "");
c5789285 1691 tracer_print_gather_field(&side_ptr_get(side_struct->fields)[i], ptr);
7a1cb105
MD
1692 }
1693 printf(" }");
67337c4a 1694 return tracer_gather_size(access_mode, type_gather->u.side_struct.size);
7a1cb105
MD
1695}
1696
f611d0c3 1697static
67337c4a 1698uint32_t tracer_print_gather_array(const struct side_type_gather *type_gather, const void *_ptr)
f611d0c3 1699{
67337c4a
MD
1700 enum side_type_gather_access_mode access_mode =
1701 (enum side_type_gather_access_mode) type_gather->u.side_array.access_mode;
dd7947bf 1702 const char *ptr = (const char *) _ptr, *orig_ptr;
d9359cfa 1703 uint32_t i;
f611d0c3 1704
67337c4a 1705 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_array.offset);
65b8734a 1706 orig_ptr = ptr;
12d787db 1707 print_attributes("attr", ":", side_ptr_get(type_gather->u.side_array.type.attr), type_gather->u.side_array.type.nr_attr);
67337c4a 1708 printf("%s", type_gather->u.side_array.type.nr_attr ? ", " : "");
65b8734a
MD
1709 printf("elements: ");
1710 printf("[ ");
67337c4a 1711 for (i = 0; i < type_gather->u.side_array.type.length; i++) {
c5789285
MD
1712 const struct side_type *elem_type = side_ptr_get(type_gather->u.side_array.type.elem_type);
1713
3ce69bfa 1714 switch (side_enum_get(elem_type->type)) {
67337c4a 1715 case SIDE_TYPE_GATHER_VLA:
d41cb7ee 1716 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
65b8734a
MD
1717 abort();
1718 default:
1719 break;
1720 }
1721 printf("%s", i ? ", " : "");
c5789285 1722 ptr += tracer_print_gather_type(elem_type, ptr);
65b8734a
MD
1723 }
1724 printf(" ]");
d41cb7ee 1725 return tracer_gather_size(access_mode, ptr - orig_ptr);
65b8734a
MD
1726}
1727
1728static
67337c4a 1729uint32_t tracer_print_gather_vla(const struct side_type_gather *type_gather, const void *_ptr,
80429681 1730 const void *_length_ptr)
65b8734a 1731{
67337c4a
MD
1732 enum side_type_gather_access_mode access_mode =
1733 (enum side_type_gather_access_mode) type_gather->u.side_vla.access_mode;
c5789285 1734 const struct side_type *length_type = side_ptr_get(type_gather->u.side_vla.length_type);
65b8734a 1735 const char *ptr = (const char *) _ptr, *orig_ptr;
80429681 1736 const char *length_ptr = (const char *) _length_ptr;
0cbdadb5 1737 union int_value v = {};
65b8734a
MD
1738 uint32_t i, length;
1739
1740 /* Access length */
3ce69bfa 1741 switch (side_enum_get(length_type->type)) {
67337c4a 1742 case SIDE_TYPE_GATHER_INTEGER:
65b8734a
MD
1743 break;
1744 default:
d41cb7ee 1745 fprintf(stderr, "<gather VLA expects integer gather length type>\n");
65b8734a
MD
1746 abort();
1747 }
0cbdadb5 1748 v = tracer_load_gather_integer_value(&length_type->u.side_gather.u.side_integer,
0519cb86 1749 length_ptr);
0cbdadb5
MD
1750 if (v.u[SIDE_INTEGER128_SPLIT_HIGH] || v.u[SIDE_INTEGER128_SPLIT_LOW] > UINT32_MAX) {
1751 fprintf(stderr, "Unexpected vla length value\n");
1752 abort();
1753 }
1754 length = (uint32_t) v.u[SIDE_INTEGER128_SPLIT_LOW];
67337c4a 1755 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_vla.offset);
dd7947bf 1756 orig_ptr = ptr;
12d787db 1757 print_attributes("attr", ":", side_ptr_get(type_gather->u.side_vla.type.attr), type_gather->u.side_vla.type.nr_attr);
67337c4a 1758 printf("%s", type_gather->u.side_vla.type.nr_attr ? ", " : "");
20574104 1759 printf("elements: ");
f611d0c3 1760 printf("[ ");
65b8734a 1761 for (i = 0; i < length; i++) {
c5789285
MD
1762 const struct side_type *elem_type = side_ptr_get(type_gather->u.side_vla.type.elem_type);
1763
3ce69bfa 1764 switch (side_enum_get(elem_type->type)) {
67337c4a 1765 case SIDE_TYPE_GATHER_VLA:
d41cb7ee 1766 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
65b8734a
MD
1767 abort();
1768 default:
1769 break;
1770 }
f611d0c3 1771 printf("%s", i ? ", " : "");
c5789285 1772 ptr += tracer_print_gather_type(elem_type, ptr);
f611d0c3
MD
1773 }
1774 printf(" ]");
d41cb7ee 1775 return tracer_gather_size(access_mode, ptr - orig_ptr);
f611d0c3
MD
1776}
1777
352a4b77 1778struct tracer_visitor_priv {
67337c4a 1779 const struct side_type *elem_type;
352a4b77
MD
1780 int i;
1781};
1782
1783static
67337c4a
MD
1784enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
1785 const struct side_arg *elem)
352a4b77 1786{
e65f9ce5 1787 struct tracer_visitor_priv *tracer_priv = (struct tracer_visitor_priv *) tracer_ctx->priv;
352a4b77
MD
1788
1789 printf("%s", tracer_priv->i++ ? ", " : "");
1790 tracer_print_type(tracer_priv->elem_type, elem);
67337c4a 1791 return SIDE_VISITOR_STATUS_OK;
352a4b77
MD
1792}
1793
f611d0c3 1794static
67337c4a 1795void tracer_print_vla_visitor(const struct side_type *type_desc, void *app_ctx)
f611d0c3 1796{
67337c4a 1797 enum side_visitor_status status;
352a4b77 1798 struct tracer_visitor_priv tracer_priv = {
c5789285 1799 .elem_type = side_ptr_get(type_desc->u.side_vla_visitor.elem_type),
352a4b77
MD
1800 .i = 0,
1801 };
67337c4a 1802 const struct side_tracer_visitor_ctx tracer_ctx = {
352a4b77
MD
1803 .write_elem = tracer_write_elem_cb,
1804 .priv = &tracer_priv,
1805 };
2e197497 1806 side_visitor_func func;
f611d0c3 1807
12d787db 1808 print_attributes("attr", ":", side_ptr_get(type_desc->u.side_vla_visitor.attr), type_desc->u.side_vla_visitor.nr_attr);
67337c4a 1809 printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : "");
20574104 1810 printf("elements: ");
352a4b77 1811 printf("[ ");
2e197497
MD
1812 func = side_ptr_get(type_desc->u.side_vla_visitor.visitor);
1813 status = func(&tracer_ctx, app_ctx);
352a4b77 1814 switch (status) {
67337c4a 1815 case SIDE_VISITOR_STATUS_OK:
352a4b77 1816 break;
67337c4a 1817 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1818 fprintf(stderr, "ERROR: Visitor error\n");
f611d0c3 1819 abort();
f611d0c3
MD
1820 }
1821 printf(" ]");
f611d0c3
MD
1822}
1823
a2e2357e 1824static
67337c4a 1825void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct)
a2e2357e 1826{
f13253cb 1827 const struct side_arg_dynamic_field *fields = side_ptr_get(dynamic_struct->fields);
e65f9ce5 1828 uint32_t i, len = dynamic_struct->len;
465e5e7e 1829
12d787db 1830 print_attributes("attr", "::", side_ptr_get(dynamic_struct->attr), dynamic_struct->nr_attr);
8d20e708 1831 printf("%s", dynamic_struct->nr_attr ? ", " : "");
f0061366 1832 printf("fields:: ");
465e5e7e
MD
1833 printf("[ ");
1834 for (i = 0; i < len; i++) {
1835 printf("%s", i ? ", " : "");
f13253cb 1836 printf("%s:: ", side_ptr_get(fields[i].field_name));
465e5e7e
MD
1837 tracer_print_dynamic(&fields[i].elem);
1838 }
1839 printf(" ]");
a2e2357e
MD
1840}
1841
2b359235
MD
1842struct tracer_dynamic_struct_visitor_priv {
1843 int i;
1844};
1845
1846static
67337c4a
MD
1847enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
1848 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
1849 const struct side_arg_dynamic_field *dynamic_field)
2b359235 1850{
e65f9ce5
MD
1851 struct tracer_dynamic_struct_visitor_priv *tracer_priv =
1852 (struct tracer_dynamic_struct_visitor_priv *) tracer_ctx->priv;
2b359235
MD
1853
1854 printf("%s", tracer_priv->i++ ? ", " : "");
f13253cb 1855 printf("%s:: ", side_ptr_get(dynamic_field->field_name));
2b359235 1856 tracer_print_dynamic(&dynamic_field->elem);
67337c4a 1857 return SIDE_VISITOR_STATUS_OK;
2b359235
MD
1858}
1859
a2e2357e 1860static
67337c4a 1861void tracer_print_dynamic_struct_visitor(const struct side_arg *item)
a2e2357e 1862{
67337c4a 1863 enum side_visitor_status status;
2b359235
MD
1864 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
1865 .i = 0,
1866 };
67337c4a 1867 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
2b359235
MD
1868 .write_field = tracer_dynamic_struct_write_elem_cb,
1869 .priv = &tracer_priv,
1870 };
2e197497 1871 void *app_ctx = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor.app_ctx);
2b359235 1872
12d787db 1873 print_attributes("attr", "::", side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor.attr), item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr);
67337c4a 1874 printf("%s", item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr ? ", " : "");
f0061366 1875 printf("fields:: ");
2b359235 1876 printf("[ ");
2e197497 1877 status = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor.visitor)(&tracer_ctx, app_ctx);
2b359235 1878 switch (status) {
67337c4a 1879 case SIDE_VISITOR_STATUS_OK:
2b359235 1880 break;
67337c4a 1881 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1882 fprintf(stderr, "ERROR: Visitor error\n");
2b359235
MD
1883 abort();
1884 }
1885 printf(" ]");
a2e2357e
MD
1886}
1887
1888static
67337c4a 1889void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla *vla)
a2e2357e 1890{
f13253cb 1891 const struct side_arg *sav = side_ptr_get(vla->sav);
67337c4a 1892 uint32_t i, side_sav_len = vla->len;
a2e2357e 1893
12d787db 1894 print_attributes("attr", "::", side_ptr_get(vla->attr), vla->nr_attr);
8d20e708 1895 printf("%s", vla->nr_attr ? ", " : "");
f0061366 1896 printf("elements:: ");
a2e2357e 1897 printf("[ ");
67337c4a 1898 for (i = 0; i < side_sav_len; i++) {
a2e2357e
MD
1899 printf("%s", i ? ", " : "");
1900 tracer_print_dynamic(&sav[i]);
1901 }
1902 printf(" ]");
1903}
1904
8ceca0cd
MD
1905struct tracer_dynamic_vla_visitor_priv {
1906 int i;
1907};
1908
1909static
67337c4a
MD
1910enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
1911 const struct side_tracer_visitor_ctx *tracer_ctx,
1912 const struct side_arg *elem)
8ceca0cd 1913{
e65f9ce5
MD
1914 struct tracer_dynamic_vla_visitor_priv *tracer_priv =
1915 (struct tracer_dynamic_vla_visitor_priv *) tracer_ctx->priv;
8ceca0cd
MD
1916
1917 printf("%s", tracer_priv->i++ ? ", " : "");
1918 tracer_print_dynamic(elem);
67337c4a 1919 return SIDE_VISITOR_STATUS_OK;
8ceca0cd
MD
1920}
1921
a2e2357e 1922static
67337c4a 1923void tracer_print_dynamic_vla_visitor(const struct side_arg *item)
a2e2357e 1924{
67337c4a 1925 enum side_visitor_status status;
8ceca0cd
MD
1926 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
1927 .i = 0,
1928 };
67337c4a 1929 const struct side_tracer_visitor_ctx tracer_ctx = {
8ceca0cd
MD
1930 .write_elem = tracer_dynamic_vla_write_elem_cb,
1931 .priv = &tracer_priv,
1932 };
2e197497 1933 void *app_ctx = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor.app_ctx);
8ceca0cd 1934
12d787db 1935 print_attributes("attr", "::", side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor.attr), item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr);
67337c4a 1936 printf("%s", item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr ? ", " : "");
f0061366 1937 printf("elements:: ");
8ceca0cd 1938 printf("[ ");
2e197497 1939 status = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor.visitor)(&tracer_ctx, app_ctx);
8ceca0cd 1940 switch (status) {
67337c4a 1941 case SIDE_VISITOR_STATUS_OK:
8ceca0cd 1942 break;
67337c4a 1943 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1944 fprintf(stderr, "ERROR: Visitor error\n");
8ceca0cd
MD
1945 abort();
1946 }
1947 printf(" ]");
a2e2357e
MD
1948}
1949
1950static
67337c4a 1951void tracer_print_dynamic(const struct side_arg *item)
a2e2357e 1952{
808bd9bf 1953 printf("{ ");
3ce69bfa 1954 switch (side_enum_get(item->type)) {
55fb50b7 1955 /* Dynamic basic types */
67337c4a 1956 case SIDE_TYPE_DYNAMIC_NULL:
b313067b
MD
1957 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_null.attr),
1958 item->u.side_dynamic.side_null.nr_attr);
a2e2357e
MD
1959 printf("<NULL TYPE>");
1960 break;
67337c4a
MD
1961 case SIDE_TYPE_DYNAMIC_BOOL:
1962 tracer_print_type_bool("::", &item->u.side_dynamic.side_bool.type, &item->u.side_dynamic.side_bool.value, 0);
66de373e 1963 break;
67337c4a
MD
1964 case SIDE_TYPE_DYNAMIC_INTEGER:
1965 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
f0dafd60 1966 TRACER_DISPLAY_BASE_10);
a2e2357e 1967 break;
67337c4a 1968 case SIDE_TYPE_DYNAMIC_BYTE:
12d787db 1969 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_byte.type.attr), item->u.side_dynamic.side_byte.type.nr_attr);
67337c4a 1970 printf("0x%" PRIx8, item->u.side_dynamic.side_byte.value);
199e7aa9 1971 break;
67337c4a
MD
1972 case SIDE_TYPE_DYNAMIC_POINTER:
1973 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
f0dafd60 1974 TRACER_DISPLAY_BASE_16);
f5e650d7 1975 break;
67337c4a
MD
1976 case SIDE_TYPE_DYNAMIC_FLOAT:
1977 tracer_print_type_float("::", &item->u.side_dynamic.side_float.type,
1978 &item->u.side_dynamic.side_float.value);
fb25b355 1979 break;
67337c4a 1980 case SIDE_TYPE_DYNAMIC_STRING:
12d787db 1981 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_string.type.attr), item->u.side_dynamic.side_string.type.nr_attr);
67337c4a
MD
1982 tracer_print_string((const char *)(uintptr_t) item->u.side_dynamic.side_string.value,
1983 item->u.side_dynamic.side_string.type.unit_size,
3bc9ba43 1984 side_enum_get(item->u.side_dynamic.side_string.type.byte_order), NULL);
a2e2357e 1985 break;
55fb50b7
MD
1986
1987 /* Dynamic compound types */
67337c4a 1988 case SIDE_TYPE_DYNAMIC_STRUCT:
f13253cb 1989 tracer_print_dynamic_struct(side_ptr_get(item->u.side_dynamic.side_dynamic_struct));
a2e2357e 1990 break;
67337c4a 1991 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
c208889e 1992 tracer_print_dynamic_struct_visitor(item);
a2e2357e 1993 break;
67337c4a 1994 case SIDE_TYPE_DYNAMIC_VLA:
f13253cb 1995 tracer_print_dynamic_vla(side_ptr_get(item->u.side_dynamic.side_dynamic_vla));
a2e2357e 1996 break;
67337c4a 1997 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
a2e2357e
MD
1998 tracer_print_dynamic_vla_visitor(item);
1999 break;
2000 default:
f6c02218 2001 fprintf(stderr, "<UNKNOWN TYPE>\n");
a2e2357e
MD
2002 abort();
2003 }
808bd9bf 2004 printf(" }");
a2e2357e
MD
2005}
2006
68f8cfbe 2007static
67337c4a
MD
2008void tracer_print_static_fields(const struct side_event_description *desc,
2009 const struct side_arg_vec *side_arg_vec,
e65f9ce5 2010 uint32_t *nr_items)
f611d0c3 2011{
f13253cb 2012 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
67337c4a 2013 uint32_t i, side_sav_len = side_arg_vec->len;
f611d0c3 2014
0b9e59d6 2015 printf("provider: %s, event: %s", side_ptr_get(desc->provider_name), side_ptr_get(desc->event_name));
67337c4a 2016 if (desc->nr_fields != side_sav_len) {
de1b3cd2 2017 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
f611d0c3
MD
2018 abort();
2019 }
12d787db 2020 print_attributes(", attr", ":", side_ptr_get(desc->attr), desc->nr_attr);
67337c4a
MD
2021 printf("%s", side_sav_len ? ", fields: [ " : "");
2022 for (i = 0; i < side_sav_len; i++) {
f611d0c3 2023 printf("%s", i ? ", " : "");
0b9e59d6 2024 tracer_print_field(&side_ptr_get(desc->fields)[i], &sav[i]);
f611d0c3 2025 }
68f8cfbe
MD
2026 if (nr_items)
2027 *nr_items = i;
67337c4a 2028 if (side_sav_len)
c7d338e2 2029 printf(" ]");
68f8cfbe
MD
2030}
2031
9365e936 2032static
67337c4a
MD
2033void tracer_call(const struct side_event_description *desc,
2034 const struct side_arg_vec *side_arg_vec,
4a7d8700 2035 void *priv __attribute__((unused)))
68f8cfbe 2036{
e65f9ce5 2037 uint32_t nr_fields = 0;
a848763d 2038
67337c4a 2039 tracer_print_static_fields(desc, side_arg_vec, &nr_fields);
f611d0c3
MD
2040 printf("\n");
2041}
19fa6aa2 2042
9365e936 2043static
67337c4a
MD
2044void tracer_call_variadic(const struct side_event_description *desc,
2045 const struct side_arg_vec *side_arg_vec,
2046 const struct side_arg_dynamic_struct *var_struct,
4a7d8700 2047 void *priv __attribute__((unused)))
19fa6aa2 2048{
e65f9ce5 2049 uint32_t nr_fields = 0, i, var_struct_len = var_struct->len;
19fa6aa2 2050
67337c4a 2051 tracer_print_static_fields(desc, side_arg_vec, &nr_fields);
68f8cfbe 2052
67337c4a 2053 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
de1b3cd2 2054 fprintf(stderr, "ERROR: unexpected non-variadic event description\n");
8a25ce77
MD
2055 abort();
2056 }
12d787db 2057 print_attributes(", attr ", "::", side_ptr_get(var_struct->attr), var_struct->nr_attr);
905c328e 2058 printf("%s", var_struct_len ? ", fields:: [ " : "");
68f8cfbe 2059 for (i = 0; i < var_struct_len; i++, nr_fields++) {
c7d338e2 2060 printf("%s", i ? ", " : "");
f13253cb
MD
2061 printf("%s:: ", side_ptr_get(side_ptr_get(var_struct->fields)[i].field_name));
2062 tracer_print_dynamic(&side_ptr_get(var_struct->fields)[i].elem);
19fa6aa2 2063 }
a848763d
MD
2064 if (i)
2065 printf(" ]");
19fa6aa2
MD
2066 printf("\n");
2067}
1e8aec23 2068
9365e936 2069static
67337c4a
MD
2070void tracer_event_notification(enum side_tracer_notification notif,
2071 struct side_event_description **events, uint32_t nr_events,
9365e936 2072 void *priv __attribute__((unused)))
1e8aec23
MD
2073{
2074 uint32_t i;
314c22c3 2075 int ret;
1e8aec23
MD
2076
2077 printf("----------------------------------------------------------\n");
2078 printf("Tracer notified of events %s\n",
67337c4a 2079 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1e8aec23 2080 for (i = 0; i < nr_events; i++) {
67337c4a 2081 struct side_event_description *event = events[i];
1e8aec23
MD
2082
2083 /* Skip NULL pointers */
2084 if (!event)
2085 continue;
b2a84b9f
MD
2086 if (event->version != SIDE_EVENT_DESCRIPTION_ABI_VERSION) {
2087 printf("Error: event description ABI version (%u) does not match the version supported by the tracer (%u)\n",
2088 event->version, SIDE_EVENT_DESCRIPTION_ABI_VERSION);
441235e7
MD
2089 return;
2090 }
1e8aec23 2091 printf("provider: %s, event: %s\n",
0b9e59d6 2092 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
441235e7 2093 if (event->struct_size != side_offsetofend(struct side_event_description, side_event_description_orig_abi_last)) {
b2a84b9f 2094 printf("Warning: Event %s.%s description contains fields unknown to the tracer\n",
441235e7
MD
2095 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
2096 }
78dd4cc3 2097 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
2d8e1a70
MD
2098 if (event->nr_side_type_label > _NR_SIDE_TYPE_LABEL) {
2099 printf("Warning: event %s:%s may contain unknown field types (%u unknown types)\n",
2100 side_ptr_get(event->provider_name), side_ptr_get(event->event_name),
2101 event->nr_side_type_label - _NR_SIDE_TYPE_LABEL);
2102 }
2103 if (event->nr_side_attr_type > _NR_SIDE_ATTR_TYPE) {
2104 printf("Warning: event %s:%s may contain unknown attribute types (%u unknown types)\n",
2105 side_ptr_get(event->provider_name), side_ptr_get(event->event_name),
2106 event->nr_side_attr_type - _NR_SIDE_ATTR_TYPE);
2107 }
67337c4a
MD
2108 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
2109 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL);
314c22c3
MD
2110 if (ret)
2111 abort();
2112 } else {
67337c4a 2113 ret = side_tracer_callback_register(event, tracer_call, NULL);
314c22c3
MD
2114 if (ret)
2115 abort();
2116 }
2117 } else {
67337c4a
MD
2118 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
2119 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL);
314c22c3
MD
2120 if (ret)
2121 abort();
2122 } else {
67337c4a 2123 ret = side_tracer_callback_unregister(event, tracer_call, NULL);
314c22c3
MD
2124 if (ret)
2125 abort();
2126 }
2127 }
1e8aec23
MD
2128 }
2129 printf("----------------------------------------------------------\n");
2130}
2131
2132static __attribute__((constructor))
2133void tracer_init(void);
2134static
2135void tracer_init(void)
2136{
67337c4a 2137 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1e8aec23
MD
2138 if (!tracer_handle)
2139 abort();
2140}
2141
2142static __attribute__((destructor))
2143void tracer_exit(void);
2144static
2145void tracer_exit(void)
2146{
67337c4a 2147 side_tracer_event_notification_unregister(tracer_handle);
1e8aec23 2148}
This page took 0.166183 seconds and 4 git commands to generate.