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