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