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