trace.h: Use side_enum_t for side_attr_type enum
[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
4f5e1b67
MD
23union int64_value {
24 uint64_t u;
25 int64_t s;
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
67337c4a 185int64_t get_attr_integer_value(const struct side_attr *attr)
1d9c515c
MD
186{
187 int64_t val;
188
15f17024 189 switch (side_enum_get(attr->value.type)) {
67337c4a
MD
190 case SIDE_ATTR_TYPE_U8:
191 val = attr->value.u.integer_value.side_u8;
1d9c515c 192 break;
67337c4a
MD
193 case SIDE_ATTR_TYPE_U16:
194 val = attr->value.u.integer_value.side_u16;
1d9c515c 195 break;
67337c4a
MD
196 case SIDE_ATTR_TYPE_U32:
197 val = attr->value.u.integer_value.side_u32;
1d9c515c 198 break;
67337c4a
MD
199 case SIDE_ATTR_TYPE_U64:
200 val = attr->value.u.integer_value.side_u64;
1d9c515c 201 break;
67337c4a
MD
202 case SIDE_ATTR_TYPE_S8:
203 val = attr->value.u.integer_value.side_s8;
1d9c515c 204 break;
67337c4a
MD
205 case SIDE_ATTR_TYPE_S16:
206 val = attr->value.u.integer_value.side_s16;
1d9c515c 207 break;
67337c4a
MD
208 case SIDE_ATTR_TYPE_S32:
209 val = attr->value.u.integer_value.side_s32;
1d9c515c 210 break;
67337c4a
MD
211 case SIDE_ATTR_TYPE_S64:
212 val = attr->value.u.integer_value.side_s64;
1d9c515c
MD
213 break;
214 default:
215 fprintf(stderr, "Unexpected attribute type\n");
216 abort();
217 }
218 return val;
219}
220
221static
67337c4a 222enum tracer_display_base get_attr_display_base(const struct side_attr *_attr, uint32_t nr_attr,
f0dafd60 223 enum tracer_display_base default_base)
1d9c515c
MD
224{
225 uint32_t i;
226
227 for (i = 0; i < nr_attr; i++) {
67337c4a 228 const struct side_attr *attr = &_attr[i];
9ceac3e2
MD
229 char *utf8_str = NULL;
230 bool cmp;
1d9c515c 231
3db2d8a1 232 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
9ceac3e2
MD
233 attr->key.byte_order, NULL, &utf8_str);
234 cmp = strcmp(utf8_str, "std.integer.base");
3db2d8a1 235 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2
MD
236 free(utf8_str);
237 if (!cmp) {
1d9c515c
MD
238 int64_t val = get_attr_integer_value(attr);
239
240 switch (val) {
241 case 2:
242 return TRACER_DISPLAY_BASE_2;
243 case 8:
244 return TRACER_DISPLAY_BASE_8;
245 case 10:
246 return TRACER_DISPLAY_BASE_10;
247 case 16:
248 return TRACER_DISPLAY_BASE_16;
249 default:
250 fprintf(stderr, "Unexpected integer display base: %" PRId64 "\n", val);
251 abort();
252 }
253 }
254 }
f0dafd60 255 return default_base; /* Default */
1d9c515c
MD
256}
257
bc3c89b3 258static
67337c4a 259void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
bc3c89b3 260{
9ceac3e2
MD
261 char *utf8_str = NULL;
262
3db2d8a1 263 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
9ceac3e2
MD
264 attr->key.byte_order, NULL, &utf8_str);
265 printf("{ key%s \"%s\", value%s ", separator, utf8_str, separator);
3db2d8a1 266 if (utf8_str != side_ptr_get(attr->key.p))
9ceac3e2 267 free(utf8_str);
15f17024 268 switch (side_enum_get(attr->value.type)) {
67337c4a 269 case SIDE_ATTR_TYPE_BOOL:
5f82db91 270 printf("%s", attr->value.u.bool_value ? "true" : "false");
bc3c89b3 271 break;
67337c4a
MD
272 case SIDE_ATTR_TYPE_U8:
273 printf("%" PRIu8, attr->value.u.integer_value.side_u8);
bc3c89b3 274 break;
67337c4a
MD
275 case SIDE_ATTR_TYPE_U16:
276 printf("%" PRIu16, attr->value.u.integer_value.side_u16);
bc3c89b3 277 break;
67337c4a
MD
278 case SIDE_ATTR_TYPE_U32:
279 printf("%" PRIu32, attr->value.u.integer_value.side_u32);
bc3c89b3 280 break;
67337c4a
MD
281 case SIDE_ATTR_TYPE_U64:
282 printf("%" PRIu64, attr->value.u.integer_value.side_u64);
bc3c89b3 283 break;
67337c4a
MD
284 case SIDE_ATTR_TYPE_S8:
285 printf("%" PRId8, attr->value.u.integer_value.side_s8);
bc3c89b3 286 break;
67337c4a
MD
287 case SIDE_ATTR_TYPE_S16:
288 printf("%" PRId16, attr->value.u.integer_value.side_s16);
bc3c89b3 289 break;
67337c4a
MD
290 case SIDE_ATTR_TYPE_S32:
291 printf("%" PRId32, attr->value.u.integer_value.side_s32);
bc3c89b3 292 break;
67337c4a
MD
293 case SIDE_ATTR_TYPE_S64:
294 printf("%" PRId64, attr->value.u.integer_value.side_s64);
bc3c89b3 295 break;
67337c4a 296 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
bc3c89b3 297#if __HAVE_FLOAT16
67337c4a 298 printf("%g", (double) attr->value.u.float_value.side_float_binary16);
bc3c89b3
MD
299 break;
300#else
de1b3cd2 301 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
bc3c89b3
MD
302 abort();
303#endif
67337c4a 304 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
bc3c89b3 305#if __HAVE_FLOAT32
67337c4a 306 printf("%g", (double) attr->value.u.float_value.side_float_binary32);
bc3c89b3
MD
307 break;
308#else
de1b3cd2 309 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
bc3c89b3
MD
310 abort();
311#endif
67337c4a 312 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
bc3c89b3 313#if __HAVE_FLOAT64
67337c4a 314 printf("%g", (double) attr->value.u.float_value.side_float_binary64);
bc3c89b3
MD
315 break;
316#else
de1b3cd2 317 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
bc3c89b3
MD
318 abort();
319#endif
67337c4a 320 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
bc3c89b3 321#if __HAVE_FLOAT128
67337c4a 322 printf("%Lg", (long double) attr->value.u.float_value.side_float_binary128);
bc3c89b3
MD
323 break;
324#else
de1b3cd2 325 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
bc3c89b3
MD
326 abort();
327#endif
67337c4a 328 case SIDE_ATTR_TYPE_STRING:
3db2d8a1 329 tracer_print_string(side_ptr_get(attr->value.u.string_value.p),
ab8a626e
MD
330 attr->value.u.string_value.unit_size,
331 attr->value.u.string_value.byte_order, NULL);
bc3c89b3
MD
332 break;
333 default:
de1b3cd2 334 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
bc3c89b3
MD
335 abort();
336 }
337 printf(" }");
338}
339
7d21cf51 340static
905c328e 341void print_attributes(const char *prefix_str, const char *separator,
67337c4a 342 const struct side_attr *attr, uint32_t nr_attr)
7d21cf51 343{
e65f9ce5 344 uint32_t i;
7d21cf51
MD
345
346 if (!nr_attr)
347 return;
905c328e 348 printf("%s%s [ ", prefix_str, separator);
7d21cf51
MD
349 for (i = 0; i < nr_attr; i++) {
350 printf("%s", i ? ", " : "");
905c328e 351 tracer_print_attr_type(separator, &attr[i]);
7d21cf51
MD
352 }
353 printf(" ]");
354}
355
79f677ba 356static
67337c4a
MD
357union int64_value tracer_load_integer_value(const struct side_type_integer *type_integer,
358 const union side_integer_value *value,
f6a2a8ed 359 uint16_t offset_bits, uint16_t *_len_bits)
79f677ba 360{
f6a2a8ed
MD
361 union int64_value v64;
362 uint16_t len_bits;
363 bool reverse_bo;
79f677ba 364
f6a2a8ed
MD
365 if (!type_integer->len_bits)
366 len_bits = type_integer->integer_size * CHAR_BIT;
367 else
368 len_bits = type_integer->len_bits;
369 if (len_bits + offset_bits > type_integer->integer_size * CHAR_BIT)
d8be25de 370 abort();
67337c4a 371 reverse_bo = type_integer->byte_order != SIDE_TYPE_BYTE_ORDER_HOST;
f6a2a8ed
MD
372 switch (type_integer->integer_size) {
373 case 1:
374 if (type_integer->signedness)
67337c4a 375 v64.s = value->side_s8;
f6a2a8ed 376 else
67337c4a 377 v64.u = value->side_u8;
d8be25de 378 break;
f6a2a8ed
MD
379 case 2:
380 if (type_integer->signedness) {
67337c4a 381 int16_t side_s16;
8bdd5c12 382
67337c4a 383 side_s16 = value->side_s16;
f6a2a8ed 384 if (reverse_bo)
67337c4a
MD
385 side_s16 = side_bswap_16(side_s16);
386 v64.s = side_s16;
f6a2a8ed 387 } else {
67337c4a 388 uint16_t side_u16;
8bdd5c12 389
67337c4a 390 side_u16 = value->side_u16;
f6a2a8ed 391 if (reverse_bo)
67337c4a
MD
392 side_u16 = side_bswap_16(side_u16);
393 v64.u = side_u16;
f6a2a8ed 394 }
d8be25de 395 break;
f6a2a8ed
MD
396 case 4:
397 if (type_integer->signedness) {
67337c4a 398 int32_t side_s32;
8bdd5c12 399
67337c4a 400 side_s32 = value->side_s32;
f6a2a8ed 401 if (reverse_bo)
67337c4a
MD
402 side_s32 = side_bswap_32(side_s32);
403 v64.s = side_s32;
f6a2a8ed 404 } else {
67337c4a 405 uint32_t side_u32;
8bdd5c12 406
67337c4a 407 side_u32 = value->side_u32;
f6a2a8ed 408 if (reverse_bo)
67337c4a
MD
409 side_u32 = side_bswap_32(side_u32);
410 v64.u = side_u32;
f6a2a8ed 411 }
d8be25de 412 break;
f6a2a8ed
MD
413 case 8:
414 if (type_integer->signedness) {
67337c4a 415 int64_t side_s64;
8bdd5c12 416
67337c4a 417 side_s64 = value->side_s64;
f6a2a8ed 418 if (reverse_bo)
67337c4a
MD
419 side_s64 = side_bswap_64(side_s64);
420 v64.s = side_s64;
f6a2a8ed 421 } else {
67337c4a 422 uint64_t side_u64;
8bdd5c12 423
67337c4a 424 side_u64 = value->side_u64;
f6a2a8ed 425 if (reverse_bo)
67337c4a
MD
426 side_u64 = side_bswap_64(side_u64);
427 v64.u = side_u64;
f6a2a8ed 428 }
d8be25de
MD
429 break;
430 default:
d8be25de
MD
431 abort();
432 }
f6a2a8ed
MD
433 v64.u >>= offset_bits;
434 if (len_bits < 64) {
435 v64.u &= (1ULL << len_bits) - 1;
436 if (type_integer->signedness) {
437 /* Sign-extend. */
438 if (v64.u & (1ULL << (len_bits - 1)))
439 v64.u |= ~((1ULL << len_bits) - 1);
440 }
441 }
442 if (_len_bits)
443 *_len_bits = len_bits;
444 return v64;
445}
446
447static
67337c4a 448void print_enum_labels(const struct side_enum_mappings *mappings, union int64_value v64)
f6a2a8ed 449{
f6a2a8ed
MD
450 uint32_t i, print_count = 0;
451
d8be25de
MD
452 printf(", labels: [ ");
453 for (i = 0; i < mappings->nr_mappings; i++) {
64037418 454 const struct side_enum_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
79f677ba 455
ea32e5fc 456 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 457 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
458 mapping->range_begin, mapping->range_end);
459 abort();
460 }
f6a2a8ed 461 if (v64.s >= mapping->range_begin && v64.s <= mapping->range_end) {
79f677ba 462 printf("%s", print_count++ ? ", " : "");
3db2d8a1 463 tracer_print_string(side_ptr_get(mapping->label.p), mapping->label.unit_size, mapping->label.byte_order, NULL);
79f677ba
MD
464 }
465 }
466 if (!print_count)
467 printf("<NO LABEL>");
468 printf(" ]");
469}
470
f6a2a8ed 471static
67337c4a 472void tracer_print_enum(const struct side_type *type_desc, const struct side_arg *item)
f6a2a8ed 473{
64037418 474 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
c5789285 475 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum.elem_type);
f6a2a8ed
MD
476 union int64_value v64;
477
3ce69bfa 478 if (side_enum_get(elem_type->type) != side_enum_get(item->type)) {
f6a2a8ed
MD
479 fprintf(stderr, "ERROR: Unexpected enum element type\n");
480 abort();
481 }
67337c4a
MD
482 v64 = tracer_load_integer_value(&elem_type->u.side_integer,
483 &item->u.side_static.integer_value, 0, NULL);
12d787db 484 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
f6a2a8ed
MD
485 printf("%s", mappings->nr_attr ? ", " : "");
486 tracer_print_type(elem_type, item);
0519cb86 487 print_enum_labels(mappings, v64);
f6a2a8ed
MD
488}
489
ea32e5fc 490static
67337c4a 491uint32_t elem_type_to_stride(const struct side_type *elem_type)
ea32e5fc 492{
af6aa6e1
MD
493 uint32_t stride_bit;
494
3ce69bfa 495 switch (side_enum_get(elem_type->type)) {
67337c4a 496 case SIDE_TYPE_BYTE:
af6aa6e1
MD
497 stride_bit = 8;
498 break;
8625d674 499
67337c4a
MD
500 case SIDE_TYPE_U8:
501 case SIDE_TYPE_U16:
502 case SIDE_TYPE_U32:
503 case SIDE_TYPE_U64:
504 case SIDE_TYPE_S8:
505 case SIDE_TYPE_S16:
506 case SIDE_TYPE_S32:
507 case SIDE_TYPE_S64:
508 return elem_type->u.side_integer.integer_size * CHAR_BIT;
af6aa6e1 509 default:
8625d674 510 fprintf(stderr, "ERROR: Unexpected enum bitmap element type\n");
af6aa6e1
MD
511 abort();
512 }
513 return stride_bit;
514}
515
516static
67337c4a
MD
517void tracer_print_enum_bitmap(const struct side_type *type_desc,
518 const struct side_arg *item)
af6aa6e1 519{
64037418 520 const struct side_enum_bitmap_mappings *side_enum_mappings = side_ptr_get(type_desc->u.side_enum_bitmap.mappings);
c5789285 521 const struct side_type *enum_elem_type = side_ptr_get(type_desc->u.side_enum_bitmap.elem_type), *elem_type;
e65f9ce5 522 uint32_t i, print_count = 0, stride_bit, nr_items;
67337c4a 523 const struct side_arg *array_item;
af6aa6e1 524
3ce69bfa 525 switch (side_enum_get(enum_elem_type->type)) {
67337c4a
MD
526 case SIDE_TYPE_U8: /* Fall-through */
527 case SIDE_TYPE_BYTE: /* Fall-through */
528 case SIDE_TYPE_U16: /* Fall-through */
529 case SIDE_TYPE_U32: /* Fall-through */
530 case SIDE_TYPE_U64: /* Fall-through */
531 case SIDE_TYPE_S8: /* Fall-through */
532 case SIDE_TYPE_S16: /* Fall-through */
533 case SIDE_TYPE_S32: /* Fall-through */
534 case SIDE_TYPE_S64:
7f8e7e97 535 elem_type = enum_elem_type;
af6aa6e1
MD
536 array_item = item;
537 nr_items = 1;
af6aa6e1 538 break;
67337c4a 539 case SIDE_TYPE_ARRAY:
c5789285 540 elem_type = side_ptr_get(enum_elem_type->u.side_array.elem_type);
f13253cb 541 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_array)->sav);
67337c4a 542 nr_items = type_desc->u.side_array.length;
af6aa6e1 543 break;
67337c4a 544 case SIDE_TYPE_VLA:
c5789285 545 elem_type = side_ptr_get(enum_elem_type->u.side_vla.elem_type);
f13253cb 546 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_vla)->sav);
bac71609 547 nr_items = side_ptr_get(item->u.side_static.side_vla)->len;
af6aa6e1
MD
548 break;
549 default:
de1b3cd2 550 fprintf(stderr, "ERROR: Unexpected enum element type\n");
af6aa6e1
MD
551 abort();
552 }
7f8e7e97 553 stride_bit = elem_type_to_stride(elem_type);
ea32e5fc 554
12d787db 555 print_attributes("attr", ":", side_ptr_get(side_enum_mappings->attr), side_enum_mappings->nr_attr);
67337c4a 556 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
af6aa6e1 557 printf("labels: [ ");
67337c4a 558 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
64037418 559 const struct side_enum_bitmap_mapping *mapping = &side_ptr_get(side_enum_mappings->mappings)[i];
ea32e5fc 560 bool match = false;
9ff49ee4 561 uint64_t bit;
ea32e5fc 562
9ff49ee4 563 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 564 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
565 mapping->range_begin, mapping->range_end);
566 abort();
567 }
568 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
af6aa6e1
MD
569 if (bit > (nr_items * stride_bit) - 1)
570 break;
3ce69bfa 571 if (side_enum_get(elem_type->type) == SIDE_TYPE_BYTE) {
67337c4a 572 uint8_t v = array_item[bit / 8].u.side_static.byte_value;
af6aa6e1
MD
573 if (v & (1ULL << (bit % 8))) {
574 match = true;
575 goto match;
576 }
7f8e7e97
MD
577 } else {
578 union int64_value v64;
579
67337c4a
MD
580 v64 = tracer_load_integer_value(&elem_type->u.side_integer,
581 &array_item[bit / stride_bit].u.side_static.integer_value,
7f8e7e97
MD
582 0, NULL);
583 if (v64.u & (1ULL << (bit % stride_bit))) {
af6aa6e1
MD
584 match = true;
585 goto match;
586 }
af6aa6e1 587 }
ea32e5fc 588 }
af6aa6e1 589match:
ea32e5fc
MD
590 if (match) {
591 printf("%s", print_count++ ? ", " : "");
3db2d8a1 592 tracer_print_string(side_ptr_get(mapping->label.p), mapping->label.unit_size, mapping->label.byte_order, NULL);
ea32e5fc
MD
593 }
594 }
595 if (!print_count)
596 printf("<NO LABEL>");
597 printf(" ]");
598}
599
1d9c515c
MD
600static
601void print_integer_binary(uint64_t v, int bits)
602{
603 int i;
604
605 printf("0b");
606 v <<= 64 - bits;
607 for (i = 0; i < bits; i++) {
608 printf("%c", v & (1ULL << 63) ? '1' : '0');
609 v <<= 1;
610 }
611}
612
0e9be766 613static
aac52685 614void tracer_print_type_header(const char *separator,
67337c4a 615 const struct side_attr *attr, uint32_t nr_attr)
ac81c466 616{
aac52685
MD
617 print_attributes("attr", separator, attr, nr_attr);
618 printf("%s", nr_attr ? ", " : "");
619 printf("value%s ", separator);
ac81c466
MD
620}
621
8ad2f385
MD
622static
623void tracer_print_type_bool(const char *separator,
67337c4a
MD
624 const struct side_type_bool *type_bool,
625 const union side_bool_value *value,
8ad2f385
MD
626 uint16_t offset_bits)
627{
88bab79c 628 uint32_t len_bits;
8ad2f385
MD
629 bool reverse_bo;
630 uint64_t v;
631
88bab79c
MD
632 if (!type_bool->len_bits)
633 len_bits = type_bool->bool_size * CHAR_BIT;
634 else
635 len_bits = type_bool->len_bits;
636 if (len_bits + offset_bits > type_bool->bool_size * CHAR_BIT)
8ad2f385 637 abort();
67337c4a 638 reverse_bo = type_bool->byte_order != SIDE_TYPE_BYTE_ORDER_HOST;
88bab79c
MD
639 switch (type_bool->bool_size) {
640 case 1:
67337c4a 641 v = value->side_bool8;
8ad2f385 642 break;
88bab79c 643 case 2:
8ad2f385 644 {
67337c4a 645 uint16_t side_u16;
8ad2f385 646
67337c4a 647 side_u16 = value->side_bool16;
8ad2f385 648 if (reverse_bo)
67337c4a
MD
649 side_u16 = side_bswap_16(side_u16);
650 v = side_u16;
8ad2f385
MD
651 break;
652 }
88bab79c 653 case 4:
8ad2f385 654 {
67337c4a 655 uint32_t side_u32;
8ad2f385 656
67337c4a 657 side_u32 = value->side_bool32;
8ad2f385 658 if (reverse_bo)
67337c4a
MD
659 side_u32 = side_bswap_32(side_u32);
660 v = side_u32;
8ad2f385
MD
661 break;
662 }
88bab79c 663 case 8:
8ad2f385 664 {
67337c4a 665 uint64_t side_u64;
8ad2f385 666
67337c4a 667 side_u64 = value->side_bool64;
8ad2f385 668 if (reverse_bo)
67337c4a
MD
669 side_u64 = side_bswap_64(side_u64);
670 v = side_u64;
8ad2f385
MD
671 break;
672 }
673 default:
674 abort();
675 }
676 v >>= offset_bits;
88bab79c
MD
677 if (len_bits < 64)
678 v &= (1ULL << len_bits) - 1;
db8df9b5 679 tracer_print_type_header(separator, side_ptr_get(type_bool->attr), type_bool->nr_attr);
8ad2f385
MD
680 printf("%s", v ? "true" : "false");
681}
682
4f5e1b67
MD
683static
684void tracer_print_type_integer(const char *separator,
67337c4a
MD
685 const struct side_type_integer *type_integer,
686 const union side_integer_value *value,
4f5e1b67
MD
687 uint16_t offset_bits,
688 enum tracer_display_base default_base)
689{
690 enum tracer_display_base base;
691 union int64_value v64;
692 uint16_t len_bits;
693
694 v64 = tracer_load_integer_value(type_integer, value, offset_bits, &len_bits);
12d787db
MD
695 tracer_print_type_header(separator, side_ptr_get(type_integer->attr), type_integer->nr_attr);
696 base = get_attr_display_base(side_ptr_get(type_integer->attr), type_integer->nr_attr, default_base);
56c21987
MD
697 switch (base) {
698 case TRACER_DISPLAY_BASE_2:
4f5e1b67 699 print_integer_binary(v64.u, len_bits);
56c21987
MD
700 break;
701 case TRACER_DISPLAY_BASE_8:
f6a2a8ed
MD
702 /* Clear sign bits beyond len_bits */
703 if (len_bits < 64)
704 v64.u &= (1ULL << len_bits) - 1;
4f5e1b67 705 printf("0%" PRIo64, v64.u);
56c21987
MD
706 break;
707 case TRACER_DISPLAY_BASE_10:
f6a2a8ed 708 if (type_integer->signedness)
4f5e1b67 709 printf("%" PRId64, v64.s);
f6a2a8ed 710 else
4f5e1b67 711 printf("%" PRIu64, v64.u);
56c21987
MD
712 break;
713 case TRACER_DISPLAY_BASE_16:
f6a2a8ed
MD
714 /* Clear sign bits beyond len_bits */
715 if (len_bits < 64)
716 v64.u &= (1ULL << len_bits) - 1;
4f5e1b67 717 printf("0x%" PRIx64, v64.u);
56c21987
MD
718 break;
719 default:
720 abort();
721 }
722}
723
3aa7ca5e
MD
724static
725void tracer_print_type_float(const char *separator,
67337c4a
MD
726 const struct side_type_float *type_float,
727 const union side_float_value *value)
3aa7ca5e
MD
728{
729 bool reverse_bo;
730
12d787db 731 tracer_print_type_header(separator, side_ptr_get(type_float->attr), type_float->nr_attr);
67337c4a 732 reverse_bo = type_float->byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST;
88bab79c
MD
733 switch (type_float->float_size) {
734 case 2:
3aa7ca5e
MD
735 {
736#if __HAVE_FLOAT16
737 union {
738 _Float16 f;
739 uint16_t u;
740 } float16 = {
67337c4a 741 .f = value->side_float_binary16,
3aa7ca5e
MD
742 };
743
744 if (reverse_bo)
67337c4a 745 float16.u = side_bswap_16(float16.u);
3aa7ca5e
MD
746 printf("%g", (double) float16.f);
747 break;
748#else
749 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
750 abort();
751#endif
752 }
88bab79c 753 case 4:
3aa7ca5e
MD
754 {
755#if __HAVE_FLOAT32
756 union {
757 _Float32 f;
758 uint32_t u;
759 } float32 = {
67337c4a 760 .f = value->side_float_binary32,
3aa7ca5e
MD
761 };
762
763 if (reverse_bo)
67337c4a 764 float32.u = side_bswap_32(float32.u);
3aa7ca5e
MD
765 printf("%g", (double) float32.f);
766 break;
767#else
768 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
769 abort();
770#endif
771 }
88bab79c 772 case 8:
3aa7ca5e
MD
773 {
774#if __HAVE_FLOAT64
775 union {
776 _Float64 f;
777 uint64_t u;
778 } float64 = {
67337c4a 779 .f = value->side_float_binary64,
3aa7ca5e
MD
780 };
781
782 if (reverse_bo)
67337c4a 783 float64.u = side_bswap_64(float64.u);
3aa7ca5e
MD
784 printf("%g", (double) float64.f);
785 break;
786#else
787 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
788 abort();
789#endif
790 }
88bab79c 791 case 16:
3aa7ca5e
MD
792 {
793#if __HAVE_FLOAT128
794 union {
795 _Float128 f;
796 char arr[16];
797 } float128 = {
67337c4a 798 .f = value->side_float_binary128,
3aa7ca5e
MD
799 };
800
801 if (reverse_bo)
67337c4a 802 side_bswap_128p(float128.arr);
3aa7ca5e
MD
803 printf("%Lg", (long double) float128.f);
804 break;
805#else
806 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
807 abort();
808#endif
809 }
810 default:
811 fprintf(stderr, "ERROR: Unknown float size\n");
812 abort();
813 }
814}
815
f611d0c3 816static
67337c4a 817void tracer_print_type(const struct side_type *type_desc, const struct side_arg *item)
f611d0c3 818{
67337c4a 819 enum side_type_label type;
d8be25de 820
3ce69bfa 821 switch (side_enum_get(type_desc->type)) {
67337c4a 822 case SIDE_TYPE_ENUM:
3ce69bfa 823 switch (side_enum_get(item->type)) {
67337c4a
MD
824 case SIDE_TYPE_U8:
825 case SIDE_TYPE_U16:
826 case SIDE_TYPE_U32:
827 case SIDE_TYPE_U64:
828 case SIDE_TYPE_S8:
829 case SIDE_TYPE_S16:
830 case SIDE_TYPE_S32:
831 case SIDE_TYPE_S64:
bab5d6e4
MD
832 break;
833 default:
de1b3cd2 834 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
45392033
MD
835 abort();
836 break;
837 }
838 break;
839
67337c4a 840 case SIDE_TYPE_ENUM_BITMAP:
3ce69bfa 841 switch (side_enum_get(item->type)) {
67337c4a
MD
842 case SIDE_TYPE_U8:
843 case SIDE_TYPE_BYTE:
844 case SIDE_TYPE_U16:
845 case SIDE_TYPE_U32:
846 case SIDE_TYPE_U64:
847 case SIDE_TYPE_ARRAY:
848 case SIDE_TYPE_VLA:
45392033
MD
849 break;
850 default:
de1b3cd2 851 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
45392033
MD
852 abort();
853 break;
d8be25de
MD
854 }
855 break;
856
67337c4a 857 case SIDE_TYPE_GATHER_ENUM:
3ce69bfa 858 switch (side_enum_get(item->type)) {
67337c4a 859 case SIDE_TYPE_GATHER_INTEGER:
0519cb86
MD
860 break;
861 default:
862 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
863 abort();
864 break;
865 }
866 break;
867
67337c4a 868 case SIDE_TYPE_DYNAMIC:
3ce69bfa 869 switch (side_enum_get(item->type)) {
67337c4a
MD
870 case SIDE_TYPE_DYNAMIC_NULL:
871 case SIDE_TYPE_DYNAMIC_BOOL:
872 case SIDE_TYPE_DYNAMIC_INTEGER:
873 case SIDE_TYPE_DYNAMIC_BYTE:
874 case SIDE_TYPE_DYNAMIC_POINTER:
875 case SIDE_TYPE_DYNAMIC_FLOAT:
876 case SIDE_TYPE_DYNAMIC_STRING:
877 case SIDE_TYPE_DYNAMIC_STRUCT:
878 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
879 case SIDE_TYPE_DYNAMIC_VLA:
880 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
66de373e
MD
881 break;
882 default:
883 fprintf(stderr, "ERROR: Unexpected dynamic type\n");
884 abort();
885 break;
886 }
887 break;
888
ba845af5 889 default:
3ce69bfa 890 if (side_enum_get(type_desc->type) != side_enum_get(item->type)) {
de1b3cd2 891 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
ba845af5
MD
892 abort();
893 }
894 break;
f611d0c3 895 }
d8be25de 896
3ce69bfa
MD
897 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)
898 type = side_enum_get(type_desc->type);
d8be25de 899 else
3ce69bfa 900 type = side_enum_get(item->type);
d8be25de 901
a848763d 902 printf("{ ");
d8be25de 903 switch (type) {
55fb50b7 904 /* Stack-copy basic types */
67337c4a 905 case SIDE_TYPE_NULL:
b313067b
MD
906 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_null.attr),
907 type_desc->u.side_null.nr_attr);
9b641221
MD
908 printf("<NULL TYPE>");
909 break;
910
67337c4a
MD
911 case SIDE_TYPE_BOOL:
912 tracer_print_type_bool(":", &type_desc->u.side_bool, &item->u.side_static.bool_value, 0);
4f40d951 913 break;
1d9c515c 914
67337c4a
MD
915 case SIDE_TYPE_U8:
916 case SIDE_TYPE_U16:
917 case SIDE_TYPE_U32:
918 case SIDE_TYPE_U64:
919 case SIDE_TYPE_S8:
920 case SIDE_TYPE_S16:
921 case SIDE_TYPE_S32:
922 case SIDE_TYPE_S64:
923 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0,
f0dafd60 924 TRACER_DISPLAY_BASE_10);
f611d0c3 925 break;
56c21987 926
67337c4a 927 case SIDE_TYPE_BYTE:
12d787db 928 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_byte.attr), type_desc->u.side_byte.nr_attr);
67337c4a 929 printf("0x%" PRIx8, item->u.side_static.byte_value);
7aec0d09 930 break;
79f677ba 931
67337c4a
MD
932 case SIDE_TYPE_POINTER:
933 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0,
55fb50b7 934 TRACER_DISPLAY_BASE_16);
ea32e5fc
MD
935 break;
936
67337c4a
MD
937 case SIDE_TYPE_FLOAT_BINARY16:
938 case SIDE_TYPE_FLOAT_BINARY32:
939 case SIDE_TYPE_FLOAT_BINARY64:
940 case SIDE_TYPE_FLOAT_BINARY128:
941 tracer_print_type_float(":", &type_desc->u.side_float, &item->u.side_static.float_value);
fb25b355 942 break;
3aa7ca5e 943
67337c4a
MD
944 case SIDE_TYPE_STRING_UTF8:
945 case SIDE_TYPE_STRING_UTF16:
946 case SIDE_TYPE_STRING_UTF32:
12d787db 947 tracer_print_type_header(":", side_ptr_get(type_desc->u.side_string.attr), type_desc->u.side_string.nr_attr);
6910c28c 948 tracer_print_string(side_ptr_get(item->u.side_static.string_value),
67337c4a 949 type_desc->u.side_string.unit_size, type_desc->u.side_string.byte_order, NULL);
f611d0c3 950 break;
55fb50b7
MD
951
952 /* Stack-copy compound types */
67337c4a 953 case SIDE_TYPE_STRUCT:
bac71609 954 tracer_print_struct(type_desc, side_ptr_get(item->u.side_static.side_struct));
f611d0c3 955 break;
5530345d 956 case SIDE_TYPE_VARIANT:
bac71609 957 tracer_print_variant(type_desc, side_ptr_get(item->u.side_static.side_variant));
5530345d 958 break;
67337c4a 959 case SIDE_TYPE_ARRAY:
bac71609 960 tracer_print_array(type_desc, side_ptr_get(item->u.side_static.side_array));
d9359cfa 961 break;
67337c4a 962 case SIDE_TYPE_VLA:
bac71609 963 tracer_print_vla(type_desc, side_ptr_get(item->u.side_static.side_vla));
33956c71 964 break;
67337c4a
MD
965 case SIDE_TYPE_VLA_VISITOR:
966 tracer_print_vla_visitor(type_desc, item->u.side_static.side_vla_app_visitor_ctx);
80429681 967 break;
55fb50b7
MD
968
969 /* Stack-copy enumeration types */
67337c4a 970 case SIDE_TYPE_ENUM:
f6a2a8ed 971 tracer_print_enum(type_desc, item);
55fb50b7 972 break;
67337c4a 973 case SIDE_TYPE_ENUM_BITMAP:
7f8e7e97 974 tracer_print_enum_bitmap(type_desc, item);
55fb50b7
MD
975 break;
976
977 /* Gather basic types */
67337c4a 978 case SIDE_TYPE_GATHER_BOOL:
155b1756 979 (void) tracer_print_gather_bool_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_bool_gather_ptr));
8ad2f385 980 break;
67337c4a 981 case SIDE_TYPE_GATHER_INTEGER:
155b1756 982 (void) tracer_print_gather_integer_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr),
55fb50b7
MD
983 TRACER_DISPLAY_BASE_10);
984 break;
67337c4a 985 case SIDE_TYPE_GATHER_BYTE:
155b1756 986 (void) tracer_print_gather_byte_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_byte_gather_ptr));
d69918cc 987 break;
67337c4a 988 case SIDE_TYPE_GATHER_POINTER:
155b1756 989 (void) tracer_print_gather_integer_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr),
4e1b0e0e
MD
990 TRACER_DISPLAY_BASE_16);
991 break;
67337c4a 992 case SIDE_TYPE_GATHER_FLOAT:
155b1756 993 (void) tracer_print_gather_float_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_float_gather_ptr));
905f68e3 994 break;
67337c4a 995 case SIDE_TYPE_GATHER_STRING:
155b1756 996 (void) tracer_print_gather_string_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_string_gather_ptr));
7d34edfc 997 break;
55fb50b7
MD
998
999 /* Gather compound type */
67337c4a 1000 case SIDE_TYPE_GATHER_STRUCT:
155b1756 1001 (void) tracer_print_gather_struct(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_struct_gather_ptr));
f611d0c3 1002 break;
67337c4a 1003 case SIDE_TYPE_GATHER_ARRAY:
155b1756 1004 (void) tracer_print_gather_array(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_array_gather_ptr));
f611d0c3 1005 break;
67337c4a 1006 case SIDE_TYPE_GATHER_VLA:
155b1756
MD
1007 (void) tracer_print_gather_vla(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_vla_gather.ptr),
1008 side_ptr_get(item->u.side_static.side_vla_gather.length_ptr));
f611d0c3 1009 break;
66de373e 1010
0519cb86 1011 /* Gather enumeration types */
67337c4a 1012 case SIDE_TYPE_GATHER_ENUM:
155b1756 1013 (void) tracer_print_gather_enum_type(&type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr));
0519cb86
MD
1014 break;
1015
55fb50b7 1016 /* Dynamic basic types */
67337c4a
MD
1017 case SIDE_TYPE_DYNAMIC_NULL:
1018 case SIDE_TYPE_DYNAMIC_BOOL:
1019 case SIDE_TYPE_DYNAMIC_INTEGER:
1020 case SIDE_TYPE_DYNAMIC_BYTE:
1021 case SIDE_TYPE_DYNAMIC_POINTER:
1022 case SIDE_TYPE_DYNAMIC_FLOAT:
1023 case SIDE_TYPE_DYNAMIC_STRING:
55fb50b7
MD
1024
1025 /* Dynamic compound types */
67337c4a
MD
1026 case SIDE_TYPE_DYNAMIC_STRUCT:
1027 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
1028 case SIDE_TYPE_DYNAMIC_VLA:
1029 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
66de373e 1030 tracer_print_dynamic(item);
a2e2357e 1031 break;
f611d0c3 1032 default:
f6c02218 1033 fprintf(stderr, "<UNKNOWN TYPE>\n");
f611d0c3
MD
1034 abort();
1035 }
a848763d 1036 printf(" }");
f611d0c3
MD
1037}
1038
1039static
67337c4a 1040void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg *item)
f611d0c3 1041{
c5789285 1042 printf("%s: ", side_ptr_get(item_desc->field_name));
67337c4a 1043 tracer_print_type(&item_desc->side_type, item);
f611d0c3
MD
1044}
1045
1046static
67337c4a 1047void tracer_print_struct(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
f611d0c3 1048{
f13253cb 1049 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
c5789285 1050 const struct side_type_struct *side_struct = side_ptr_get(type_desc->u.side_struct);
67337c4a 1051 uint32_t i, side_sav_len = side_arg_vec->len;
f611d0c3 1052
c5789285 1053 if (side_struct->nr_fields != side_sav_len) {
de1b3cd2 1054 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n");
f611d0c3
MD
1055 abort();
1056 }
c5789285
MD
1057 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1058 printf("%s", side_struct->nr_attr ? ", " : "");
73b2b0c2 1059 printf("fields: { ");
67337c4a 1060 for (i = 0; i < side_sav_len; i++) {
f611d0c3 1061 printf("%s", i ? ", " : "");
c5789285 1062 tracer_print_field(&side_ptr_get(side_struct->fields)[i], &sav[i]);
f611d0c3 1063 }
d4328528 1064 printf(" }");
f611d0c3
MD
1065}
1066
5530345d
MD
1067static
1068void tracer_print_variant(const struct side_type *type_desc, const struct side_arg_variant *side_arg_variant)
1069{
c5789285 1070 const struct side_type_variant *side_type_variant = side_ptr_get(type_desc->u.side_variant);
5530345d
MD
1071 const struct side_type *selector_type = &side_type_variant->selector;
1072 union int64_value v64;
1073 uint32_t i;
1074
3ce69bfa 1075 if (side_enum_get(selector_type->type) != side_enum_get(side_arg_variant->selector.type)) {
5530345d
MD
1076 fprintf(stderr, "ERROR: Unexpected variant selector type\n");
1077 abort();
1078 }
3ce69bfa 1079 switch (side_enum_get(selector_type->type)) {
5530345d
MD
1080 case SIDE_TYPE_U8:
1081 case SIDE_TYPE_U16:
1082 case SIDE_TYPE_U32:
1083 case SIDE_TYPE_U64:
1084 case SIDE_TYPE_S8:
1085 case SIDE_TYPE_S16:
1086 case SIDE_TYPE_S32:
1087 case SIDE_TYPE_S64:
1088 break;
1089 default:
1090 fprintf(stderr, "ERROR: Expecting integer variant selector type\n");
1091 abort();
1092 }
1093 v64 = tracer_load_integer_value(&selector_type->u.side_integer,
1094 &side_arg_variant->selector.u.side_static.integer_value, 0, NULL);
1095 for (i = 0; i < side_type_variant->nr_options; i++) {
c5789285 1096 const struct side_variant_option *option = &side_ptr_get(side_type_variant->options)[i];
5530345d
MD
1097
1098 if (v64.s >= option->range_begin && v64.s <= option->range_end) {
1099 tracer_print_type(&option->side_type, &side_arg_variant->option);
1100 return;
1101 }
1102 }
1103 fprintf(stderr, "ERROR: Variant selector value unknown %" PRId64 "\n", v64.s);
1104 abort();
1105}
1106
7a1cb105 1107static
67337c4a 1108void tracer_print_array(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
d9359cfa 1109{
f13253cb 1110 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
67337c4a 1111 uint32_t i, side_sav_len = side_arg_vec->len;
d9359cfa 1112
67337c4a 1113 if (type_desc->u.side_array.length != side_sav_len) {
d9359cfa
MD
1114 fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n");
1115 abort();
1116 }
12d787db 1117 print_attributes("attr", ":", side_ptr_get(type_desc->u.side_array.attr), type_desc->u.side_array.nr_attr);
67337c4a 1118 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
d9359cfa
MD
1119 printf("elements: ");
1120 printf("[ ");
67337c4a 1121 for (i = 0; i < side_sav_len; i++) {
d9359cfa 1122 printf("%s", i ? ", " : "");
c5789285 1123 tracer_print_type(side_ptr_get(type_desc->u.side_array.elem_type), &sav[i]);
d9359cfa
MD
1124 }
1125 printf(" ]");
1126}
1127
1128static
67337c4a 1129void tracer_print_vla(const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec)
d9359cfa 1130{
f13253cb 1131 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
67337c4a 1132 uint32_t i, side_sav_len = side_arg_vec->len;
d9359cfa 1133
12d787db 1134 print_attributes("attr", ":", side_ptr_get(type_desc->u.side_vla.attr), type_desc->u.side_vla.nr_attr);
67337c4a 1135 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
d9359cfa
MD
1136 printf("elements: ");
1137 printf("[ ");
67337c4a 1138 for (i = 0; i < side_sav_len; i++) {
d9359cfa 1139 printf("%s", i ? ", " : "");
c5789285 1140 tracer_print_type(side_ptr_get(type_desc->u.side_vla.elem_type), &sav[i]);
d9359cfa
MD
1141 }
1142 printf(" ]");
1143}
1144
dd7947bf 1145static
67337c4a 1146const char *tracer_gather_access(enum side_type_gather_access_mode access_mode, const char *ptr)
dd7947bf 1147{
65b8734a 1148 switch (access_mode) {
67337c4a 1149 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
dd7947bf 1150 return ptr;
67337c4a 1151 case SIDE_TYPE_GATHER_ACCESS_POINTER:
dd7947bf 1152 /* Dereference pointer */
dc9567a6 1153 memcpy(&ptr, ptr, sizeof(const char *));
dd7947bf
MD
1154 return ptr;
1155 default:
1156 abort();
1157 }
1158}
1159
1160static
67337c4a 1161uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode, uint32_t len)
dd7947bf 1162{
65b8734a 1163 switch (access_mode) {
67337c4a 1164 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
dd7947bf 1165 return len;
67337c4a 1166 case SIDE_TYPE_GATHER_ACCESS_POINTER:
dd7947bf
MD
1167 return sizeof(void *);
1168 default:
1169 abort();
1170 }
1171}
1172
d9359cfa 1173static
67337c4a 1174union int64_value tracer_load_gather_integer_value(const struct side_type_gather_integer *side_integer,
0519cb86 1175 const void *_ptr)
7a1cb105 1176{
67337c4a
MD
1177 enum side_type_gather_access_mode access_mode =
1178 (enum side_type_gather_access_mode) side_integer->access_mode;
1179 uint32_t integer_size_bytes = side_integer->type.integer_size;
7a1cb105 1180 const char *ptr = (const char *) _ptr;
67337c4a 1181 union side_integer_value value;
65b8734a 1182
67337c4a 1183 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
65b8734a 1184 memcpy(&value, ptr, integer_size_bytes);
67337c4a
MD
1185 return tracer_load_integer_value(&side_integer->type, &value,
1186 side_integer->offset_bits, NULL);
65b8734a
MD
1187}
1188
8ad2f385 1189static
67337c4a 1190uint32_t tracer_print_gather_bool_type(const struct side_type_gather *type_gather, const void *_ptr)
8ad2f385 1191{
67337c4a
MD
1192 enum side_type_gather_access_mode access_mode =
1193 (enum side_type_gather_access_mode) type_gather->u.side_bool.access_mode;
1194 uint32_t bool_size_bytes = type_gather->u.side_bool.type.bool_size;
8ad2f385 1195 const char *ptr = (const char *) _ptr;
67337c4a 1196 union side_bool_value value;
8ad2f385 1197
88bab79c
MD
1198 switch (bool_size_bytes) {
1199 case 1:
1200 case 2:
1201 case 4:
8ad2f385 1202 case 8:
8ad2f385
MD
1203 break;
1204 default:
1205 abort();
1206 }
67337c4a 1207 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_bool.offset);
8ad2f385 1208 memcpy(&value, ptr, bool_size_bytes);
67337c4a
MD
1209 tracer_print_type_bool(":", &type_gather->u.side_bool.type, &value,
1210 type_gather->u.side_bool.offset_bits);
8ad2f385
MD
1211 return tracer_gather_size(access_mode, bool_size_bytes);
1212}
1213
d69918cc 1214static
67337c4a 1215uint32_t tracer_print_gather_byte_type(const struct side_type_gather *type_gather, const void *_ptr)
d69918cc 1216{
67337c4a
MD
1217 enum side_type_gather_access_mode access_mode =
1218 (enum side_type_gather_access_mode) type_gather->u.side_byte.access_mode;
d69918cc
MD
1219 const char *ptr = (const char *) _ptr;
1220 uint8_t value;
1221
67337c4a 1222 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_byte.offset);
d69918cc 1223 memcpy(&value, ptr, 1);
12d787db 1224 tracer_print_type_header(":", side_ptr_get(type_gather->u.side_byte.type.attr),
67337c4a 1225 type_gather->u.side_byte.type.nr_attr);
d69918cc
MD
1226 printf("0x%" PRIx8, value);
1227 return tracer_gather_size(access_mode, 1);
1228}
1229
65b8734a 1230static
67337c4a 1231uint32_t tracer_print_gather_integer_type(const struct side_type_gather *type_gather, const void *_ptr,
4e1b0e0e 1232 enum tracer_display_base default_base)
65b8734a 1233{
67337c4a
MD
1234 enum side_type_gather_access_mode access_mode =
1235 (enum side_type_gather_access_mode) type_gather->u.side_integer.access_mode;
1236 uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size;
65b8734a 1237 const char *ptr = (const char *) _ptr;
67337c4a 1238 union side_integer_value value;
7a1cb105 1239
88bab79c
MD
1240 switch (integer_size_bytes) {
1241 case 1:
1242 case 2:
1243 case 4:
33956c71 1244 case 8:
9b641221 1245 break;
33956c71
MD
1246 default:
1247 abort();
1248 }
67337c4a 1249 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset);
dd7947bf 1250 memcpy(&value, ptr, integer_size_bytes);
67337c4a
MD
1251 tracer_print_type_integer(":", &type_gather->u.side_integer.type, &value,
1252 type_gather->u.side_integer.offset_bits, default_base);
d41cb7ee 1253 return tracer_gather_size(access_mode, integer_size_bytes);
33956c71 1254}
9b641221 1255
905f68e3 1256static
67337c4a 1257uint32_t tracer_print_gather_float_type(const struct side_type_gather *type_gather, const void *_ptr)
905f68e3 1258{
67337c4a
MD
1259 enum side_type_gather_access_mode access_mode =
1260 (enum side_type_gather_access_mode) type_gather->u.side_float.access_mode;
1261 uint32_t float_size_bytes = type_gather->u.side_float.type.float_size;
905f68e3 1262 const char *ptr = (const char *) _ptr;
67337c4a 1263 union side_float_value value;
905f68e3 1264
88bab79c
MD
1265 switch (float_size_bytes) {
1266 case 2:
1267 case 4:
1268 case 8:
905f68e3 1269 case 16:
905f68e3
MD
1270 break;
1271 default:
1272 abort();
1273 }
67337c4a 1274 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_float.offset);
dd7947bf 1275 memcpy(&value, ptr, float_size_bytes);
67337c4a 1276 tracer_print_type_float(":", &type_gather->u.side_float.type, &value);
d41cb7ee 1277 return tracer_gather_size(access_mode, float_size_bytes);
905f68e3
MD
1278}
1279
7d34edfc 1280static
67337c4a 1281uint32_t tracer_print_gather_string_type(const struct side_type_gather *type_gather, const void *_ptr)
7d34edfc 1282{
67337c4a
MD
1283 enum side_type_gather_access_mode access_mode =
1284 (enum side_type_gather_access_mode) type_gather->u.side_string.access_mode;
7d34edfc
MD
1285 const char *ptr = (const char *) _ptr;
1286 size_t string_len;
1287
67337c4a 1288 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_string.offset);
12d787db 1289 tracer_print_type_header(":", side_ptr_get(type_gather->u.side_string.type.attr),
67337c4a 1290 type_gather->u.side_string.type.nr_attr);
7d34edfc 1291 if (ptr) {
67337c4a
MD
1292 tracer_print_string(ptr, type_gather->u.side_string.type.unit_size,
1293 type_gather->u.side_string.type.byte_order, &string_len);
7d34edfc
MD
1294 } else {
1295 printf("<NULL>");
67337c4a 1296 string_len = type_gather->u.side_string.type.unit_size;
7d34edfc
MD
1297 }
1298 return tracer_gather_size(access_mode, string_len);
1299}
1300
33956c71 1301static
67337c4a 1302uint32_t tracer_print_gather_type(const struct side_type *type_desc, const void *ptr)
33956c71 1303{
d9359cfa
MD
1304 uint32_t len;
1305
33956c71 1306 printf("{ ");
3ce69bfa 1307 switch (side_enum_get(type_desc->type)) {
55fb50b7 1308 /* Gather basic types */
67337c4a
MD
1309 case SIDE_TYPE_GATHER_BOOL:
1310 len = tracer_print_gather_bool_type(&type_desc->u.side_gather, ptr);
8ad2f385 1311 break;
67337c4a
MD
1312 case SIDE_TYPE_GATHER_INTEGER:
1313 len = tracer_print_gather_integer_type(&type_desc->u.side_gather, ptr,
55fb50b7
MD
1314 TRACER_DISPLAY_BASE_10);
1315 break;
67337c4a
MD
1316 case SIDE_TYPE_GATHER_BYTE:
1317 len = tracer_print_gather_byte_type(&type_desc->u.side_gather, ptr);
d69918cc 1318 break;
67337c4a
MD
1319 case SIDE_TYPE_GATHER_POINTER:
1320 len = tracer_print_gather_integer_type(&type_desc->u.side_gather, ptr,
4e1b0e0e
MD
1321 TRACER_DISPLAY_BASE_16);
1322 break;
67337c4a
MD
1323 case SIDE_TYPE_GATHER_FLOAT:
1324 len = tracer_print_gather_float_type(&type_desc->u.side_gather, ptr);
33956c71 1325 break;
67337c4a
MD
1326 case SIDE_TYPE_GATHER_STRING:
1327 len = tracer_print_gather_string_type(&type_desc->u.side_gather, ptr);
7d34edfc 1328 break;
55fb50b7 1329
0519cb86 1330 /* Gather enum types */
67337c4a
MD
1331 case SIDE_TYPE_GATHER_ENUM:
1332 len = tracer_print_gather_enum_type(&type_desc->u.side_gather, ptr);
0519cb86
MD
1333 break;
1334
55fb50b7 1335 /* Gather compound types */
67337c4a
MD
1336 case SIDE_TYPE_GATHER_STRUCT:
1337 len = tracer_print_gather_struct(&type_desc->u.side_gather, ptr);
d9359cfa 1338 break;
67337c4a
MD
1339 case SIDE_TYPE_GATHER_ARRAY:
1340 len = tracer_print_gather_array(&type_desc->u.side_gather, ptr);
9b641221 1341 break;
67337c4a
MD
1342 case SIDE_TYPE_GATHER_VLA:
1343 len = tracer_print_gather_vla(&type_desc->u.side_gather, ptr, ptr);
65b8734a 1344 break;
9b641221 1345 default:
d41cb7ee 1346 fprintf(stderr, "<UNKNOWN GATHER TYPE>");
9b641221 1347 abort();
7a1cb105
MD
1348 }
1349 printf(" }");
d9359cfa 1350 return len;
7a1cb105
MD
1351}
1352
0519cb86 1353static
67337c4a 1354uint32_t tracer_print_gather_enum_type(const struct side_type_gather *type_gather, const void *_ptr)
0519cb86 1355{
64037418 1356 const struct side_enum_mappings *mappings = side_ptr_get(type_gather->u.side_enum.mappings);
c5789285 1357 const struct side_type *enum_elem_type = side_ptr_get(type_gather->u.side_enum.elem_type);
67337c4a
MD
1358 const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer;
1359 enum side_type_gather_access_mode access_mode =
1360 (enum side_type_gather_access_mode) side_integer->access_mode;
1361 uint32_t integer_size_bytes = side_integer->type.integer_size;
0519cb86 1362 const char *ptr = (const char *) _ptr;
67337c4a 1363 union side_integer_value value;
0519cb86
MD
1364 union int64_value v64;
1365
1366 switch (integer_size_bytes) {
1367 case 1:
1368 case 2:
1369 case 4:
1370 case 8:
1371 break;
1372 default:
1373 abort();
1374 }
67337c4a 1375 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
0519cb86 1376 memcpy(&value, ptr, integer_size_bytes);
67337c4a 1377 v64 = tracer_load_gather_integer_value(side_integer, &value);
12d787db 1378 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
0519cb86
MD
1379 printf("%s", mappings->nr_attr ? ", " : "");
1380 tracer_print_gather_type(enum_elem_type, ptr);
1381 print_enum_labels(mappings, v64);
1382 return tracer_gather_size(access_mode, integer_size_bytes);
1383}
1384
7a1cb105 1385static
67337c4a 1386void tracer_print_gather_field(const struct side_event_field *field, const void *ptr)
7a1cb105 1387{
c5789285 1388 printf("%s: ", side_ptr_get(field->field_name));
67337c4a 1389 (void) tracer_print_gather_type(&field->side_type, ptr);
7a1cb105
MD
1390}
1391
1392static
67337c4a 1393uint32_t tracer_print_gather_struct(const struct side_type_gather *type_gather, const void *_ptr)
7a1cb105 1394{
67337c4a
MD
1395 enum side_type_gather_access_mode access_mode =
1396 (enum side_type_gather_access_mode) type_gather->u.side_struct.access_mode;
c5789285 1397 const struct side_type_struct *side_struct = side_ptr_get(type_gather->u.side_struct.type);
dd7947bf 1398 const char *ptr = (const char *) _ptr;
e65f9ce5 1399 uint32_t i;
7a1cb105 1400
67337c4a 1401 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_struct.offset);
c5789285
MD
1402 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1403 printf("%s", side_struct->nr_attr ? ", " : "");
7a1cb105 1404 printf("fields: { ");
c5789285 1405 for (i = 0; i < side_struct->nr_fields; i++) {
7a1cb105 1406 printf("%s", i ? ", " : "");
c5789285 1407 tracer_print_gather_field(&side_ptr_get(side_struct->fields)[i], ptr);
7a1cb105
MD
1408 }
1409 printf(" }");
67337c4a 1410 return tracer_gather_size(access_mode, type_gather->u.side_struct.size);
7a1cb105
MD
1411}
1412
f611d0c3 1413static
67337c4a 1414uint32_t tracer_print_gather_array(const struct side_type_gather *type_gather, const void *_ptr)
f611d0c3 1415{
67337c4a
MD
1416 enum side_type_gather_access_mode access_mode =
1417 (enum side_type_gather_access_mode) type_gather->u.side_array.access_mode;
dd7947bf 1418 const char *ptr = (const char *) _ptr, *orig_ptr;
d9359cfa 1419 uint32_t i;
f611d0c3 1420
67337c4a 1421 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_array.offset);
65b8734a 1422 orig_ptr = ptr;
12d787db 1423 print_attributes("attr", ":", side_ptr_get(type_gather->u.side_array.type.attr), type_gather->u.side_array.type.nr_attr);
67337c4a 1424 printf("%s", type_gather->u.side_array.type.nr_attr ? ", " : "");
65b8734a
MD
1425 printf("elements: ");
1426 printf("[ ");
67337c4a 1427 for (i = 0; i < type_gather->u.side_array.type.length; i++) {
c5789285
MD
1428 const struct side_type *elem_type = side_ptr_get(type_gather->u.side_array.type.elem_type);
1429
3ce69bfa 1430 switch (side_enum_get(elem_type->type)) {
67337c4a 1431 case SIDE_TYPE_GATHER_VLA:
d41cb7ee 1432 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
65b8734a
MD
1433 abort();
1434 default:
1435 break;
1436 }
1437 printf("%s", i ? ", " : "");
c5789285 1438 ptr += tracer_print_gather_type(elem_type, ptr);
65b8734a
MD
1439 }
1440 printf(" ]");
d41cb7ee 1441 return tracer_gather_size(access_mode, ptr - orig_ptr);
65b8734a
MD
1442}
1443
1444static
67337c4a 1445uint32_t tracer_print_gather_vla(const struct side_type_gather *type_gather, const void *_ptr,
80429681 1446 const void *_length_ptr)
65b8734a 1447{
67337c4a
MD
1448 enum side_type_gather_access_mode access_mode =
1449 (enum side_type_gather_access_mode) type_gather->u.side_vla.access_mode;
c5789285 1450 const struct side_type *length_type = side_ptr_get(type_gather->u.side_vla.length_type);
65b8734a 1451 const char *ptr = (const char *) _ptr, *orig_ptr;
80429681 1452 const char *length_ptr = (const char *) _length_ptr;
4f5e1b67 1453 union int64_value v64;
65b8734a
MD
1454 uint32_t i, length;
1455
1456 /* Access length */
3ce69bfa 1457 switch (side_enum_get(length_type->type)) {
67337c4a 1458 case SIDE_TYPE_GATHER_INTEGER:
65b8734a
MD
1459 break;
1460 default:
d41cb7ee 1461 fprintf(stderr, "<gather VLA expects integer gather length type>\n");
65b8734a
MD
1462 abort();
1463 }
c5789285 1464 v64 = tracer_load_gather_integer_value(&length_type->u.side_gather.u.side_integer,
0519cb86 1465 length_ptr);
4f5e1b67 1466 length = (uint32_t) v64.u;
67337c4a 1467 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_vla.offset);
dd7947bf 1468 orig_ptr = ptr;
12d787db 1469 print_attributes("attr", ":", side_ptr_get(type_gather->u.side_vla.type.attr), type_gather->u.side_vla.type.nr_attr);
67337c4a 1470 printf("%s", type_gather->u.side_vla.type.nr_attr ? ", " : "");
20574104 1471 printf("elements: ");
f611d0c3 1472 printf("[ ");
65b8734a 1473 for (i = 0; i < length; i++) {
c5789285
MD
1474 const struct side_type *elem_type = side_ptr_get(type_gather->u.side_vla.type.elem_type);
1475
3ce69bfa 1476 switch (side_enum_get(elem_type->type)) {
67337c4a 1477 case SIDE_TYPE_GATHER_VLA:
d41cb7ee 1478 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
65b8734a
MD
1479 abort();
1480 default:
1481 break;
1482 }
f611d0c3 1483 printf("%s", i ? ", " : "");
c5789285 1484 ptr += tracer_print_gather_type(elem_type, ptr);
f611d0c3
MD
1485 }
1486 printf(" ]");
d41cb7ee 1487 return tracer_gather_size(access_mode, ptr - orig_ptr);
f611d0c3
MD
1488}
1489
352a4b77 1490struct tracer_visitor_priv {
67337c4a 1491 const struct side_type *elem_type;
352a4b77
MD
1492 int i;
1493};
1494
1495static
67337c4a
MD
1496enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
1497 const struct side_arg *elem)
352a4b77 1498{
e65f9ce5 1499 struct tracer_visitor_priv *tracer_priv = (struct tracer_visitor_priv *) tracer_ctx->priv;
352a4b77
MD
1500
1501 printf("%s", tracer_priv->i++ ? ", " : "");
1502 tracer_print_type(tracer_priv->elem_type, elem);
67337c4a 1503 return SIDE_VISITOR_STATUS_OK;
352a4b77
MD
1504}
1505
f611d0c3 1506static
67337c4a 1507void tracer_print_vla_visitor(const struct side_type *type_desc, void *app_ctx)
f611d0c3 1508{
67337c4a 1509 enum side_visitor_status status;
352a4b77 1510 struct tracer_visitor_priv tracer_priv = {
c5789285 1511 .elem_type = side_ptr_get(type_desc->u.side_vla_visitor.elem_type),
352a4b77
MD
1512 .i = 0,
1513 };
67337c4a 1514 const struct side_tracer_visitor_ctx tracer_ctx = {
352a4b77
MD
1515 .write_elem = tracer_write_elem_cb,
1516 .priv = &tracer_priv,
1517 };
f611d0c3 1518
12d787db 1519 print_attributes("attr", ":", side_ptr_get(type_desc->u.side_vla_visitor.attr), type_desc->u.side_vla_visitor.nr_attr);
67337c4a 1520 printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : "");
20574104 1521 printf("elements: ");
352a4b77 1522 printf("[ ");
67337c4a 1523 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
352a4b77 1524 switch (status) {
67337c4a 1525 case SIDE_VISITOR_STATUS_OK:
352a4b77 1526 break;
67337c4a 1527 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1528 fprintf(stderr, "ERROR: Visitor error\n");
f611d0c3 1529 abort();
f611d0c3
MD
1530 }
1531 printf(" ]");
f611d0c3
MD
1532}
1533
a2e2357e 1534static
67337c4a 1535void tracer_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct)
a2e2357e 1536{
f13253cb 1537 const struct side_arg_dynamic_field *fields = side_ptr_get(dynamic_struct->fields);
e65f9ce5 1538 uint32_t i, len = dynamic_struct->len;
465e5e7e 1539
12d787db 1540 print_attributes("attr", "::", side_ptr_get(dynamic_struct->attr), dynamic_struct->nr_attr);
8d20e708 1541 printf("%s", dynamic_struct->nr_attr ? ", " : "");
f0061366 1542 printf("fields:: ");
465e5e7e
MD
1543 printf("[ ");
1544 for (i = 0; i < len; i++) {
1545 printf("%s", i ? ", " : "");
f13253cb 1546 printf("%s:: ", side_ptr_get(fields[i].field_name));
465e5e7e
MD
1547 tracer_print_dynamic(&fields[i].elem);
1548 }
1549 printf(" ]");
a2e2357e
MD
1550}
1551
2b359235
MD
1552struct tracer_dynamic_struct_visitor_priv {
1553 int i;
1554};
1555
1556static
67337c4a
MD
1557enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
1558 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
1559 const struct side_arg_dynamic_field *dynamic_field)
2b359235 1560{
e65f9ce5
MD
1561 struct tracer_dynamic_struct_visitor_priv *tracer_priv =
1562 (struct tracer_dynamic_struct_visitor_priv *) tracer_ctx->priv;
2b359235
MD
1563
1564 printf("%s", tracer_priv->i++ ? ", " : "");
f13253cb 1565 printf("%s:: ", side_ptr_get(dynamic_field->field_name));
2b359235 1566 tracer_print_dynamic(&dynamic_field->elem);
67337c4a 1567 return SIDE_VISITOR_STATUS_OK;
2b359235
MD
1568}
1569
a2e2357e 1570static
67337c4a 1571void tracer_print_dynamic_struct_visitor(const struct side_arg *item)
a2e2357e 1572{
67337c4a 1573 enum side_visitor_status status;
2b359235
MD
1574 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
1575 .i = 0,
1576 };
67337c4a 1577 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
2b359235
MD
1578 .write_field = tracer_dynamic_struct_write_elem_cb,
1579 .priv = &tracer_priv,
1580 };
67337c4a 1581 void *app_ctx = item->u.side_dynamic.side_dynamic_struct_visitor.app_ctx;
2b359235 1582
12d787db 1583 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 1584 printf("%s", item->u.side_dynamic.side_dynamic_struct_visitor.nr_attr ? ", " : "");
f0061366 1585 printf("fields:: ");
2b359235 1586 printf("[ ");
67337c4a 1587 status = item->u.side_dynamic.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
2b359235 1588 switch (status) {
67337c4a 1589 case SIDE_VISITOR_STATUS_OK:
2b359235 1590 break;
67337c4a 1591 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1592 fprintf(stderr, "ERROR: Visitor error\n");
2b359235
MD
1593 abort();
1594 }
1595 printf(" ]");
a2e2357e
MD
1596}
1597
1598static
67337c4a 1599void tracer_print_dynamic_vla(const struct side_arg_dynamic_vla *vla)
a2e2357e 1600{
f13253cb 1601 const struct side_arg *sav = side_ptr_get(vla->sav);
67337c4a 1602 uint32_t i, side_sav_len = vla->len;
a2e2357e 1603
12d787db 1604 print_attributes("attr", "::", side_ptr_get(vla->attr), vla->nr_attr);
8d20e708 1605 printf("%s", vla->nr_attr ? ", " : "");
f0061366 1606 printf("elements:: ");
a2e2357e 1607 printf("[ ");
67337c4a 1608 for (i = 0; i < side_sav_len; i++) {
a2e2357e
MD
1609 printf("%s", i ? ", " : "");
1610 tracer_print_dynamic(&sav[i]);
1611 }
1612 printf(" ]");
1613}
1614
8ceca0cd
MD
1615struct tracer_dynamic_vla_visitor_priv {
1616 int i;
1617};
1618
1619static
67337c4a
MD
1620enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
1621 const struct side_tracer_visitor_ctx *tracer_ctx,
1622 const struct side_arg *elem)
8ceca0cd 1623{
e65f9ce5
MD
1624 struct tracer_dynamic_vla_visitor_priv *tracer_priv =
1625 (struct tracer_dynamic_vla_visitor_priv *) tracer_ctx->priv;
8ceca0cd
MD
1626
1627 printf("%s", tracer_priv->i++ ? ", " : "");
1628 tracer_print_dynamic(elem);
67337c4a 1629 return SIDE_VISITOR_STATUS_OK;
8ceca0cd
MD
1630}
1631
a2e2357e 1632static
67337c4a 1633void tracer_print_dynamic_vla_visitor(const struct side_arg *item)
a2e2357e 1634{
67337c4a 1635 enum side_visitor_status status;
8ceca0cd
MD
1636 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
1637 .i = 0,
1638 };
67337c4a 1639 const struct side_tracer_visitor_ctx tracer_ctx = {
8ceca0cd
MD
1640 .write_elem = tracer_dynamic_vla_write_elem_cb,
1641 .priv = &tracer_priv,
1642 };
67337c4a 1643 void *app_ctx = item->u.side_dynamic.side_dynamic_vla_visitor.app_ctx;
8ceca0cd 1644
12d787db 1645 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 1646 printf("%s", item->u.side_dynamic.side_dynamic_vla_visitor.nr_attr ? ", " : "");
f0061366 1647 printf("elements:: ");
8ceca0cd 1648 printf("[ ");
67337c4a 1649 status = item->u.side_dynamic.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
8ceca0cd 1650 switch (status) {
67337c4a 1651 case SIDE_VISITOR_STATUS_OK:
8ceca0cd 1652 break;
67337c4a 1653 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1654 fprintf(stderr, "ERROR: Visitor error\n");
8ceca0cd
MD
1655 abort();
1656 }
1657 printf(" ]");
a2e2357e
MD
1658}
1659
1660static
67337c4a 1661void tracer_print_dynamic(const struct side_arg *item)
a2e2357e 1662{
808bd9bf 1663 printf("{ ");
3ce69bfa 1664 switch (side_enum_get(item->type)) {
55fb50b7 1665 /* Dynamic basic types */
67337c4a 1666 case SIDE_TYPE_DYNAMIC_NULL:
b313067b
MD
1667 tracer_print_type_header("::", side_ptr_get(item->u.side_dynamic.side_null.attr),
1668 item->u.side_dynamic.side_null.nr_attr);
a2e2357e
MD
1669 printf("<NULL TYPE>");
1670 break;
67337c4a
MD
1671 case SIDE_TYPE_DYNAMIC_BOOL:
1672 tracer_print_type_bool("::", &item->u.side_dynamic.side_bool.type, &item->u.side_dynamic.side_bool.value, 0);
66de373e 1673 break;
67337c4a
MD
1674 case SIDE_TYPE_DYNAMIC_INTEGER:
1675 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
f0dafd60 1676 TRACER_DISPLAY_BASE_10);
a2e2357e 1677 break;
67337c4a 1678 case SIDE_TYPE_DYNAMIC_BYTE:
12d787db 1679 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 1680 printf("0x%" PRIx8, item->u.side_dynamic.side_byte.value);
199e7aa9 1681 break;
67337c4a
MD
1682 case SIDE_TYPE_DYNAMIC_POINTER:
1683 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
f0dafd60 1684 TRACER_DISPLAY_BASE_16);
f5e650d7 1685 break;
67337c4a
MD
1686 case SIDE_TYPE_DYNAMIC_FLOAT:
1687 tracer_print_type_float("::", &item->u.side_dynamic.side_float.type,
1688 &item->u.side_dynamic.side_float.value);
fb25b355 1689 break;
67337c4a 1690 case SIDE_TYPE_DYNAMIC_STRING:
12d787db 1691 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
1692 tracer_print_string((const char *)(uintptr_t) item->u.side_dynamic.side_string.value,
1693 item->u.side_dynamic.side_string.type.unit_size,
1694 item->u.side_dynamic.side_string.type.byte_order, NULL);
a2e2357e 1695 break;
55fb50b7
MD
1696
1697 /* Dynamic compound types */
67337c4a 1698 case SIDE_TYPE_DYNAMIC_STRUCT:
f13253cb 1699 tracer_print_dynamic_struct(side_ptr_get(item->u.side_dynamic.side_dynamic_struct));
a2e2357e 1700 break;
67337c4a 1701 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
c208889e 1702 tracer_print_dynamic_struct_visitor(item);
a2e2357e 1703 break;
67337c4a 1704 case SIDE_TYPE_DYNAMIC_VLA:
f13253cb 1705 tracer_print_dynamic_vla(side_ptr_get(item->u.side_dynamic.side_dynamic_vla));
a2e2357e 1706 break;
67337c4a 1707 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
a2e2357e
MD
1708 tracer_print_dynamic_vla_visitor(item);
1709 break;
1710 default:
f6c02218 1711 fprintf(stderr, "<UNKNOWN TYPE>\n");
a2e2357e
MD
1712 abort();
1713 }
808bd9bf 1714 printf(" }");
a2e2357e
MD
1715}
1716
68f8cfbe 1717static
67337c4a
MD
1718void tracer_print_static_fields(const struct side_event_description *desc,
1719 const struct side_arg_vec *side_arg_vec,
e65f9ce5 1720 uint32_t *nr_items)
f611d0c3 1721{
f13253cb 1722 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
67337c4a 1723 uint32_t i, side_sav_len = side_arg_vec->len;
f611d0c3 1724
0b9e59d6 1725 printf("provider: %s, event: %s", side_ptr_get(desc->provider_name), side_ptr_get(desc->event_name));
67337c4a 1726 if (desc->nr_fields != side_sav_len) {
de1b3cd2 1727 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
f611d0c3
MD
1728 abort();
1729 }
12d787db 1730 print_attributes(", attr", ":", side_ptr_get(desc->attr), desc->nr_attr);
67337c4a
MD
1731 printf("%s", side_sav_len ? ", fields: [ " : "");
1732 for (i = 0; i < side_sav_len; i++) {
f611d0c3 1733 printf("%s", i ? ", " : "");
0b9e59d6 1734 tracer_print_field(&side_ptr_get(desc->fields)[i], &sav[i]);
f611d0c3 1735 }
68f8cfbe
MD
1736 if (nr_items)
1737 *nr_items = i;
67337c4a 1738 if (side_sav_len)
c7d338e2 1739 printf(" ]");
68f8cfbe
MD
1740}
1741
9365e936 1742static
67337c4a
MD
1743void tracer_call(const struct side_event_description *desc,
1744 const struct side_arg_vec *side_arg_vec,
4a7d8700 1745 void *priv __attribute__((unused)))
68f8cfbe 1746{
e65f9ce5 1747 uint32_t nr_fields = 0;
a848763d 1748
67337c4a 1749 tracer_print_static_fields(desc, side_arg_vec, &nr_fields);
f611d0c3
MD
1750 printf("\n");
1751}
19fa6aa2 1752
9365e936 1753static
67337c4a
MD
1754void tracer_call_variadic(const struct side_event_description *desc,
1755 const struct side_arg_vec *side_arg_vec,
1756 const struct side_arg_dynamic_struct *var_struct,
4a7d8700 1757 void *priv __attribute__((unused)))
19fa6aa2 1758{
e65f9ce5 1759 uint32_t nr_fields = 0, i, var_struct_len = var_struct->len;
19fa6aa2 1760
67337c4a 1761 tracer_print_static_fields(desc, side_arg_vec, &nr_fields);
68f8cfbe 1762
67337c4a 1763 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
de1b3cd2 1764 fprintf(stderr, "ERROR: unexpected non-variadic event description\n");
8a25ce77
MD
1765 abort();
1766 }
12d787db 1767 print_attributes(", attr ", "::", side_ptr_get(var_struct->attr), var_struct->nr_attr);
905c328e 1768 printf("%s", var_struct_len ? ", fields:: [ " : "");
68f8cfbe 1769 for (i = 0; i < var_struct_len; i++, nr_fields++) {
c7d338e2 1770 printf("%s", i ? ", " : "");
f13253cb
MD
1771 printf("%s:: ", side_ptr_get(side_ptr_get(var_struct->fields)[i].field_name));
1772 tracer_print_dynamic(&side_ptr_get(var_struct->fields)[i].elem);
19fa6aa2 1773 }
a848763d
MD
1774 if (i)
1775 printf(" ]");
19fa6aa2
MD
1776 printf("\n");
1777}
1e8aec23 1778
9365e936 1779static
67337c4a
MD
1780void tracer_event_notification(enum side_tracer_notification notif,
1781 struct side_event_description **events, uint32_t nr_events,
9365e936 1782 void *priv __attribute__((unused)))
1e8aec23
MD
1783{
1784 uint32_t i;
314c22c3 1785 int ret;
1e8aec23
MD
1786
1787 printf("----------------------------------------------------------\n");
1788 printf("Tracer notified of events %s\n",
67337c4a 1789 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1e8aec23 1790 for (i = 0; i < nr_events; i++) {
67337c4a 1791 struct side_event_description *event = events[i];
1e8aec23
MD
1792
1793 /* Skip NULL pointers */
1794 if (!event)
1795 continue;
1796 printf("provider: %s, event: %s\n",
0b9e59d6 1797 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
78dd4cc3 1798 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
67337c4a
MD
1799 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1800 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL);
314c22c3
MD
1801 if (ret)
1802 abort();
1803 } else {
67337c4a 1804 ret = side_tracer_callback_register(event, tracer_call, NULL);
314c22c3
MD
1805 if (ret)
1806 abort();
1807 }
1808 } else {
67337c4a
MD
1809 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1810 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL);
314c22c3
MD
1811 if (ret)
1812 abort();
1813 } else {
67337c4a 1814 ret = side_tracer_callback_unregister(event, tracer_call, NULL);
314c22c3
MD
1815 if (ret)
1816 abort();
1817 }
1818 }
1e8aec23
MD
1819 }
1820 printf("----------------------------------------------------------\n");
1821}
1822
1823static __attribute__((constructor))
1824void tracer_init(void);
1825static
1826void tracer_init(void)
1827{
67337c4a 1828 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1e8aec23
MD
1829 if (!tracer_handle)
1830 abort();
1831}
1832
1833static __attribute__((destructor))
1834void tracer_exit(void);
1835static
1836void tracer_exit(void)
1837{
67337c4a 1838 side_tracer_event_notification_unregister(tracer_handle);
1e8aec23 1839}
This page took 0.13877 seconds and 4 git commands to generate.