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