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