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