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