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