Use uint64_t for string pointer
[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>
f611d0c3
MD
11
12#include <side/trace.h>
13
1e8aec23
MD
14static struct side_tracer_handle *tracer_handle;
15
f611d0c3
MD
16static
17void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
18static
19void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
20static
21void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
22static
352a4b77 23void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx);
ba845af5
MD
24static
25void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
1533629f
MD
26static
27void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
a2e2357e
MD
28static
29void tracer_print_dynamic(const struct side_arg_dynamic_vec *dynamic_item);
d8be25de
MD
30static
31void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item);
f611d0c3 32
8bdd5c12
MD
33static
34bool type_to_host_reverse_bo(const struct side_type_description *type_desc)
35{
36 switch (type_desc->type) {
37 case SIDE_TYPE_U8:
38 case SIDE_TYPE_S8:
39 case SIDE_TYPE_BYTE:
40 return false;
41 case SIDE_TYPE_U16:
42 case SIDE_TYPE_U32:
43 case SIDE_TYPE_U64:
44 case SIDE_TYPE_S16:
45 case SIDE_TYPE_S32:
46 case SIDE_TYPE_S64:
dd6e76cb
MD
47 case SIDE_TYPE_POINTER32:
48 case SIDE_TYPE_POINTER64:
8bdd5c12
MD
49 if (type_desc->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST)
50 return true;
51 else
52 return false;
53 break;
54 case SIDE_TYPE_FLOAT_BINARY16:
55 case SIDE_TYPE_FLOAT_BINARY32:
56 case SIDE_TYPE_FLOAT_BINARY64:
57 case SIDE_TYPE_FLOAT_BINARY128:
58 if (type_desc->u.side_basic.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST)
59 return true;
60 else
61 return false;
62 break;
63 default:
64 fprintf(stderr, "Unexpected type\n");
65 abort();
66 }
67}
68
69static
70bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec *item)
71{
72 switch (item->dynamic_type) {
73 case SIDE_DYNAMIC_TYPE_U8:
74 case SIDE_DYNAMIC_TYPE_S8:
75 case SIDE_DYNAMIC_TYPE_BYTE:
76 return false;
77 case SIDE_DYNAMIC_TYPE_U16:
78 case SIDE_DYNAMIC_TYPE_U32:
79 case SIDE_DYNAMIC_TYPE_U64:
80 case SIDE_DYNAMIC_TYPE_S16:
81 case SIDE_DYNAMIC_TYPE_S32:
82 case SIDE_DYNAMIC_TYPE_S64:
dd6e76cb
MD
83 case SIDE_DYNAMIC_TYPE_POINTER32:
84 case SIDE_DYNAMIC_TYPE_POINTER64:
8bdd5c12
MD
85 if (item->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST)
86 return true;
87 else
88 return false;
89 break;
90 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
91 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
92 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
93 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
94 if (item->u.side_basic.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST)
95 return true;
96 else
97 return false;
98 break;
99 default:
100 fprintf(stderr, "Unexpected type\n");
101 abort();
102 }
103}
104
bc3c89b3 105static
905c328e 106void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
bc3c89b3 107{
905c328e 108 printf("{ key%s \"%s\", value%s ", separator, attr->key, separator);
bc3c89b3
MD
109 switch (attr->value.type) {
110 case SIDE_ATTR_TYPE_BOOL:
111 printf("%s", attr->value.u.side_bool ? "true" : "false");
112 break;
113 case SIDE_ATTR_TYPE_U8:
114 printf("%" PRIu8, attr->value.u.side_u8);
115 break;
116 case SIDE_ATTR_TYPE_U16:
117 printf("%" PRIu16, attr->value.u.side_u16);
118 break;
119 case SIDE_ATTR_TYPE_U32:
120 printf("%" PRIu32, attr->value.u.side_u32);
121 break;
122 case SIDE_ATTR_TYPE_U64:
123 printf("%" PRIu64, attr->value.u.side_u64);
124 break;
125 case SIDE_ATTR_TYPE_S8:
126 printf("%" PRId8, attr->value.u.side_s8);
127 break;
128 case SIDE_ATTR_TYPE_S16:
129 printf("%" PRId16, attr->value.u.side_s16);
130 break;
131 case SIDE_ATTR_TYPE_S32:
132 printf("%" PRId32, attr->value.u.side_s32);
133 break;
134 case SIDE_ATTR_TYPE_S64:
135 printf("%" PRId64, attr->value.u.side_s64);
136 break;
dd6e76cb
MD
137 case SIDE_ATTR_TYPE_POINTER32:
138 printf("0x%" PRIx32, attr->value.u.side_u32);
139 break;
140 case SIDE_ATTR_TYPE_POINTER64:
141 printf("0x%" PRIx64, attr->value.u.side_u64);
f5e650d7 142 break;
bc3c89b3
MD
143 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
144#if __HAVE_FLOAT16
145 printf("%g", (double) attr->value.u.side_float_binary16);
146 break;
147#else
de1b3cd2 148 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
bc3c89b3
MD
149 abort();
150#endif
151 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
152#if __HAVE_FLOAT32
153 printf("%g", (double) attr->value.u.side_float_binary32);
154 break;
155#else
de1b3cd2 156 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
bc3c89b3
MD
157 abort();
158#endif
159 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
160#if __HAVE_FLOAT64
161 printf("%g", (double) attr->value.u.side_float_binary64);
162 break;
163#else
de1b3cd2 164 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
bc3c89b3
MD
165 abort();
166#endif
167 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
168#if __HAVE_FLOAT128
169 printf("%Lg", (long double) attr->value.u.side_float_binary128);
170 break;
171#else
de1b3cd2 172 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
bc3c89b3
MD
173 abort();
174#endif
175 case SIDE_ATTR_TYPE_STRING:
8549e629 176 printf("\"%s\"", (const char *)(uintptr_t) attr->value.u.string);
bc3c89b3
MD
177 break;
178 default:
de1b3cd2 179 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
bc3c89b3
MD
180 abort();
181 }
182 printf(" }");
183}
184
7d21cf51 185static
905c328e
MD
186void print_attributes(const char *prefix_str, const char *separator,
187 const struct side_attr *attr, uint32_t nr_attr)
7d21cf51
MD
188{
189 int i;
190
191 if (!nr_attr)
192 return;
905c328e 193 printf("%s%s [ ", prefix_str, separator);
7d21cf51
MD
194 for (i = 0; i < nr_attr; i++) {
195 printf("%s", i ? ", " : "");
905c328e 196 tracer_print_attr_type(separator, &attr[i]);
7d21cf51
MD
197 }
198 printf(" ]");
199}
200
79f677ba 201static
d8be25de 202void print_enum(const struct side_type_description *type_desc, const struct side_arg_vec *item)
79f677ba 203{
d8be25de 204 const struct side_enum_mappings *mappings = type_desc->u.side_enum.mappings;
8bdd5c12 205 const struct side_type_description *elem_type = type_desc->u.side_enum.elem_type;
79f677ba 206 int i, print_count = 0;
d8be25de 207 int64_t value;
79f677ba 208
8bdd5c12 209 if (elem_type->type != item->type) {
de1b3cd2 210 fprintf(stderr, "ERROR: Unexpected enum element type\n");
d8be25de
MD
211 abort();
212 }
213 switch (item->type) {
214 case SIDE_TYPE_U8:
215 value = (int64_t) item->u.side_u8;
216 break;
217 case SIDE_TYPE_U16:
8bdd5c12
MD
218 {
219 uint16_t v;
220
221 v = item->u.side_u16;
222 if (type_to_host_reverse_bo(elem_type))
223 v = side_bswap_16(v);
224 value = (int64_t) v;
d8be25de 225 break;
8bdd5c12 226 }
d8be25de 227 case SIDE_TYPE_U32:
8bdd5c12
MD
228 {
229 uint32_t v;
230
231 v = item->u.side_u32;
232 if (type_to_host_reverse_bo(elem_type))
233 v = side_bswap_32(v);
234 value = (int64_t) v;
d8be25de 235 break;
8bdd5c12 236 }
d8be25de 237 case SIDE_TYPE_U64:
8bdd5c12
MD
238 {
239 uint64_t v;
240
241 v = item->u.side_u64;
242 if (type_to_host_reverse_bo(elem_type))
243 v = side_bswap_64(v);
244 value = (int64_t) v;
d8be25de 245 break;
8bdd5c12 246 }
d8be25de
MD
247 case SIDE_TYPE_S8:
248 value = (int64_t) item->u.side_s8;
249 break;
250 case SIDE_TYPE_S16:
8bdd5c12
MD
251 {
252 int16_t v;
253
254 v = item->u.side_s16;
255 if (type_to_host_reverse_bo(elem_type))
256 v = side_bswap_16(v);
257 value = (int64_t) v;
d8be25de 258 break;
8bdd5c12 259 }
d8be25de 260 case SIDE_TYPE_S32:
8bdd5c12
MD
261 {
262 int32_t v;
263
264 v = item->u.side_s32;
265 if (type_to_host_reverse_bo(elem_type))
266 v = side_bswap_32(v);
267 value = (int64_t) v;
d8be25de 268 break;
8bdd5c12 269 }
d8be25de 270 case SIDE_TYPE_S64:
8bdd5c12
MD
271 {
272 int64_t v;
273
274 v = item->u.side_s64;
275 if (type_to_host_reverse_bo(elem_type))
276 v = side_bswap_64(v);
277 value = v;
d8be25de 278 break;
8bdd5c12 279 }
d8be25de 280 default:
de1b3cd2 281 fprintf(stderr, "ERROR: Unexpected enum element type\n");
d8be25de
MD
282 abort();
283 }
905c328e 284 print_attributes("attr", ":", mappings->attr, mappings->nr_attr);
d8be25de
MD
285 printf("%s", mappings->nr_attr ? ", " : "");
286 tracer_print_type(type_desc->u.side_enum.elem_type, item);
287 printf(", labels: [ ");
288 for (i = 0; i < mappings->nr_mappings; i++) {
289 const struct side_enum_mapping *mapping = &mappings->mappings[i];
79f677ba 290
ea32e5fc 291 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 292 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
293 mapping->range_begin, mapping->range_end);
294 abort();
295 }
79f677ba
MD
296 if (value >= mapping->range_begin && value <= mapping->range_end) {
297 printf("%s", print_count++ ? ", " : "");
298 printf("\"%s\"", mapping->label);
299 }
300 }
301 if (!print_count)
302 printf("<NO LABEL>");
303 printf(" ]");
304}
305
ea32e5fc 306static
bab5d6e4 307uint32_t enum_elem_type_to_stride(const struct side_type_description *elem_type)
ea32e5fc 308{
af6aa6e1
MD
309 uint32_t stride_bit;
310
bab5d6e4 311 switch (elem_type->type) {
4cc2880b
MD
312 case SIDE_TYPE_U8: /* Fall-through */
313 case SIDE_TYPE_BYTE:
af6aa6e1
MD
314 stride_bit = 8;
315 break;
af6aa6e1 316 case SIDE_TYPE_U16:
af6aa6e1
MD
317 stride_bit = 16;
318 break;
af6aa6e1 319 case SIDE_TYPE_U32:
af6aa6e1
MD
320 stride_bit = 32;
321 break;
af6aa6e1 322 case SIDE_TYPE_U64:
af6aa6e1
MD
323 stride_bit = 64;
324 break;
af6aa6e1 325 default:
de1b3cd2 326 fprintf(stderr, "ERROR: Unexpected enum element type\n");
af6aa6e1
MD
327 abort();
328 }
329 return stride_bit;
330}
331
332static
333void print_enum_bitmap(const struct side_type_description *type_desc,
334 const struct side_arg_vec *item)
335{
bab5d6e4
MD
336 const struct side_type_description *elem_type = type_desc->u.side_enum_bitmap.elem_type;
337 const struct side_enum_bitmap_mappings *side_enum_mappings = type_desc->u.side_enum_bitmap.mappings;
ea32e5fc 338 int i, print_count = 0;
af6aa6e1 339 uint32_t stride_bit, nr_items;
8bdd5c12 340 bool reverse_byte_order = false;
af6aa6e1
MD
341 const struct side_arg_vec *array_item;
342
bab5d6e4
MD
343 switch (elem_type->type) {
344 case SIDE_TYPE_U8: /* Fall-through */
4cc2880b 345 case SIDE_TYPE_BYTE: /* Fall-through */
bab5d6e4
MD
346 case SIDE_TYPE_U16: /* Fall-through */
347 case SIDE_TYPE_U32: /* Fall-through */
4cc2880b 348 case SIDE_TYPE_U64:
45392033 349 stride_bit = enum_elem_type_to_stride(elem_type);
8bdd5c12 350 reverse_byte_order = type_to_host_reverse_bo(elem_type);
af6aa6e1
MD
351 array_item = item;
352 nr_items = 1;
af6aa6e1 353 break;
bab5d6e4 354 case SIDE_TYPE_ARRAY:
45392033 355 stride_bit = enum_elem_type_to_stride(elem_type->u.side_array.elem_type);
8bdd5c12 356 reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_array.elem_type);
af6aa6e1 357 array_item = item->u.side_array->sav;
bab5d6e4 358 nr_items = type_desc->u.side_array.length;
af6aa6e1 359 break;
bab5d6e4 360 case SIDE_TYPE_VLA:
45392033 361 stride_bit = enum_elem_type_to_stride(elem_type->u.side_vla.elem_type);
8bdd5c12 362 reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_vla.elem_type);
af6aa6e1 363 array_item = item->u.side_vla->sav;
bab5d6e4 364 nr_items = item->u.side_vla->len;
af6aa6e1
MD
365 break;
366 default:
de1b3cd2 367 fprintf(stderr, "ERROR: Unexpected enum element type\n");
af6aa6e1
MD
368 abort();
369 }
ea32e5fc 370
905c328e 371 print_attributes("attr", ":", side_enum_mappings->attr, side_enum_mappings->nr_attr);
d4328528 372 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
af6aa6e1 373 printf("labels: [ ");
ea32e5fc 374 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
66cff328 375 const struct side_enum_bitmap_mapping *mapping = &side_enum_mappings->mappings[i];
ea32e5fc 376 bool match = false;
9ff49ee4 377 uint64_t bit;
ea32e5fc 378
9ff49ee4 379 if (mapping->range_end < mapping->range_begin) {
de1b3cd2 380 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
ea32e5fc
MD
381 mapping->range_begin, mapping->range_end);
382 abort();
383 }
384 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
af6aa6e1
MD
385 if (bit > (nr_items * stride_bit) - 1)
386 break;
387 switch (stride_bit) {
388 case 8:
389 {
390 uint8_t v = array_item[bit / 8].u.side_u8;
391 if (v & (1ULL << (bit % 8))) {
392 match = true;
393 goto match;
394 }
395 break;
396 }
397 case 16:
398 {
399 uint16_t v = array_item[bit / 16].u.side_u16;
8bdd5c12
MD
400 if (reverse_byte_order)
401 v = side_bswap_16(v);
af6aa6e1
MD
402 if (v & (1ULL << (bit % 16))) {
403 match = true;
404 goto match;
405 }
406 break;
407 }
408 case 32:
409 {
410 uint32_t v = array_item[bit / 32].u.side_u32;
8bdd5c12
MD
411 if (reverse_byte_order)
412 v = side_bswap_32(v);
af6aa6e1
MD
413 if (v & (1ULL << (bit % 32))) {
414 match = true;
415 goto match;
416 }
ea32e5fc
MD
417 break;
418 }
af6aa6e1
MD
419 case 64:
420 {
421 uint64_t v = array_item[bit / 64].u.side_u64;
8bdd5c12
MD
422 if (reverse_byte_order)
423 v = side_bswap_64(v);
af6aa6e1
MD
424 if (v & (1ULL << (bit % 64))) {
425 match = true;
426 goto match;
427 }
428 break;
429 }
430 default:
431 abort();
432 }
ea32e5fc 433 }
af6aa6e1 434match:
ea32e5fc
MD
435 if (match) {
436 printf("%s", print_count++ ? ", " : "");
437 printf("\"%s\"", mapping->label);
438 }
439 }
440 if (!print_count)
441 printf("<NO LABEL>");
442 printf(" ]");
443}
444
0e9be766
MD
445static
446void tracer_print_basic_type_header(const struct side_type_description *type_desc)
447{
905c328e 448 print_attributes("attr", ":", type_desc->u.side_basic.attr, type_desc->u.side_basic.nr_attr);
0e9be766
MD
449 printf("%s", type_desc->u.side_basic.nr_attr ? ", " : "");
450 printf("value: ");
451}
452
f611d0c3
MD
453static
454void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item)
455{
d8be25de
MD
456 enum side_type type;
457
45392033
MD
458 switch (type_desc->type) {
459 case SIDE_TYPE_ARRAY:
460 switch (item->type) {
461 case SIDE_TYPE_ARRAY_U8:
462 case SIDE_TYPE_ARRAY_U16:
463 case SIDE_TYPE_ARRAY_U32:
464 case SIDE_TYPE_ARRAY_U64:
465 case SIDE_TYPE_ARRAY_S8:
466 case SIDE_TYPE_ARRAY_S16:
467 case SIDE_TYPE_ARRAY_S32:
468 case SIDE_TYPE_ARRAY_S64:
dd6e76cb
MD
469 case SIDE_TYPE_ARRAY_POINTER32:
470 case SIDE_TYPE_ARRAY_POINTER64:
f7653b43 471 case SIDE_TYPE_ARRAY_BYTE:
45392033
MD
472 case SIDE_TYPE_ARRAY:
473 break;
474 default:
de1b3cd2 475 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
ba845af5 476 abort();
45392033 477 break;
ba845af5
MD
478 }
479 break;
45392033
MD
480
481 case SIDE_TYPE_VLA:
482 switch (item->type) {
483 case SIDE_TYPE_VLA_U8:
484 case SIDE_TYPE_VLA_U16:
485 case SIDE_TYPE_VLA_U32:
486 case SIDE_TYPE_VLA_U64:
487 case SIDE_TYPE_VLA_S8:
488 case SIDE_TYPE_VLA_S16:
489 case SIDE_TYPE_VLA_S32:
490 case SIDE_TYPE_VLA_S64:
f7653b43 491 case SIDE_TYPE_VLA_BYTE:
dd6e76cb
MD
492 case SIDE_TYPE_VLA_POINTER32:
493 case SIDE_TYPE_VLA_POINTER64:
45392033
MD
494 case SIDE_TYPE_VLA:
495 break;
496 default:
de1b3cd2 497 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
1533629f 498 abort();
45392033 499 break;
1533629f
MD
500 }
501 break;
502
45392033
MD
503 case SIDE_TYPE_ENUM:
504 switch (item->type) {
505 case SIDE_TYPE_U8:
506 case SIDE_TYPE_U16:
507 case SIDE_TYPE_U32:
508 case SIDE_TYPE_U64:
509 case SIDE_TYPE_S8:
510 case SIDE_TYPE_S16:
511 case SIDE_TYPE_S32:
512 case SIDE_TYPE_S64:
bab5d6e4
MD
513 break;
514 default:
de1b3cd2 515 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
45392033
MD
516 abort();
517 break;
518 }
519 break;
520
521 case SIDE_TYPE_ENUM_BITMAP:
522 switch (item->type) {
523 case SIDE_TYPE_U8:
4cc2880b 524 case SIDE_TYPE_BYTE:
45392033
MD
525 case SIDE_TYPE_U16:
526 case SIDE_TYPE_U32:
527 case SIDE_TYPE_U64:
528 case SIDE_TYPE_ARRAY:
529 case SIDE_TYPE_VLA:
530 break;
531 default:
de1b3cd2 532 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
45392033
MD
533 abort();
534 break;
d8be25de
MD
535 }
536 break;
537
ba845af5 538 default:
a2e2357e 539 if (type_desc->type != item->type) {
de1b3cd2 540 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
ba845af5
MD
541 abort();
542 }
543 break;
f611d0c3 544 }
d8be25de 545
bab5d6e4
MD
546 if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP)
547 type = type_desc->type;
d8be25de
MD
548 else
549 type = item->type;
550
a848763d 551 printf("{ ");
d8be25de 552 switch (type) {
4f40d951 553 case SIDE_TYPE_BOOL:
0e9be766 554 tracer_print_basic_type_header(type_desc);
4f40d951
MD
555 printf("%s", item->u.side_bool ? "true" : "false");
556 break;
f611d0c3 557 case SIDE_TYPE_U8:
0e9be766 558 tracer_print_basic_type_header(type_desc);
f611d0c3
MD
559 printf("%" PRIu8, item->u.side_u8);
560 break;
561 case SIDE_TYPE_U16:
8bdd5c12
MD
562 {
563 uint16_t v;
564
565 v = item->u.side_u16;
566 if (type_to_host_reverse_bo(type_desc))
567 v = side_bswap_16(v);
0e9be766 568 tracer_print_basic_type_header(type_desc);
8bdd5c12 569 printf("%" PRIu16, v);
f611d0c3 570 break;
8bdd5c12 571 }
f611d0c3 572 case SIDE_TYPE_U32:
8bdd5c12
MD
573 {
574 uint32_t v;
575
576 v = item->u.side_u32;
577 if (type_to_host_reverse_bo(type_desc))
578 v = side_bswap_32(v);
0e9be766 579 tracer_print_basic_type_header(type_desc);
8bdd5c12 580 printf("%" PRIu32, v);
f611d0c3 581 break;
8bdd5c12 582 }
f611d0c3 583 case SIDE_TYPE_U64:
8bdd5c12
MD
584 {
585 uint64_t v;
586
587 v = item->u.side_u64;
588 if (type_to_host_reverse_bo(type_desc))
589 v = side_bswap_64(v);
0e9be766 590 tracer_print_basic_type_header(type_desc);
8bdd5c12 591 printf("%" PRIu64, v);
f611d0c3 592 break;
8bdd5c12 593 }
f611d0c3 594 case SIDE_TYPE_S8:
0e9be766 595 tracer_print_basic_type_header(type_desc);
f611d0c3
MD
596 printf("%" PRId8, item->u.side_s8);
597 break;
598 case SIDE_TYPE_S16:
8bdd5c12
MD
599 {
600 int16_t v;
601
602 v = item->u.side_s16;
603 if (type_to_host_reverse_bo(type_desc))
604 v = side_bswap_16(v);
0e9be766 605 tracer_print_basic_type_header(type_desc);
8bdd5c12 606 printf("%" PRId16, v);
f611d0c3 607 break;
8bdd5c12 608 }
f611d0c3 609 case SIDE_TYPE_S32:
8bdd5c12
MD
610 {
611 int32_t v;
612
613 v = item->u.side_s32;
614 if (type_to_host_reverse_bo(type_desc))
615 v = side_bswap_32(v);
0e9be766 616 tracer_print_basic_type_header(type_desc);
8bdd5c12 617 printf("%" PRId32, v);
f611d0c3 618 break;
8bdd5c12 619 }
f611d0c3 620 case SIDE_TYPE_S64:
8bdd5c12
MD
621 {
622 int64_t v;
623
624 v = item->u.side_s64;
625 if (type_to_host_reverse_bo(type_desc))
626 v = side_bswap_64(v);
0e9be766 627 tracer_print_basic_type_header(type_desc);
8bdd5c12 628 printf("%" PRId64, v);
f611d0c3 629 break;
8bdd5c12 630 }
dd6e76cb 631 case SIDE_TYPE_POINTER32:
f5e650d7 632 {
dd6e76cb 633 uint32_t v;
f5e650d7 634
dd6e76cb 635 v = item->u.side_u32;
f5e650d7 636 if (type_to_host_reverse_bo(type_desc))
dd6e76cb 637 v = side_bswap_32(v);
f5e650d7 638 tracer_print_basic_type_header(type_desc);
dd6e76cb
MD
639 printf("0x%" PRIx32, v);
640 break;
641 }
642 case SIDE_TYPE_POINTER64:
643 {
644 uint64_t v;
645
646 v = item->u.side_u64;
647 if (type_to_host_reverse_bo(type_desc))
648 v = side_bswap_64(v);
649 tracer_print_basic_type_header(type_desc);
650 printf("0x%" PRIx64, v);
f5e650d7
MD
651 break;
652 }
f7653b43 653 case SIDE_TYPE_BYTE:
0e9be766 654 tracer_print_basic_type_header(type_desc);
f7653b43 655 printf("0x%" PRIx8, item->u.side_byte);
7aec0d09 656 break;
79f677ba 657
d8be25de
MD
658 case SIDE_TYPE_ENUM:
659 print_enum(type_desc, item);
79f677ba
MD
660 break;
661
bab5d6e4 662 case SIDE_TYPE_ENUM_BITMAP:
af6aa6e1 663 print_enum_bitmap(type_desc, item);
ea32e5fc
MD
664 break;
665
fb25b355 666 case SIDE_TYPE_FLOAT_BINARY16:
8bdd5c12 667 {
fb25b355 668#if __HAVE_FLOAT16
8bdd5c12
MD
669 union {
670 _Float16 f;
671 uint16_t u;
672 } float16 = {
673 .f = item->u.side_float_binary16,
674 };
675
676 if (type_to_host_reverse_bo(type_desc))
677 float16.u = side_bswap_16(float16.u);
678 tracer_print_basic_type_header(type_desc);
679 printf("%g", (double) float16.f);
fb25b355
MD
680 break;
681#else
de1b3cd2 682 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
fb25b355
MD
683 abort();
684#endif
8bdd5c12 685 }
fb25b355 686 case SIDE_TYPE_FLOAT_BINARY32:
8bdd5c12 687 {
fb25b355 688#if __HAVE_FLOAT32
8bdd5c12
MD
689 union {
690 _Float32 f;
691 uint32_t u;
692 } float32 = {
693 .f = item->u.side_float_binary32,
694 };
695
696 if (type_to_host_reverse_bo(type_desc))
697 float32.u = side_bswap_32(float32.u);
698 tracer_print_basic_type_header(type_desc);
699 printf("%g", (double) float32.f);
fb25b355
MD
700 break;
701#else
de1b3cd2 702 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
fb25b355
MD
703 abort();
704#endif
8bdd5c12 705 }
fb25b355 706 case SIDE_TYPE_FLOAT_BINARY64:
8bdd5c12 707 {
fb25b355 708#if __HAVE_FLOAT64
8bdd5c12
MD
709 union {
710 _Float64 f;
711 uint64_t u;
712 } float64 = {
713 .f = item->u.side_float_binary64,
714 };
715
716 if (type_to_host_reverse_bo(type_desc))
717 float64.u = side_bswap_64(float64.u);
718 tracer_print_basic_type_header(type_desc);
719 printf("%g", (double) float64.f);
fb25b355
MD
720 break;
721#else
de1b3cd2 722 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
fb25b355
MD
723 abort();
724#endif
8bdd5c12 725 }
fb25b355 726 case SIDE_TYPE_FLOAT_BINARY128:
8bdd5c12 727 {
fb25b355 728#if __HAVE_FLOAT128
8bdd5c12
MD
729 union {
730 _Float128 f;
731 char arr[16];
732 } float128 = {
733 .f = item->u.side_float_binary128,
734 };
735
736 if (type_to_host_reverse_bo(type_desc))
737 side_bswap_128p(float128.arr);
738 tracer_print_basic_type_header(type_desc);
739 printf("%Lg", (long double) float128.f);
fb25b355
MD
740 break;
741#else
de1b3cd2 742 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
fb25b355
MD
743 abort();
744#endif
8bdd5c12 745 }
f611d0c3 746 case SIDE_TYPE_STRING:
0e9be766 747 tracer_print_basic_type_header(type_desc);
8549e629 748 printf("\"%s\"", (const char *)(uintptr_t) item->u.string);
f611d0c3
MD
749 break;
750 case SIDE_TYPE_STRUCT:
751 tracer_print_struct(type_desc, item->u.side_struct);
752 break;
753 case SIDE_TYPE_ARRAY:
754 tracer_print_array(type_desc, item->u.side_array);
755 break;
756 case SIDE_TYPE_VLA:
757 tracer_print_vla(type_desc, item->u.side_vla);
758 break;
759 case SIDE_TYPE_VLA_VISITOR:
352a4b77 760 tracer_print_vla_visitor(type_desc, item->u.side_vla_app_visitor_ctx);
f611d0c3 761 break;
ba845af5
MD
762 case SIDE_TYPE_ARRAY_U8:
763 case SIDE_TYPE_ARRAY_U16:
764 case SIDE_TYPE_ARRAY_U32:
765 case SIDE_TYPE_ARRAY_U64:
766 case SIDE_TYPE_ARRAY_S8:
767 case SIDE_TYPE_ARRAY_S16:
768 case SIDE_TYPE_ARRAY_S32:
769 case SIDE_TYPE_ARRAY_S64:
f7653b43 770 case SIDE_TYPE_ARRAY_BYTE:
dd6e76cb
MD
771 case SIDE_TYPE_ARRAY_POINTER32:
772 case SIDE_TYPE_ARRAY_POINTER64:
ba845af5
MD
773 tracer_print_array_fixint(type_desc, item);
774 break;
1533629f
MD
775 case SIDE_TYPE_VLA_U8:
776 case SIDE_TYPE_VLA_U16:
777 case SIDE_TYPE_VLA_U32:
778 case SIDE_TYPE_VLA_U64:
779 case SIDE_TYPE_VLA_S8:
780 case SIDE_TYPE_VLA_S16:
781 case SIDE_TYPE_VLA_S32:
782 case SIDE_TYPE_VLA_S64:
f7653b43 783 case SIDE_TYPE_VLA_BYTE:
dd6e76cb
MD
784 case SIDE_TYPE_VLA_POINTER32:
785 case SIDE_TYPE_VLA_POINTER64:
1533629f
MD
786 tracer_print_vla_fixint(type_desc, item);
787 break;
a2e2357e 788 case SIDE_TYPE_DYNAMIC:
0e9be766 789 tracer_print_basic_type_header(type_desc);
a2e2357e
MD
790 tracer_print_dynamic(&item->u.dynamic);
791 break;
f611d0c3 792 default:
de1b3cd2 793 fprintf(stderr, "<UNKNOWN TYPE>");
f611d0c3
MD
794 abort();
795 }
a848763d 796 printf(" }");
f611d0c3
MD
797}
798
799static
800void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg_vec *item)
801{
19fa6aa2 802 printf("%s: ", item_desc->field_name);
f611d0c3 803 tracer_print_type(&item_desc->side_type, item);
f611d0c3
MD
804}
805
806static
807void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
808{
809 const struct side_arg_vec *sav = sav_desc->sav;
810 uint32_t side_sav_len = sav_desc->len;
811 int i;
812
c7a14585 813 if (type_desc->u.side_struct->nr_fields != side_sav_len) {
de1b3cd2 814 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n");
f611d0c3
MD
815 abort();
816 }
905c328e 817 print_attributes("attr", ":", type_desc->u.side_struct->attr, type_desc->u.side_struct->nr_attr);
73b2b0c2
MD
818 printf("%s", type_desc->u.side_struct->nr_attr ? ", " : "");
819 printf("fields: { ");
f611d0c3
MD
820 for (i = 0; i < side_sav_len; i++) {
821 printf("%s", i ? ", " : "");
c7a14585 822 tracer_print_field(&type_desc->u.side_struct->fields[i], &sav[i]);
f611d0c3 823 }
d4328528 824 printf(" }");
f611d0c3
MD
825}
826
827static
828void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
829{
830 const struct side_arg_vec *sav = sav_desc->sav;
831 uint32_t side_sav_len = sav_desc->len;
832 int i;
833
834 if (type_desc->u.side_array.length != side_sav_len) {
de1b3cd2 835 fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n");
f611d0c3
MD
836 abort();
837 }
905c328e 838 print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
d4328528 839 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
20574104 840 printf("elements: ");
f611d0c3
MD
841 printf("[ ");
842 for (i = 0; i < side_sav_len; i++) {
843 printf("%s", i ? ", " : "");
844 tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]);
845 }
846 printf(" ]");
847}
848
849static
850void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
851{
852 const struct side_arg_vec *sav = sav_desc->sav;
853 uint32_t side_sav_len = sav_desc->len;
854 int i;
855
905c328e 856 print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
d4328528 857 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
20574104 858 printf("elements: ");
f611d0c3
MD
859 printf("[ ");
860 for (i = 0; i < side_sav_len; i++) {
861 printf("%s", i ? ", " : "");
862 tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]);
863 }
864 printf(" ]");
865}
866
352a4b77
MD
867struct tracer_visitor_priv {
868 const struct side_type_description *elem_type;
869 int i;
870};
871
872static
873enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
874 const struct side_arg_vec *elem)
875{
876 struct tracer_visitor_priv *tracer_priv = tracer_ctx->priv;
877
878 printf("%s", tracer_priv->i++ ? ", " : "");
879 tracer_print_type(tracer_priv->elem_type, elem);
880 return SIDE_VISITOR_STATUS_OK;
881}
882
f611d0c3 883static
352a4b77 884void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx)
f611d0c3
MD
885{
886 enum side_visitor_status status;
352a4b77
MD
887 struct tracer_visitor_priv tracer_priv = {
888 .elem_type = type_desc->u.side_vla_visitor.elem_type,
889 .i = 0,
890 };
891 const struct side_tracer_visitor_ctx tracer_ctx = {
892 .write_elem = tracer_write_elem_cb,
893 .priv = &tracer_priv,
894 };
f611d0c3 895
905c328e 896 print_attributes("attr", ":", type_desc->u.side_vla_visitor.attr, type_desc->u.side_vla_visitor.nr_attr);
d4328528 897 printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : "");
20574104 898 printf("elements: ");
352a4b77
MD
899 printf("[ ");
900 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
901 switch (status) {
902 case SIDE_VISITOR_STATUS_OK:
903 break;
904 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 905 fprintf(stderr, "ERROR: Visitor error\n");
f611d0c3 906 abort();
f611d0c3
MD
907 }
908 printf(" ]");
f611d0c3
MD
909}
910
ba845af5
MD
911void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
912{
913 const struct side_type_description *elem_type = type_desc->u.side_array.elem_type;
914 uint32_t side_sav_len = type_desc->u.side_array.length;
915 void *p = item->u.side_array_fixint;
916 enum side_type side_type;
917 int i;
918
905c328e 919 print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
d4328528 920 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
20574104 921 printf("elements: ");
1e8256c9
MD
922 switch (item->type) {
923 case SIDE_TYPE_ARRAY_U8:
924 if (elem_type->type != SIDE_TYPE_U8)
925 goto type_error;
926 break;
927 case SIDE_TYPE_ARRAY_U16:
928 if (elem_type->type != SIDE_TYPE_U16)
929 goto type_error;
930 break;
931 case SIDE_TYPE_ARRAY_U32:
932 if (elem_type->type != SIDE_TYPE_U32)
933 goto type_error;
934 break;
935 case SIDE_TYPE_ARRAY_U64:
936 if (elem_type->type != SIDE_TYPE_U64)
937 goto type_error;
938 break;
939 case SIDE_TYPE_ARRAY_S8:
940 if (elem_type->type != SIDE_TYPE_S8)
941 goto type_error;
942 break;
943 case SIDE_TYPE_ARRAY_S16:
944 if (elem_type->type != SIDE_TYPE_S16)
945 goto type_error;
946 break;
947 case SIDE_TYPE_ARRAY_S32:
948 if (elem_type->type != SIDE_TYPE_S32)
949 goto type_error;
950 break;
951 case SIDE_TYPE_ARRAY_S64:
952 if (elem_type->type != SIDE_TYPE_S64)
953 goto type_error;
954 break;
f7653b43
MD
955 case SIDE_TYPE_ARRAY_BYTE:
956 if (elem_type->type != SIDE_TYPE_BYTE)
7aec0d09
MD
957 goto type_error;
958 break;
dd6e76cb
MD
959 case SIDE_TYPE_ARRAY_POINTER32:
960 if (elem_type->type != SIDE_TYPE_POINTER32)
961 goto type_error;
962 case SIDE_TYPE_ARRAY_POINTER64:
963 if (elem_type->type != SIDE_TYPE_POINTER64)
f5e650d7
MD
964 goto type_error;
965 break;
1e8256c9
MD
966 default:
967 goto type_error;
ba845af5 968 }
1e8256c9 969 side_type = elem_type->type;
ba845af5 970
1533629f
MD
971 printf("[ ");
972 for (i = 0; i < side_sav_len; i++) {
973 struct side_arg_vec sav_elem = {
974 .type = side_type,
975 };
976
977 switch (side_type) {
978 case SIDE_TYPE_U8:
979 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
980 break;
981 case SIDE_TYPE_S8:
982 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
983 break;
984 case SIDE_TYPE_U16:
985 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
986 break;
987 case SIDE_TYPE_S16:
988 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
989 break;
990 case SIDE_TYPE_U32:
991 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
992 break;
993 case SIDE_TYPE_S32:
994 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
995 break;
996 case SIDE_TYPE_U64:
997 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
998 break;
999 case SIDE_TYPE_S64:
1000 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
1001 break;
f7653b43
MD
1002 case SIDE_TYPE_BYTE:
1003 sav_elem.u.side_byte = ((const uint8_t *) p)[i];
7aec0d09 1004 break;
dd6e76cb
MD
1005 case SIDE_TYPE_POINTER32:
1006 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
1007 break;
1008 case SIDE_TYPE_POINTER64:
1009 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
f5e650d7 1010 break;
1533629f
MD
1011
1012 default:
de1b3cd2 1013 fprintf(stderr, "ERROR: Unexpected type\n");
1533629f
MD
1014 abort();
1015 }
1016
1017 printf("%s", i ? ", " : "");
1018 tracer_print_type(elem_type, &sav_elem);
1019 }
1020 printf(" ]");
1021 return;
1022
1023type_error:
de1b3cd2 1024 fprintf(stderr, "ERROR: type mismatch\n");
1533629f
MD
1025 abort();
1026}
1027
1028void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
1029{
1030 const struct side_type_description *elem_type = type_desc->u.side_vla.elem_type;
1031 uint32_t side_sav_len = item->u.side_vla_fixint.length;
1032 void *p = item->u.side_vla_fixint.p;
1033 enum side_type side_type;
1034 int i;
1035
905c328e 1036 print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
d4328528 1037 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
20574104 1038 printf("elements: ");
a2e2357e
MD
1039 switch (item->type) {
1040 case SIDE_TYPE_VLA_U8:
1041 if (elem_type->type != SIDE_TYPE_U8)
1533629f 1042 goto type_error;
a2e2357e
MD
1043 break;
1044 case SIDE_TYPE_VLA_U16:
1045 if (elem_type->type != SIDE_TYPE_U16)
1533629f 1046 goto type_error;
a2e2357e
MD
1047 break;
1048 case SIDE_TYPE_VLA_U32:
1049 if (elem_type->type != SIDE_TYPE_U32)
1050 goto type_error;
1051 break;
1052 case SIDE_TYPE_VLA_U64:
1053 if (elem_type->type != SIDE_TYPE_U64)
1054 goto type_error;
1055 break;
1056 case SIDE_TYPE_VLA_S8:
1057 if (elem_type->type != SIDE_TYPE_S8)
1058 goto type_error;
1059 break;
1060 case SIDE_TYPE_VLA_S16:
1061 if (elem_type->type != SIDE_TYPE_S16)
1062 goto type_error;
1063 break;
1064 case SIDE_TYPE_VLA_S32:
1065 if (elem_type->type != SIDE_TYPE_S32)
1066 goto type_error;
1067 break;
1068 case SIDE_TYPE_VLA_S64:
1069 if (elem_type->type != SIDE_TYPE_S64)
1070 goto type_error;
1071 break;
f7653b43
MD
1072 case SIDE_TYPE_VLA_BYTE:
1073 if (elem_type->type != SIDE_TYPE_BYTE)
7aec0d09
MD
1074 goto type_error;
1075 break;
dd6e76cb
MD
1076 case SIDE_TYPE_VLA_POINTER32:
1077 if (elem_type->type != SIDE_TYPE_POINTER32)
1078 goto type_error;
1079 case SIDE_TYPE_VLA_POINTER64:
1080 if (elem_type->type != SIDE_TYPE_POINTER64)
f5e650d7
MD
1081 goto type_error;
1082 break;
a2e2357e
MD
1083 default:
1084 goto type_error;
1533629f 1085 }
a2e2357e 1086 side_type = elem_type->type;
1533629f 1087
ba845af5
MD
1088 printf("[ ");
1089 for (i = 0; i < side_sav_len; i++) {
1090 struct side_arg_vec sav_elem = {
1091 .type = side_type,
1092 };
1093
1094 switch (side_type) {
1095 case SIDE_TYPE_U8:
1096 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
1097 break;
1098 case SIDE_TYPE_S8:
1099 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
1100 break;
1101 case SIDE_TYPE_U16:
1102 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
1103 break;
1104 case SIDE_TYPE_S16:
1105 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
1106 break;
1107 case SIDE_TYPE_U32:
1108 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
1109 break;
1110 case SIDE_TYPE_S32:
1111 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
1112 break;
1113 case SIDE_TYPE_U64:
1114 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
1115 break;
1116 case SIDE_TYPE_S64:
1117 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
1118 break;
f7653b43
MD
1119 case SIDE_TYPE_BYTE:
1120 sav_elem.u.side_byte = ((const uint8_t *) p)[i];
7aec0d09 1121 break;
dd6e76cb
MD
1122 case SIDE_TYPE_POINTER32:
1123 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
1124 break;
1125 case SIDE_TYPE_POINTER64:
1126 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
f5e650d7 1127 break;
ba845af5
MD
1128
1129 default:
de1b3cd2 1130 fprintf(stderr, "ERROR: Unexpected type\n");
ba845af5
MD
1131 abort();
1132 }
1133
1134 printf("%s", i ? ", " : "");
1135 tracer_print_type(elem_type, &sav_elem);
1136 }
1137 printf(" ]");
1138 return;
1139
1140type_error:
de1b3cd2 1141 fprintf(stderr, "ERROR: type mismatch\n");
ba845af5
MD
1142 abort();
1143}
1144
a2e2357e 1145static
c208889e 1146void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct)
a2e2357e 1147{
c208889e
MD
1148 const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields;
1149 uint32_t len = dynamic_struct->len;
465e5e7e
MD
1150 int i;
1151
905c328e 1152 print_attributes("attr", "::", dynamic_struct->attr, dynamic_struct->nr_attr);
8d20e708 1153 printf("%s", dynamic_struct->nr_attr ? ", " : "");
f0061366 1154 printf("fields:: ");
465e5e7e
MD
1155 printf("[ ");
1156 for (i = 0; i < len; i++) {
1157 printf("%s", i ? ", " : "");
1158 printf("%s:: ", fields[i].field_name);
1159 tracer_print_dynamic(&fields[i].elem);
1160 }
1161 printf(" ]");
a2e2357e
MD
1162}
1163
2b359235
MD
1164struct tracer_dynamic_struct_visitor_priv {
1165 int i;
1166};
1167
1168static
1169enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
1170 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
1171 const struct side_arg_dynamic_event_field *dynamic_field)
1172{
1173 struct tracer_dynamic_struct_visitor_priv *tracer_priv = tracer_ctx->priv;
1174
1175 printf("%s", tracer_priv->i++ ? ", " : "");
1176 printf("%s:: ", dynamic_field->field_name);
1177 tracer_print_dynamic(&dynamic_field->elem);
1178 return SIDE_VISITOR_STATUS_OK;
1179}
1180
a2e2357e 1181static
c208889e 1182void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item)
a2e2357e 1183{
2b359235
MD
1184 enum side_visitor_status status;
1185 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
1186 .i = 0,
1187 };
1188 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
1189 .write_field = tracer_dynamic_struct_write_elem_cb,
1190 .priv = &tracer_priv,
1191 };
1192 void *app_ctx = item->u.side_dynamic_struct_visitor.app_ctx;
1193
905c328e 1194 print_attributes("attr", "::", item->u.side_dynamic_struct_visitor.attr, item->u.side_dynamic_struct_visitor.nr_attr);
8d20e708 1195 printf("%s", item->u.side_dynamic_struct_visitor.nr_attr ? ", " : "");
f0061366 1196 printf("fields:: ");
2b359235
MD
1197 printf("[ ");
1198 status = item->u.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
1199 switch (status) {
1200 case SIDE_VISITOR_STATUS_OK:
1201 break;
1202 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1203 fprintf(stderr, "ERROR: Visitor error\n");
2b359235
MD
1204 abort();
1205 }
1206 printf(" ]");
a2e2357e
MD
1207}
1208
1209static
1210void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla)
1211{
1212 const struct side_arg_dynamic_vec *sav = vla->sav;
1213 uint32_t side_sav_len = vla->len;
1214 int i;
1215
905c328e 1216 print_attributes("attr", "::", vla->attr, vla->nr_attr);
8d20e708 1217 printf("%s", vla->nr_attr ? ", " : "");
f0061366 1218 printf("elements:: ");
a2e2357e
MD
1219 printf("[ ");
1220 for (i = 0; i < side_sav_len; i++) {
1221 printf("%s", i ? ", " : "");
1222 tracer_print_dynamic(&sav[i]);
1223 }
1224 printf(" ]");
1225}
1226
8ceca0cd
MD
1227struct tracer_dynamic_vla_visitor_priv {
1228 int i;
1229};
1230
1231static
1232enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
1233 const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
1234 const struct side_arg_dynamic_vec *elem)
1235{
1236 struct tracer_dynamic_vla_visitor_priv *tracer_priv = tracer_ctx->priv;
1237
1238 printf("%s", tracer_priv->i++ ? ", " : "");
1239 tracer_print_dynamic(elem);
1240 return SIDE_VISITOR_STATUS_OK;
1241}
1242
a2e2357e
MD
1243static
1244void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item)
1245{
8ceca0cd
MD
1246 enum side_visitor_status status;
1247 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
1248 .i = 0,
1249 };
1250 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx = {
1251 .write_elem = tracer_dynamic_vla_write_elem_cb,
1252 .priv = &tracer_priv,
1253 };
1254 void *app_ctx = item->u.side_dynamic_vla_visitor.app_ctx;
1255
905c328e 1256 print_attributes("attr", "::", item->u.side_dynamic_vla_visitor.attr, item->u.side_dynamic_vla_visitor.nr_attr);
8d20e708 1257 printf("%s", item->u.side_dynamic_vla_visitor.nr_attr ? ", " : "");
f0061366 1258 printf("elements:: ");
8ceca0cd
MD
1259 printf("[ ");
1260 status = item->u.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
1261 switch (status) {
1262 case SIDE_VISITOR_STATUS_OK:
1263 break;
1264 case SIDE_VISITOR_STATUS_ERROR:
de1b3cd2 1265 fprintf(stderr, "ERROR: Visitor error\n");
8ceca0cd
MD
1266 abort();
1267 }
1268 printf(" ]");
a2e2357e
MD
1269}
1270
0e9be766
MD
1271static
1272void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec *item)
1273{
905c328e 1274 print_attributes("attr", "::", item->u.side_basic.attr, item->u.side_basic.nr_attr);
0e9be766
MD
1275 printf("%s", item->u.side_basic.nr_attr ? ", " : "");
1276 printf("value:: ");
1277}
1278
a2e2357e
MD
1279static
1280void tracer_print_dynamic(const struct side_arg_dynamic_vec *item)
1281{
808bd9bf 1282 printf("{ ");
1e8256c9 1283 switch (item->dynamic_type) {
a2e2357e 1284 case SIDE_DYNAMIC_TYPE_NULL:
0e9be766 1285 tracer_print_dynamic_basic_type_header(item);
a2e2357e
MD
1286 printf("<NULL TYPE>");
1287 break;
4f40d951 1288 case SIDE_DYNAMIC_TYPE_BOOL:
0e9be766 1289 tracer_print_dynamic_basic_type_header(item);
8d20e708 1290 printf("%s", item->u.side_basic.u.side_bool ? "true" : "false");
4f40d951 1291 break;
a2e2357e 1292 case SIDE_DYNAMIC_TYPE_U8:
0e9be766 1293 tracer_print_dynamic_basic_type_header(item);
8d20e708 1294 printf("%" PRIu8, item->u.side_basic.u.side_u8);
a2e2357e
MD
1295 break;
1296 case SIDE_DYNAMIC_TYPE_U16:
8bdd5c12
MD
1297 {
1298 uint16_t v;
1299
1300 v = item->u.side_basic.u.side_u16;
1301 if (dynamic_type_to_host_reverse_bo(item))
1302 v = side_bswap_16(v);
0e9be766 1303 tracer_print_dynamic_basic_type_header(item);
8bdd5c12 1304 printf("%" PRIu16, v);
a2e2357e 1305 break;
8bdd5c12 1306 }
a2e2357e 1307 case SIDE_DYNAMIC_TYPE_U32:
8bdd5c12
MD
1308 {
1309 uint32_t v;
1310
1311 v = item->u.side_basic.u.side_u32;
1312 if (dynamic_type_to_host_reverse_bo(item))
1313 v = side_bswap_32(v);
0e9be766 1314 tracer_print_dynamic_basic_type_header(item);
8bdd5c12 1315 printf("%" PRIu32, v);
a2e2357e 1316 break;
8bdd5c12 1317 }
a2e2357e 1318 case SIDE_DYNAMIC_TYPE_U64:
8bdd5c12
MD
1319 {
1320 uint64_t v;
1321
1322 v = item->u.side_basic.u.side_u64;
1323 if (dynamic_type_to_host_reverse_bo(item))
1324 v = side_bswap_64(v);
0e9be766 1325 tracer_print_dynamic_basic_type_header(item);
8bdd5c12 1326 printf("%" PRIu64, v);
a2e2357e 1327 break;
8bdd5c12 1328 }
a2e2357e 1329 case SIDE_DYNAMIC_TYPE_S8:
0e9be766 1330 tracer_print_dynamic_basic_type_header(item);
8d20e708 1331 printf("%" PRId8, item->u.side_basic.u.side_s8);
a2e2357e
MD
1332 break;
1333 case SIDE_DYNAMIC_TYPE_S16:
8bdd5c12
MD
1334 {
1335 int16_t v;
1336
1337 v = item->u.side_basic.u.side_u16;
1338 if (dynamic_type_to_host_reverse_bo(item))
1339 v = side_bswap_16(v);
0e9be766 1340 tracer_print_dynamic_basic_type_header(item);
8bdd5c12 1341 printf("%" PRId16, v);
a2e2357e 1342 break;
8bdd5c12 1343 }
a2e2357e 1344 case SIDE_DYNAMIC_TYPE_S32:
8bdd5c12
MD
1345 {
1346 int32_t v;
1347
1348 v = item->u.side_basic.u.side_u32;
1349 if (dynamic_type_to_host_reverse_bo(item))
1350 v = side_bswap_32(v);
0e9be766 1351 tracer_print_dynamic_basic_type_header(item);
8bdd5c12 1352 printf("%" PRId32, v);
a2e2357e 1353 break;
8bdd5c12 1354 }
a2e2357e 1355 case SIDE_DYNAMIC_TYPE_S64:
8bdd5c12
MD
1356 {
1357 int64_t v;
1358
1359 v = item->u.side_basic.u.side_u64;
1360 if (dynamic_type_to_host_reverse_bo(item))
1361 v = side_bswap_64(v);
0e9be766 1362 tracer_print_dynamic_basic_type_header(item);
8bdd5c12 1363 printf("%" PRId64, v);
a2e2357e 1364 break;
8bdd5c12 1365 }
f7653b43 1366 case SIDE_DYNAMIC_TYPE_BYTE:
0e9be766 1367 tracer_print_dynamic_basic_type_header(item);
f7653b43 1368 printf("0x%" PRIx8, item->u.side_basic.u.side_byte);
199e7aa9 1369 break;
dd6e76cb 1370 case SIDE_DYNAMIC_TYPE_POINTER32:
f5e650d7 1371 {
dd6e76cb 1372 uint32_t v;
f5e650d7 1373
dd6e76cb 1374 v = item->u.side_basic.u.side_u32;
f5e650d7 1375 if (dynamic_type_to_host_reverse_bo(item))
dd6e76cb
MD
1376 v = side_bswap_32(v);
1377 tracer_print_dynamic_basic_type_header(item);
1378 printf("0x%" PRIx32, v);
1379 break;
1380 }
1381
1382 case SIDE_DYNAMIC_TYPE_POINTER64:
1383 {
1384 uint64_t v;
1385
1386 v = item->u.side_basic.u.side_u64;
1387 if (dynamic_type_to_host_reverse_bo(item))
1388 v = side_bswap_64(v);
f5e650d7 1389 tracer_print_dynamic_basic_type_header(item);
dd6e76cb 1390 printf("0x%" PRIx64, v);
f5e650d7
MD
1391 break;
1392 }
199e7aa9 1393
fb25b355 1394 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
8bdd5c12 1395 {
fb25b355 1396#if __HAVE_FLOAT16
8bdd5c12
MD
1397 union {
1398 _Float16 f;
1399 uint16_t u;
1400 } float16 = {
1401 .f = item->u.side_basic.u.side_float_binary16,
1402 };
1403
1404 if (dynamic_type_to_host_reverse_bo(item))
1405 float16.u = side_bswap_16(float16.u);
1406 tracer_print_dynamic_basic_type_header(item);
1407 printf("%g", (double) float16.f);
fb25b355
MD
1408 break;
1409#else
de1b3cd2 1410 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
fb25b355
MD
1411 abort();
1412#endif
8bdd5c12 1413 }
fb25b355 1414 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
8bdd5c12 1415 {
fb25b355 1416#if __HAVE_FLOAT32
8bdd5c12
MD
1417 union {
1418 _Float32 f;
1419 uint32_t u;
1420 } float32 = {
1421 .f = item->u.side_basic.u.side_float_binary32,
1422 };
1423
1424 if (dynamic_type_to_host_reverse_bo(item))
1425 float32.u = side_bswap_32(float32.u);
1426 tracer_print_dynamic_basic_type_header(item);
1427 printf("%g", (double) float32.f);
fb25b355
MD
1428 break;
1429#else
de1b3cd2 1430 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
fb25b355
MD
1431 abort();
1432#endif
8bdd5c12 1433 }
fb25b355 1434 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
8bdd5c12 1435 {
fb25b355 1436#if __HAVE_FLOAT64
8bdd5c12
MD
1437 union {
1438 _Float64 f;
1439 uint64_t u;
1440 } float64 = {
1441 .f = item->u.side_basic.u.side_float_binary64,
1442 };
1443
1444 if (dynamic_type_to_host_reverse_bo(item))
1445 float64.u = side_bswap_64(float64.u);
1446 tracer_print_dynamic_basic_type_header(item);
1447 printf("%g", (double) float64.f);
fb25b355
MD
1448 break;
1449#else
de1b3cd2 1450 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
fb25b355
MD
1451 abort();
1452#endif
8bdd5c12 1453 }
fb25b355 1454 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
8bdd5c12 1455 {
fb25b355 1456#if __HAVE_FLOAT128
8bdd5c12
MD
1457 union {
1458 _Float128 f;
1459 char arr[16];
1460 } float128 = {
1461 .f = item->u.side_basic.u.side_float_binary128,
1462 };
1463
1464 if (dynamic_type_to_host_reverse_bo(item))
1465 side_bswap_128p(float128.arr);
1466 tracer_print_dynamic_basic_type_header(item);
1467 printf("%Lg", (long double) float128.f);
fb25b355
MD
1468 break;
1469#else
de1b3cd2 1470 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
fb25b355
MD
1471 abort();
1472#endif
8bdd5c12 1473 }
a2e2357e 1474 case SIDE_DYNAMIC_TYPE_STRING:
0e9be766 1475 tracer_print_dynamic_basic_type_header(item);
8549e629 1476 printf("\"%s\"", (const char *)(uintptr_t) item->u.side_basic.u.string);
a2e2357e 1477 break;
c208889e
MD
1478 case SIDE_DYNAMIC_TYPE_STRUCT:
1479 tracer_print_dynamic_struct(item->u.side_dynamic_struct);
a2e2357e 1480 break;
c208889e
MD
1481 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR:
1482 tracer_print_dynamic_struct_visitor(item);
a2e2357e
MD
1483 break;
1484 case SIDE_DYNAMIC_TYPE_VLA:
1485 tracer_print_dynamic_vla(item->u.side_dynamic_vla);
1486 break;
1487 case SIDE_DYNAMIC_TYPE_VLA_VISITOR:
1488 tracer_print_dynamic_vla_visitor(item);
1489 break;
1490 default:
de1b3cd2 1491 fprintf(stderr, "<UNKNOWN TYPE>");
a2e2357e
MD
1492 abort();
1493 }
808bd9bf 1494 printf(" }");
a2e2357e
MD
1495}
1496
68f8cfbe
MD
1497static
1498void tracer_print_static_fields(const struct side_event_description *desc,
1499 const struct side_arg_vec_description *sav_desc,
1500 int *nr_items)
f611d0c3
MD
1501{
1502 const struct side_arg_vec *sav = sav_desc->sav;
1503 uint32_t side_sav_len = sav_desc->len;
1504 int i;
1505
65010f43 1506 printf("provider: %s, event: %s", desc->provider_name, desc->event_name);
f611d0c3 1507 if (desc->nr_fields != side_sav_len) {
de1b3cd2 1508 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
f611d0c3
MD
1509 abort();
1510 }
905c328e 1511 print_attributes(", attr", ":", desc->attr, desc->nr_attr);
a848763d 1512 printf("%s", side_sav_len ? ", fields: [ " : "");
f611d0c3
MD
1513 for (i = 0; i < side_sav_len; i++) {
1514 printf("%s", i ? ", " : "");
1515 tracer_print_field(&desc->fields[i], &sav[i]);
1516 }
68f8cfbe
MD
1517 if (nr_items)
1518 *nr_items = i;
c7d338e2
MD
1519 if (side_sav_len)
1520 printf(" ]");
68f8cfbe
MD
1521}
1522
4a7d8700
MD
1523void tracer_call(const struct side_event_description *desc,
1524 const struct side_arg_vec_description *sav_desc,
1525 void *priv __attribute__((unused)))
68f8cfbe 1526{
a848763d
MD
1527 int nr_fields = 0;
1528
a848763d 1529 tracer_print_static_fields(desc, sav_desc, &nr_fields);
f611d0c3
MD
1530 printf("\n");
1531}
19fa6aa2
MD
1532
1533void tracer_call_variadic(const struct side_event_description *desc,
4a7d8700
MD
1534 const struct side_arg_vec_description *sav_desc,
1535 const struct side_arg_dynamic_event_struct *var_struct,
1536 void *priv __attribute__((unused)))
19fa6aa2 1537{
68f8cfbe
MD
1538 uint32_t var_struct_len = var_struct->len;
1539 int nr_fields = 0, i;
19fa6aa2 1540
68f8cfbe
MD
1541 tracer_print_static_fields(desc, sav_desc, &nr_fields);
1542
8a25ce77 1543 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
de1b3cd2 1544 fprintf(stderr, "ERROR: unexpected non-variadic event description\n");
8a25ce77
MD
1545 abort();
1546 }
905c328e
MD
1547 print_attributes(", attr ", "::", var_struct->attr, var_struct->nr_attr);
1548 printf("%s", var_struct_len ? ", fields:: [ " : "");
68f8cfbe 1549 for (i = 0; i < var_struct_len; i++, nr_fields++) {
c7d338e2 1550 printf("%s", i ? ", " : "");
68f8cfbe
MD
1551 printf("%s:: ", var_struct->fields[i].field_name);
1552 tracer_print_dynamic(&var_struct->fields[i].elem);
19fa6aa2 1553 }
a848763d
MD
1554 if (i)
1555 printf(" ]");
19fa6aa2
MD
1556 printf("\n");
1557}
1e8aec23
MD
1558
1559void tracer_event_notification(enum side_tracer_notification notif,
1560 struct side_event_description **events, uint32_t nr_events, void *priv)
1561{
1562 uint32_t i;
314c22c3 1563 int ret;
1e8aec23
MD
1564
1565 printf("----------------------------------------------------------\n");
1566 printf("Tracer notified of events %s\n",
314c22c3 1567 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1e8aec23
MD
1568 for (i = 0; i < nr_events; i++) {
1569 struct side_event_description *event = events[i];
1570
1571 /* Skip NULL pointers */
1572 if (!event)
1573 continue;
1574 printf("provider: %s, event: %s\n",
1575 event->provider_name, event->event_name);
314c22c3
MD
1576 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
1577 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1578 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL);
1579 if (ret)
1580 abort();
1581 } else {
1582 ret = side_tracer_callback_register(event, tracer_call, NULL);
1583 if (ret)
1584 abort();
1585 }
1586 } else {
1587 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1588 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL);
1589 if (ret)
1590 abort();
1591 } else {
1592 ret = side_tracer_callback_unregister(event, tracer_call, NULL);
1593 if (ret)
1594 abort();
1595 }
1596 }
1e8aec23
MD
1597 }
1598 printf("----------------------------------------------------------\n");
1599}
1600
1601static __attribute__((constructor))
1602void tracer_init(void);
1603static
1604void tracer_init(void)
1605{
1606 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1607 if (!tracer_handle)
1608 abort();
1609}
1610
1611static __attribute__((destructor))
1612void tracer_exit(void);
1613static
1614void tracer_exit(void)
1615{
1616 side_tracer_event_notification_unregister(tracer_handle);
1617}
This page took 0.189144 seconds and 4 git commands to generate.