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