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