Add key characteristics to rfc
[libside.git] / src / tracer.c
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>
10 #include <stdbool.h>
11 #include <string.h>
12 #include <iconv.h>
13
14 #include <side/trace.h>
15
16 #include "visit-arg-vec.h"
17 #include "visit-description.h"
18
19 /* TODO: optionally print caller address. */
20 static bool print_caller = false;
21
22 #define MAX_NESTING 32
23
24 enum tracer_display_base {
25 TRACER_DISPLAY_BASE_2,
26 TRACER_DISPLAY_BASE_8,
27 TRACER_DISPLAY_BASE_10,
28 TRACER_DISPLAY_BASE_16,
29 };
30
31 union int_value {
32 uint64_t u[NR_SIDE_INTEGER128_SPLIT];
33 int64_t s[NR_SIDE_INTEGER128_SPLIT];
34 };
35
36 struct print_ctx {
37 int nesting; /* Keep track of nesting, useful for tabulations. */
38 int item_nr[MAX_NESTING]; /* Item number in current nesting level, useful for comma-separated lists. */
39 };
40
41 static struct side_tracer_handle *tracer_handle;
42
43 static uint64_t tracer_key;
44
45 static struct side_description_visitor description_visitor;
46
47 static
48 void tracer_convert_string_to_utf8(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
49 size_t *strlen_with_null,
50 char **output_str)
51 {
52 size_t ret, inbytesleft = 0, outbytesleft, bufsize, input_size;
53 const char *str = p, *fromcode;
54 char *inbuf = (char *) p, *outbuf, *buf;
55 iconv_t cd;
56
57 switch (unit_size) {
58 case 1:
59 if (strlen_with_null)
60 *strlen_with_null = strlen(str) + 1;
61 *output_str = (char *) str;
62 return;
63 case 2:
64 {
65 const uint16_t *p16 = p;
66
67 switch (byte_order) {
68 case SIDE_TYPE_BYTE_ORDER_LE:
69 {
70 fromcode = "UTF-16LE";
71 break;
72 }
73 case SIDE_TYPE_BYTE_ORDER_BE:
74 {
75 fromcode = "UTF-16BE";
76 break;
77 }
78 default:
79 fprintf(stderr, "Unknown byte order\n");
80 abort();
81 }
82 for (; *p16; p16++)
83 inbytesleft += 2;
84 input_size = inbytesleft + 2;
85 /*
86 * Worse case is U+FFFF UTF-16 (2 bytes) converting to
87 * { ef, bf, bf } UTF-8 (3 bytes).
88 */
89 bufsize = inbytesleft / 2 * 3 + 1;
90 break;
91 }
92 case 4:
93 {
94 const uint32_t *p32 = p;
95
96 switch (byte_order) {
97 case SIDE_TYPE_BYTE_ORDER_LE:
98 {
99 fromcode = "UTF-32LE";
100 break;
101 }
102 case SIDE_TYPE_BYTE_ORDER_BE:
103 {
104 fromcode = "UTF-32BE";
105 break;
106 }
107 default:
108 fprintf(stderr, "Unknown byte order\n");
109 abort();
110 }
111 for (; *p32; p32++)
112 inbytesleft += 4;
113 input_size = inbytesleft + 4;
114 /*
115 * Each 4-byte UTF-32 character converts to at most a
116 * 4-byte UTF-8 character.
117 */
118 bufsize = inbytesleft + 1;
119 break;
120 }
121 default:
122 fprintf(stderr, "Unknown string unit size %" PRIu8 "\n", unit_size);
123 abort();
124 }
125
126 cd = iconv_open("UTF8", fromcode);
127 if (cd == (iconv_t) -1) {
128 perror("iconv_open");
129 abort();
130 }
131 buf = malloc(bufsize);
132 if (!buf) {
133 abort();
134 }
135 outbuf = (char *) buf;
136 outbytesleft = bufsize;
137 ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
138 if (ret == (size_t) -1) {
139 perror("iconv");
140 abort();
141 }
142 if (inbytesleft) {
143 fprintf(stderr, "Buffer too small to convert string input\n");
144 abort();
145 }
146 (*outbuf++) = '\0';
147 if (iconv_close(cd) == -1) {
148 perror("iconv_close");
149 abort();
150 }
151 if (strlen_with_null)
152 *strlen_with_null = input_size;
153 *output_str = buf;
154 }
155
156 static
157 void tracer_print_type_string(const void *p, uint8_t unit_size, enum side_type_label_byte_order byte_order,
158 size_t *strlen_with_null)
159 {
160 char *output_str = NULL;
161
162 tracer_convert_string_to_utf8(p, unit_size, byte_order, strlen_with_null, &output_str);
163 printf("\"%s\"", output_str);
164 if (output_str != p)
165 free(output_str);
166 }
167
168 static
169 void side_check_value_u64(union int_value v)
170 {
171 if (v.u[SIDE_INTEGER128_SPLIT_HIGH]) {
172 fprintf(stderr, "Unexpected integer value\n");
173 abort();
174 }
175 }
176
177 static
178 void side_check_value_s64(union int_value v)
179 {
180 if (v.s[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << 63)) {
181 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] != ~0LL) {
182 fprintf(stderr, "Unexpected integer value\n");
183 abort();
184 }
185 } else {
186 if (v.s[SIDE_INTEGER128_SPLIT_HIGH]) {
187 fprintf(stderr, "Unexpected integer value\n");
188 abort();
189 }
190 }
191 }
192
193 static
194 int64_t get_attr_integer64_value(const struct side_attr *attr)
195 {
196 int64_t val;
197
198 switch (side_enum_get(attr->value.type)) {
199 case SIDE_ATTR_TYPE_U8:
200 val = attr->value.u.integer_value.side_u8;
201 break;
202 case SIDE_ATTR_TYPE_U16:
203 val = attr->value.u.integer_value.side_u16;
204 break;
205 case SIDE_ATTR_TYPE_U32:
206 val = attr->value.u.integer_value.side_u32;
207 break;
208 case SIDE_ATTR_TYPE_U64:
209 val = attr->value.u.integer_value.side_u64;
210 break;
211 case SIDE_ATTR_TYPE_U128:
212 {
213 union int_value v = {
214 .u = {
215 [SIDE_INTEGER128_SPLIT_LOW] = attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW],
216 [SIDE_INTEGER128_SPLIT_HIGH] = attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH],
217 },
218 };
219 side_check_value_u64(v);
220 val = v.u[SIDE_INTEGER128_SPLIT_LOW];
221 break;
222 }
223 case SIDE_ATTR_TYPE_S8:
224 val = attr->value.u.integer_value.side_s8;
225 break;
226 case SIDE_ATTR_TYPE_S16:
227 val = attr->value.u.integer_value.side_s16;
228 break;
229 case SIDE_ATTR_TYPE_S32:
230 val = attr->value.u.integer_value.side_s32;
231 break;
232 case SIDE_ATTR_TYPE_S64:
233 val = attr->value.u.integer_value.side_s64;
234 break;
235 case SIDE_ATTR_TYPE_S128:
236 {
237 union int_value v = {
238 .s = {
239 [SIDE_INTEGER128_SPLIT_LOW] = attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW],
240 [SIDE_INTEGER128_SPLIT_HIGH] = attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH],
241 },
242 };
243 side_check_value_s64(v);
244 val = v.s[SIDE_INTEGER128_SPLIT_LOW];
245 break;
246 }
247 default:
248 fprintf(stderr, "Unexpected attribute type\n");
249 abort();
250 }
251 return val;
252 }
253
254 static
255 enum tracer_display_base get_attr_display_base(const struct side_attr *_attr, uint32_t nr_attr,
256 enum tracer_display_base default_base)
257 {
258 uint32_t i;
259
260 for (i = 0; i < nr_attr; i++) {
261 const struct side_attr *attr = &_attr[i];
262 char *utf8_str = NULL;
263 bool cmp;
264
265 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
266 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
267 cmp = strcmp(utf8_str, "std.integer.base");
268 if (utf8_str != side_ptr_get(attr->key.p))
269 free(utf8_str);
270 if (!cmp) {
271 int64_t val = get_attr_integer64_value(attr);
272
273 switch (val) {
274 case 2:
275 return TRACER_DISPLAY_BASE_2;
276 case 8:
277 return TRACER_DISPLAY_BASE_8;
278 case 10:
279 return TRACER_DISPLAY_BASE_10;
280 case 16:
281 return TRACER_DISPLAY_BASE_16;
282 default:
283 fprintf(stderr, "Unexpected integer display base: %" PRId64 "\n", val);
284 abort();
285 }
286 }
287 }
288 return default_base; /* Default */
289 }
290
291 static
292 void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
293 {
294 char *utf8_str = NULL;
295
296 tracer_convert_string_to_utf8(side_ptr_get(attr->key.p), attr->key.unit_size,
297 side_enum_get(attr->key.byte_order), NULL, &utf8_str);
298 printf("{ key%s \"%s\", value%s ", separator, utf8_str, separator);
299 if (utf8_str != side_ptr_get(attr->key.p))
300 free(utf8_str);
301 switch (side_enum_get(attr->value.type)) {
302 case SIDE_ATTR_TYPE_BOOL:
303 printf("%s", attr->value.u.bool_value ? "true" : "false");
304 break;
305 case SIDE_ATTR_TYPE_U8:
306 printf("%" PRIu8, attr->value.u.integer_value.side_u8);
307 break;
308 case SIDE_ATTR_TYPE_U16:
309 printf("%" PRIu16, attr->value.u.integer_value.side_u16);
310 break;
311 case SIDE_ATTR_TYPE_U32:
312 printf("%" PRIu32, attr->value.u.integer_value.side_u32);
313 break;
314 case SIDE_ATTR_TYPE_U64:
315 printf("%" PRIu64, attr->value.u.integer_value.side_u64);
316 break;
317 case SIDE_ATTR_TYPE_U128:
318 if (attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
319 printf("0x%" PRIx64, attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW]);
320 } else {
321 printf("0x%" PRIx64 "%016" PRIx64,
322 attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_HIGH],
323 attr->value.u.integer_value.side_u128_split[SIDE_INTEGER128_SPLIT_LOW]);
324 }
325 break;
326 case SIDE_ATTR_TYPE_S8:
327 printf("%" PRId8, attr->value.u.integer_value.side_s8);
328 break;
329 case SIDE_ATTR_TYPE_S16:
330 printf("%" PRId16, attr->value.u.integer_value.side_s16);
331 break;
332 case SIDE_ATTR_TYPE_S32:
333 printf("%" PRId32, attr->value.u.integer_value.side_s32);
334 break;
335 case SIDE_ATTR_TYPE_S64:
336 printf("%" PRId64, attr->value.u.integer_value.side_s64);
337 break;
338 case SIDE_ATTR_TYPE_S128:
339 if (attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
340 printf("0x%" PRIx64, attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW]);
341 } else {
342 printf("0x%" PRIx64 "%016" PRIx64,
343 attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_HIGH],
344 attr->value.u.integer_value.side_s128_split[SIDE_INTEGER128_SPLIT_LOW]);
345 }
346 break;
347 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
348 #if __HAVE_FLOAT16
349 printf("%g", (double) attr->value.u.float_value.side_float_binary16);
350 break;
351 #else
352 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
353 abort();
354 #endif
355 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
356 #if __HAVE_FLOAT32
357 printf("%g", (double) attr->value.u.float_value.side_float_binary32);
358 break;
359 #else
360 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
361 abort();
362 #endif
363 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
364 #if __HAVE_FLOAT64
365 printf("%g", (double) attr->value.u.float_value.side_float_binary64);
366 break;
367 #else
368 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
369 abort();
370 #endif
371 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
372 #if __HAVE_FLOAT128
373 printf("%Lg", (long double) attr->value.u.float_value.side_float_binary128);
374 break;
375 #else
376 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
377 abort();
378 #endif
379 case SIDE_ATTR_TYPE_STRING:
380 tracer_print_type_string(side_ptr_get(attr->value.u.string_value.p),
381 attr->value.u.string_value.unit_size,
382 side_enum_get(attr->value.u.string_value.byte_order), NULL);
383 break;
384 default:
385 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
386 abort();
387 }
388 printf(" }");
389 }
390
391 static
392 void print_attributes(const char *prefix_str, const char *separator,
393 const struct side_attr *attr, uint32_t nr_attr)
394 {
395 uint32_t i;
396
397 if (!nr_attr)
398 return;
399 printf("%s%s [", prefix_str, separator);
400 for (i = 0; i < nr_attr; i++) {
401 printf("%s", i ? ", " : " ");
402 tracer_print_attr_type(separator, &attr[i]);
403 }
404 printf(" ]");
405 }
406
407 static
408 union int_value tracer_load_integer_value(const struct side_type_integer *type_integer,
409 const union side_integer_value *value,
410 uint16_t offset_bits, uint16_t *_len_bits)
411 {
412 union int_value v = {};
413 uint16_t len_bits;
414 bool reverse_bo;
415
416 if (!type_integer->len_bits)
417 len_bits = type_integer->integer_size * CHAR_BIT;
418 else
419 len_bits = type_integer->len_bits;
420 if (len_bits + offset_bits > type_integer->integer_size * CHAR_BIT)
421 abort();
422 reverse_bo = side_enum_get(type_integer->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
423 switch (type_integer->integer_size) {
424 case 1:
425 if (type_integer->signedness)
426 v.s[SIDE_INTEGER128_SPLIT_LOW] = value->side_s8;
427 else
428 v.u[SIDE_INTEGER128_SPLIT_LOW] = value->side_u8;
429 break;
430 case 2:
431 if (type_integer->signedness) {
432 int16_t side_s16;
433
434 side_s16 = value->side_s16;
435 if (reverse_bo)
436 side_s16 = side_bswap_16(side_s16);
437 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s16;
438 } else {
439 uint16_t side_u16;
440
441 side_u16 = value->side_u16;
442 if (reverse_bo)
443 side_u16 = side_bswap_16(side_u16);
444 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u16;
445 }
446 break;
447 case 4:
448 if (type_integer->signedness) {
449 int32_t side_s32;
450
451 side_s32 = value->side_s32;
452 if (reverse_bo)
453 side_s32 = side_bswap_32(side_s32);
454 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s32;
455 } else {
456 uint32_t side_u32;
457
458 side_u32 = value->side_u32;
459 if (reverse_bo)
460 side_u32 = side_bswap_32(side_u32);
461 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u32;
462 }
463 break;
464 case 8:
465 if (type_integer->signedness) {
466 int64_t side_s64;
467
468 side_s64 = value->side_s64;
469 if (reverse_bo)
470 side_s64 = side_bswap_64(side_s64);
471 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64;
472 } else {
473 uint64_t side_u64;
474
475 side_u64 = value->side_u64;
476 if (reverse_bo)
477 side_u64 = side_bswap_64(side_u64);
478 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64;
479 }
480 break;
481 case 16:
482 if (type_integer->signedness) {
483 int64_t side_s64[NR_SIDE_INTEGER128_SPLIT];
484
485 side_s64[SIDE_INTEGER128_SPLIT_LOW] = value->side_s128_split[SIDE_INTEGER128_SPLIT_LOW];
486 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_s128_split[SIDE_INTEGER128_SPLIT_HIGH];
487 if (reverse_bo) {
488 side_s64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_LOW]);
489 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_HIGH]);
490 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
491 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
492 } else {
493 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
494 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
495 }
496 } else {
497 uint64_t side_u64[NR_SIDE_INTEGER128_SPLIT];
498
499 side_u64[SIDE_INTEGER128_SPLIT_LOW] = value->side_u128_split[SIDE_INTEGER128_SPLIT_LOW];
500 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_u128_split[SIDE_INTEGER128_SPLIT_HIGH];
501 if (reverse_bo) {
502 side_u64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_LOW]);
503 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_HIGH]);
504 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
505 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
506 } else {
507 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
508 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
509 }
510 }
511 break;
512 default:
513 abort();
514 }
515 if (type_integer->integer_size <= 8) {
516 v.u[SIDE_INTEGER128_SPLIT_LOW] >>= offset_bits;
517 if (len_bits < 64) {
518 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
519 if (type_integer->signedness) {
520 /* Sign-extend. */
521 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (len_bits - 1))) {
522 v.u[SIDE_INTEGER128_SPLIT_LOW] |= ~((1ULL << len_bits) - 1);
523 v.u[SIDE_INTEGER128_SPLIT_HIGH] = ~0ULL;
524 }
525 }
526 }
527 } else {
528 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
529 if (len_bits < 128 || offset_bits != 0)
530 abort();
531 }
532 if (_len_bits)
533 *_len_bits = len_bits;
534 return v;
535 }
536
537 static
538 void print_enum_labels(const struct side_enum_mappings *mappings, union int_value v)
539 {
540 uint32_t i, print_count = 0;
541
542 side_check_value_s64(v);
543 printf(", labels: [ ");
544 for (i = 0; i < mappings->nr_mappings; i++) {
545 const struct side_enum_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
546
547 if (mapping->range_end < mapping->range_begin) {
548 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
549 mapping->range_begin, mapping->range_end);
550 abort();
551 }
552 if (v.s[SIDE_INTEGER128_SPLIT_LOW] >= mapping->range_begin && v.s[SIDE_INTEGER128_SPLIT_LOW] <= mapping->range_end) {
553 printf("%s", print_count++ ? ", " : "");
554 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
555 side_enum_get(mapping->label.byte_order), NULL);
556 }
557 }
558 if (!print_count)
559 printf("<NO LABEL>");
560 printf(" ]");
561 }
562
563 static
564 uint32_t elem_type_to_stride(const struct side_type *elem_type)
565 {
566 uint32_t stride_bit;
567
568 switch (side_enum_get(elem_type->type)) {
569 case SIDE_TYPE_BYTE:
570 stride_bit = 8;
571 break;
572
573 case SIDE_TYPE_U8:
574 case SIDE_TYPE_U16:
575 case SIDE_TYPE_U32:
576 case SIDE_TYPE_U64:
577 case SIDE_TYPE_U128:
578 case SIDE_TYPE_S8:
579 case SIDE_TYPE_S16:
580 case SIDE_TYPE_S32:
581 case SIDE_TYPE_S64:
582 case SIDE_TYPE_S128:
583 return elem_type->u.side_integer.integer_size * CHAR_BIT;
584 default:
585 fprintf(stderr, "ERROR: Unexpected enum bitmap element type\n");
586 abort();
587 }
588 return stride_bit;
589 }
590
591 static
592 void print_integer_binary(uint64_t v[NR_SIDE_INTEGER128_SPLIT], int bits)
593 {
594 int bit;
595
596 printf("0b");
597 if (bits > 64) {
598 bits -= 64;
599 v[SIDE_INTEGER128_SPLIT_HIGH] <<= 64 - bits;
600 for (bit = 0; bit < bits; bit++) {
601 printf("%c", v[SIDE_INTEGER128_SPLIT_HIGH] & (1ULL << 63) ? '1' : '0');
602 v[SIDE_INTEGER128_SPLIT_HIGH] <<= 1;
603 }
604 bits = 64;
605 }
606 v[SIDE_INTEGER128_SPLIT_LOW] <<= 64 - bits;
607 for (bit = 0; bit < bits; bit++) {
608 printf("%c", v[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << 63) ? '1' : '0');
609 v[SIDE_INTEGER128_SPLIT_LOW] <<= 1;
610 }
611 }
612
613 static
614 void tracer_print_type_header(const char *prefix, const char *separator,
615 const struct side_attr *attr, uint32_t nr_attr)
616 {
617 print_attributes("attr", separator, attr, nr_attr);
618 printf("%s", nr_attr ? ", " : "");
619 printf("%s%s ", prefix, separator);
620 }
621
622 static
623 void tracer_print_type_bool(const char *separator,
624 const struct side_type_bool *type_bool,
625 const union side_bool_value *value,
626 uint16_t offset_bits)
627 {
628 uint32_t len_bits;
629 bool reverse_bo;
630 uint64_t v;
631
632 if (!type_bool->len_bits)
633 len_bits = type_bool->bool_size * CHAR_BIT;
634 else
635 len_bits = type_bool->len_bits;
636 if (len_bits + offset_bits > type_bool->bool_size * CHAR_BIT)
637 abort();
638 reverse_bo = side_enum_get(type_bool->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
639 switch (type_bool->bool_size) {
640 case 1:
641 v = value->side_bool8;
642 break;
643 case 2:
644 {
645 uint16_t side_u16;
646
647 side_u16 = value->side_bool16;
648 if (reverse_bo)
649 side_u16 = side_bswap_16(side_u16);
650 v = side_u16;
651 break;
652 }
653 case 4:
654 {
655 uint32_t side_u32;
656
657 side_u32 = value->side_bool32;
658 if (reverse_bo)
659 side_u32 = side_bswap_32(side_u32);
660 v = side_u32;
661 break;
662 }
663 case 8:
664 {
665 uint64_t side_u64;
666
667 side_u64 = value->side_bool64;
668 if (reverse_bo)
669 side_u64 = side_bswap_64(side_u64);
670 v = side_u64;
671 break;
672 }
673 default:
674 abort();
675 }
676 v >>= offset_bits;
677 if (len_bits < 64)
678 v &= (1ULL << len_bits) - 1;
679 tracer_print_type_header("value", separator, side_ptr_get(type_bool->attr), type_bool->nr_attr);
680 printf("%s", v ? "true" : "false");
681 }
682
683 /* 2^128 - 1 */
684 #define U128_BASE_10_ARRAY_LEN sizeof("340282366920938463463374607431768211455")
685 /* -2^127 */
686 #define S128_BASE_10_ARRAY_LEN sizeof("-170141183460469231731687303715884105728")
687
688 /*
689 * u128_tostring_base_10 is inspired from https://stackoverflow.com/a/4364365
690 */
691 static
692 void u128_tostring_base_10(union int_value v, char str[U128_BASE_10_ARRAY_LEN])
693 {
694 int d[39] = {}, i, j, str_i = 0;
695
696 for (i = 63; i > -1; i--) {
697 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
698 d[0]++;
699 for (j = 0; j < 39; j++)
700 d[j] *= 2;
701 for (j = 0; j < 38; j++) {
702 d[j + 1] += d[j] / 10;
703 d[j] %= 10;
704 }
705 }
706 for (i = 63; i > -1; i--) {
707 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
708 d[0]++;
709 if (i > 0) {
710 for (j = 0; j < 39; j++)
711 d[j] *= 2;
712 }
713 for (j = 0; j < 38; j++) {
714 d[j + 1] += d[j] / 10;
715 d[j] %= 10;
716 }
717 }
718 for (i = 38; i > 0; i--)
719 if (d[i] > 0)
720 break;
721 for (; i > -1; i--) {
722 str[str_i++] = '0' + d[i];
723 }
724 str[str_i] = '\0';
725 }
726
727 static
728 void s128_tostring_base_10(union int_value v, char str[S128_BASE_10_ARRAY_LEN])
729 {
730 uint64_t low, high, tmp;
731
732 if (v.s[SIDE_INTEGER128_SPLIT_HIGH] >= 0) {
733 /* Positive. */
734 v.u[SIDE_INTEGER128_SPLIT_LOW] = (uint64_t) v.s[SIDE_INTEGER128_SPLIT_LOW];
735 v.u[SIDE_INTEGER128_SPLIT_HIGH] = (uint64_t) v.s[SIDE_INTEGER128_SPLIT_HIGH];
736 u128_tostring_base_10(v, str);
737 return;
738 }
739
740 /* Negative. */
741
742 /* Special-case minimum value, which has no positive signed representation. */
743 if ((v.s[SIDE_INTEGER128_SPLIT_HIGH] == INT64_MIN) && (v.s[SIDE_INTEGER128_SPLIT_LOW] == 0)) {
744 memcpy(str, "-170141183460469231731687303715884105728", S128_BASE_10_ARRAY_LEN);
745 return;
746 }
747 /* Convert from two's complement. */
748 high = ~(uint64_t) v.s[SIDE_INTEGER128_SPLIT_HIGH];
749 low = ~(uint64_t) v.s[SIDE_INTEGER128_SPLIT_LOW];
750 tmp = low + 1;
751 if (tmp < low) {
752 high++;
753 /* Clear overflow to sign bit. */
754 high &= ~0x8000000000000000ULL;
755 }
756 v.u[SIDE_INTEGER128_SPLIT_LOW] = tmp;
757 v.u[SIDE_INTEGER128_SPLIT_HIGH] = high;
758 str[0] = '-';
759 u128_tostring_base_10(v, str + 1);
760 }
761
762 /* 2^128 - 1 */
763 #define U128_BASE_8_ARRAY_LEN sizeof("3777777777777777777777777777777777777777777")
764
765 static
766 void u128_tostring_base_8(union int_value v, char str[U128_BASE_8_ARRAY_LEN])
767 {
768 int d[43] = {}, i, j, str_i = 0;
769
770 for (i = 63; i > -1; i--) {
771 if ((v.u[SIDE_INTEGER128_SPLIT_HIGH] >> i) & 1)
772 d[0]++;
773 for (j = 0; j < 43; j++)
774 d[j] *= 2;
775 for (j = 0; j < 42; j++) {
776 d[j + 1] += d[j] / 8;
777 d[j] %= 8;
778 }
779 }
780 for (i = 63; i > -1; i--) {
781 if ((v.u[SIDE_INTEGER128_SPLIT_LOW] >> i) & 1)
782 d[0]++;
783 if (i > 0) {
784 for (j = 0; j < 43; j++)
785 d[j] *= 2;
786 }
787 for (j = 0; j < 42; j++) {
788 d[j + 1] += d[j] / 8;
789 d[j] %= 8;
790 }
791 }
792 for (i = 42; i > 0; i--)
793 if (d[i] > 0)
794 break;
795 for (; i > -1; i--) {
796 str[str_i++] = '0' + d[i];
797 }
798 str[str_i] = '\0';
799 }
800
801 static
802 void tracer_print_type_integer(const char *separator,
803 const struct side_type_integer *type_integer,
804 const union side_integer_value *value,
805 uint16_t offset_bits,
806 enum tracer_display_base default_base)
807 {
808 enum tracer_display_base base;
809 union int_value v;
810 uint16_t len_bits;
811
812 v = tracer_load_integer_value(type_integer, value, offset_bits, &len_bits);
813 tracer_print_type_header("value", separator, side_ptr_get(type_integer->attr), type_integer->nr_attr);
814 base = get_attr_display_base(side_ptr_get(type_integer->attr), type_integer->nr_attr, default_base);
815 switch (base) {
816 case TRACER_DISPLAY_BASE_2:
817 print_integer_binary(v.u, len_bits);
818 break;
819 case TRACER_DISPLAY_BASE_8:
820 /* Clear sign bits beyond len_bits */
821 if (len_bits < 64) {
822 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
823 v.u[SIDE_INTEGER128_SPLIT_HIGH] = 0;
824 } else if (len_bits < 128) {
825 v.u[SIDE_INTEGER128_SPLIT_HIGH] &= (1ULL << (len_bits - 64)) - 1;
826 }
827 if (len_bits <= 64) {
828 printf("0o%" PRIo64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
829 } else {
830 char str[U128_BASE_8_ARRAY_LEN];
831
832 u128_tostring_base_8(v, str);
833 printf("0o%s", str);
834 }
835 break;
836 case TRACER_DISPLAY_BASE_10:
837 if (len_bits <= 64) {
838 if (type_integer->signedness)
839 printf("%" PRId64, v.s[SIDE_INTEGER128_SPLIT_LOW]);
840 else
841 printf("%" PRIu64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
842 } else {
843 if (type_integer->signedness) {
844 char str[S128_BASE_10_ARRAY_LEN];
845 s128_tostring_base_10(v, str);
846 printf("%s", str);
847 } else {
848 char str[U128_BASE_10_ARRAY_LEN];
849 u128_tostring_base_10(v, str);
850 printf("%s", str);
851 }
852 }
853 break;
854 case TRACER_DISPLAY_BASE_16:
855 /* Clear sign bits beyond len_bits */
856 if (len_bits < 64) {
857 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
858 v.u[SIDE_INTEGER128_SPLIT_HIGH] = 0;
859 } else if (len_bits < 128) {
860 v.u[SIDE_INTEGER128_SPLIT_HIGH] &= (1ULL << (len_bits - 64)) - 1;
861 }
862 if (len_bits <= 64 || v.u[SIDE_INTEGER128_SPLIT_HIGH] == 0) {
863 printf("0x%" PRIx64, v.u[SIDE_INTEGER128_SPLIT_LOW]);
864 } else {
865 printf("0x%" PRIx64 "%016" PRIx64,
866 v.u[SIDE_INTEGER128_SPLIT_HIGH],
867 v.u[SIDE_INTEGER128_SPLIT_LOW]);
868 }
869 break;
870 default:
871 abort();
872 }
873 }
874
875 static
876 void tracer_print_type_float(const char *separator,
877 const struct side_type_float *type_float,
878 const union side_float_value *value)
879 {
880 bool reverse_bo;
881
882 tracer_print_type_header("value", separator, side_ptr_get(type_float->attr), type_float->nr_attr);
883 reverse_bo = side_enum_get(type_float->byte_order) != SIDE_TYPE_FLOAT_WORD_ORDER_HOST;
884 switch (type_float->float_size) {
885 case 2:
886 {
887 #if __HAVE_FLOAT16
888 union {
889 _Float16 f;
890 uint16_t u;
891 } float16 = {
892 .f = value->side_float_binary16,
893 };
894
895 if (reverse_bo)
896 float16.u = side_bswap_16(float16.u);
897 printf("%g", (double) float16.f);
898 break;
899 #else
900 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
901 abort();
902 #endif
903 }
904 case 4:
905 {
906 #if __HAVE_FLOAT32
907 union {
908 _Float32 f;
909 uint32_t u;
910 } float32 = {
911 .f = value->side_float_binary32,
912 };
913
914 if (reverse_bo)
915 float32.u = side_bswap_32(float32.u);
916 printf("%g", (double) float32.f);
917 break;
918 #else
919 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
920 abort();
921 #endif
922 }
923 case 8:
924 {
925 #if __HAVE_FLOAT64
926 union {
927 _Float64 f;
928 uint64_t u;
929 } float64 = {
930 .f = value->side_float_binary64,
931 };
932
933 if (reverse_bo)
934 float64.u = side_bswap_64(float64.u);
935 printf("%g", (double) float64.f);
936 break;
937 #else
938 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
939 abort();
940 #endif
941 }
942 case 16:
943 {
944 #if __HAVE_FLOAT128
945 union {
946 _Float128 f;
947 char arr[16];
948 } float128 = {
949 .f = value->side_float_binary128,
950 };
951
952 if (reverse_bo)
953 side_bswap_128p(float128.arr);
954 printf("%Lg", (long double) float128.f);
955 break;
956 #else
957 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
958 abort();
959 #endif
960 }
961 default:
962 fprintf(stderr, "ERROR: Unknown float size\n");
963 abort();
964 }
965 }
966
967 static
968 void push_nesting(struct print_ctx *ctx)
969 {
970 if (++ctx->nesting >= MAX_NESTING) {
971 fprintf(stderr, "ERROR: Nesting too deep.\n");
972 abort();
973 }
974 ctx->item_nr[ctx->nesting] = 0;
975 }
976
977 static
978 void pop_nesting(struct print_ctx *ctx)
979 {
980 ctx->item_nr[ctx->nesting] = 0;
981 if (ctx->nesting-- <= 0) {
982 fprintf(stderr, "ERROR: Nesting underflow.\n");
983 abort();
984 }
985 }
986
987 static
988 int get_nested_item_nr(struct print_ctx *ctx)
989 {
990 return ctx->item_nr[ctx->nesting];
991 }
992
993 static
994 void inc_nested_item_nr(struct print_ctx *ctx)
995 {
996 ctx->item_nr[ctx->nesting]++;
997 }
998
999 static
1000 void tracer_before_print_event(const struct side_event_description *desc,
1001 const struct side_arg_vec *side_arg_vec,
1002 const struct side_arg_dynamic_struct *var_struct __attribute__((unused)),
1003 void *caller_addr, void *priv __attribute__((unused)))
1004 {
1005 uint32_t side_sav_len = side_arg_vec->len;
1006
1007 if (desc->nr_fields != side_sav_len) {
1008 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1009 abort();
1010 }
1011
1012 if (print_caller)
1013 printf("caller: [%p], ", caller_addr);
1014 printf("provider: %s, event: %s",
1015 side_ptr_get(desc->provider_name),
1016 side_ptr_get(desc->event_name));
1017 print_attributes(", attr", ":", side_ptr_get(desc->attr), desc->nr_attr);
1018 }
1019
1020 static
1021 void tracer_after_print_event(const struct side_event_description *desc __attribute__((unused)),
1022 const struct side_arg_vec *side_arg_vec __attribute__((unused)),
1023 const struct side_arg_dynamic_struct *var_struct __attribute__((unused)),
1024 void *caller_addr __attribute__((unused)), void *priv __attribute__((unused)))
1025 {
1026 printf("\n");
1027 }
1028
1029 static
1030 void tracer_before_print_static_fields(const struct side_arg_vec *side_arg_vec, void *priv)
1031 {
1032 struct print_ctx *ctx = (struct print_ctx *) priv;
1033 uint32_t side_sav_len = side_arg_vec->len;
1034
1035 printf("%s", side_sav_len ? ", fields: {" : "");
1036 push_nesting(ctx);
1037 }
1038
1039
1040 static
1041 void tracer_after_print_static_fields(const struct side_arg_vec *side_arg_vec, void *priv)
1042 {
1043 struct print_ctx *ctx = (struct print_ctx *) priv;
1044 uint32_t side_sav_len = side_arg_vec->len;
1045
1046 pop_nesting(ctx);
1047 if (side_sav_len)
1048 printf(" }");
1049 }
1050
1051 static
1052 void tracer_before_print_variadic_fields(const struct side_arg_dynamic_struct *var_struct,
1053 void *priv)
1054 {
1055 struct print_ctx *ctx = (struct print_ctx *) priv;
1056 uint32_t var_struct_len = var_struct->len;
1057
1058 print_attributes(", attr ", "::", side_ptr_get(var_struct->attr), var_struct->nr_attr);
1059 printf("%s", var_struct_len ? ", fields:: {" : "");
1060 push_nesting(ctx);
1061 }
1062
1063 static
1064 void tracer_after_print_variadic_fields(const struct side_arg_dynamic_struct *var_struct, void *priv)
1065 {
1066 struct print_ctx *ctx = (struct print_ctx *) priv;
1067 uint32_t var_struct_len = var_struct->len;
1068
1069 pop_nesting(ctx);
1070 if (var_struct_len)
1071 printf(" }");
1072 }
1073
1074 static
1075 void tracer_before_print_field(const struct side_event_field *item_desc, void *priv)
1076 {
1077 struct print_ctx *ctx = (struct print_ctx *) priv;
1078
1079 if (get_nested_item_nr(ctx) != 0)
1080 printf(",");
1081 printf(" %s: { ", side_ptr_get(item_desc->field_name));
1082 }
1083
1084 static
1085 void tracer_after_print_field(const struct side_event_field *item_desc __attribute__((unused)), void *priv)
1086 {
1087 struct print_ctx *ctx = (struct print_ctx *) priv;
1088
1089 printf(" }");
1090 inc_nested_item_nr(ctx);
1091 }
1092
1093 static
1094 void tracer_before_print_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1095 {
1096 struct print_ctx *ctx = (struct print_ctx *) priv;
1097
1098 if (get_nested_item_nr(ctx) != 0)
1099 printf(", { ");
1100 else
1101 printf(" { ");
1102 }
1103
1104 static
1105 void tracer_after_print_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1106 {
1107 struct print_ctx *ctx = (struct print_ctx *) priv;
1108
1109 printf(" }");
1110 inc_nested_item_nr(ctx);
1111 }
1112
1113 static
1114 void tracer_print_null(const struct side_type *type_desc,
1115 const struct side_arg *item __attribute__((unused)),
1116 void *priv __attribute__((unused)))
1117 {
1118 tracer_print_type_header("value", ":", side_ptr_get(type_desc->u.side_null.attr),
1119 type_desc->u.side_null.nr_attr);
1120 printf("<NULL TYPE>");
1121 }
1122
1123 static
1124 void tracer_print_bool(const struct side_type *type_desc,
1125 const struct side_arg *item,
1126 void *priv __attribute__((unused)))
1127 {
1128 tracer_print_type_bool(":", &type_desc->u.side_bool, &item->u.side_static.bool_value, 0);
1129 }
1130
1131 static
1132 void tracer_print_integer(const struct side_type *type_desc,
1133 const struct side_arg *item,
1134 void *priv __attribute__((unused)))
1135 {
1136 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0, TRACER_DISPLAY_BASE_10);
1137 }
1138
1139 static
1140 void tracer_print_byte(const struct side_type *type_desc __attribute__((unused)),
1141 const struct side_arg *item,
1142 void *priv __attribute__((unused)))
1143 {
1144 tracer_print_type_header("value", ":", side_ptr_get(type_desc->u.side_byte.attr), type_desc->u.side_byte.nr_attr);
1145 printf("0x%" PRIx8, item->u.side_static.byte_value);
1146 }
1147
1148 static
1149 void tracer_print_pointer(const struct side_type *type_desc,
1150 const struct side_arg *item,
1151 void *priv __attribute__((unused)))
1152 {
1153 tracer_print_type_integer(":", &type_desc->u.side_integer, &item->u.side_static.integer_value, 0, TRACER_DISPLAY_BASE_16);
1154 }
1155
1156 static
1157 void tracer_print_float(const struct side_type *type_desc,
1158 const struct side_arg *item,
1159 void *priv __attribute__((unused)))
1160 {
1161 tracer_print_type_float(":", &type_desc->u.side_float, &item->u.side_static.float_value);
1162 }
1163
1164 static
1165 void tracer_print_string(const struct side_type *type_desc,
1166 const struct side_arg *item,
1167 void *priv __attribute__((unused)))
1168 {
1169 tracer_print_type_header("value", ":", side_ptr_get(type_desc->u.side_string.attr), type_desc->u.side_string.nr_attr);
1170 tracer_print_type_string(side_ptr_get(item->u.side_static.string_value),
1171 type_desc->u.side_string.unit_size,
1172 side_enum_get(type_desc->u.side_string.byte_order), NULL);
1173 }
1174
1175 static
1176 void tracer_before_print_struct(const struct side_type_struct *side_struct,
1177 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
1178 {
1179 struct print_ctx *ctx = (struct print_ctx *) priv;
1180
1181 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
1182 printf("%s", side_struct->nr_attr ? ", " : "");
1183 printf("fields: {");
1184 push_nesting(ctx);
1185 }
1186
1187
1188 static
1189 void tracer_after_print_struct(const struct side_type_struct *side_struct __attribute__((unused)),
1190 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
1191 {
1192 struct print_ctx *ctx = (struct print_ctx *) priv;
1193
1194 pop_nesting(ctx);
1195 printf(" }");
1196 }
1197
1198 static
1199 void tracer_before_print_array(const struct side_type_array *side_array,
1200 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
1201 {
1202 struct print_ctx *ctx = (struct print_ctx *) priv;
1203
1204 print_attributes("attr", ":", side_ptr_get(side_array->attr), side_array->nr_attr);
1205 printf("%s", side_array->nr_attr ? ", " : "");
1206 printf("elements: [");
1207 push_nesting(ctx);
1208 }
1209
1210 static
1211 void tracer_after_print_array(const struct side_type_array *side_array __attribute__((unused)),
1212 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
1213 {
1214 struct print_ctx *ctx = (struct print_ctx *) priv;
1215
1216 pop_nesting(ctx);
1217 printf(" ]");
1218 }
1219
1220 static
1221 void do_tracer_before_print_vla(const struct side_type_vla *side_vla,
1222 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
1223 {
1224 struct print_ctx *ctx = (struct print_ctx *) priv;
1225
1226 print_attributes("attr", ":", side_ptr_get(side_vla->attr), side_vla->nr_attr);
1227 printf("%s", side_vla->nr_attr ? ", " : "");
1228 printf("elements: [");
1229 push_nesting(ctx);
1230 }
1231
1232
1233 static
1234 void do_tracer_after_print_vla(const struct side_type_vla *side_vla __attribute__((unused)),
1235 const struct side_arg_vec *side_arg_vec __attribute__((unused)), void *priv)
1236 {
1237 struct print_ctx *ctx = (struct print_ctx *) priv;
1238
1239 pop_nesting(ctx);
1240 printf(" ]");
1241 }
1242
1243 static
1244 void tracer_before_print_vla(const struct side_type_vla *side_vla,
1245 const struct side_arg_vec *side_arg_vec, void *priv)
1246 {
1247 switch (side_enum_get(side_ptr_get(side_vla->length_type)->type)) {
1248 case SIDE_TYPE_U8: /* Fall-through */
1249 case SIDE_TYPE_U16: /* Fall-through */
1250 case SIDE_TYPE_U32: /* Fall-through */
1251 case SIDE_TYPE_U64: /* Fall-through */
1252 case SIDE_TYPE_U128: /* Fall-through */
1253 case SIDE_TYPE_S8: /* Fall-through */
1254 case SIDE_TYPE_S16: /* Fall-through */
1255 case SIDE_TYPE_S32: /* Fall-through */
1256 case SIDE_TYPE_S64: /* Fall-through */
1257 case SIDE_TYPE_S128:
1258 break;
1259 default:
1260 fprintf(stderr, "ERROR: Unexpected vla length type\n");
1261 abort();
1262 }
1263 do_tracer_before_print_vla(side_vla, side_arg_vec, priv);
1264 }
1265
1266 static
1267 void tracer_after_print_vla(const struct side_type_vla *side_vla,
1268 const struct side_arg_vec *side_arg_vec, void *priv)
1269 {
1270 do_tracer_after_print_vla(side_vla, side_arg_vec, priv);
1271 }
1272
1273 static
1274 void tracer_before_print_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor,
1275 const struct side_arg_vla_visitor *side_arg_vla_visitor __attribute__((unused)), void *priv)
1276 {
1277 struct print_ctx *ctx = (struct print_ctx *) priv;
1278
1279 switch (side_enum_get(side_ptr_get(side_vla_visitor->length_type)->type)) {
1280 case SIDE_TYPE_U8: /* Fall-through */
1281 case SIDE_TYPE_U16: /* Fall-through */
1282 case SIDE_TYPE_U32: /* Fall-through */
1283 case SIDE_TYPE_U64: /* Fall-through */
1284 case SIDE_TYPE_U128: /* Fall-through */
1285 case SIDE_TYPE_S8: /* Fall-through */
1286 case SIDE_TYPE_S16: /* Fall-through */
1287 case SIDE_TYPE_S32: /* Fall-through */
1288 case SIDE_TYPE_S64: /* Fall-through */
1289 case SIDE_TYPE_S128:
1290 break;
1291 default:
1292 fprintf(stderr, "ERROR: Unexpected vla visitor length type\n");
1293 abort();
1294 }
1295
1296 print_attributes("attr", ":", side_ptr_get(side_vla_visitor->attr), side_vla_visitor->nr_attr);
1297 printf("%s", side_vla_visitor->nr_attr ? ", " : "");
1298 printf("elements: [");
1299 push_nesting(ctx);
1300 }
1301
1302 static
1303 void tracer_after_print_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor __attribute__((unused)),
1304 const struct side_arg_vla_visitor *side_arg_vla_visitor __attribute__((unused)), void *priv)
1305 {
1306 struct print_ctx *ctx = (struct print_ctx *) priv;
1307
1308 pop_nesting(ctx);
1309 printf(" ]");
1310 }
1311
1312 static void tracer_print_enum(const struct side_type *type_desc,
1313 const struct side_arg *item, void *priv)
1314 {
1315 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
1316 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum.elem_type);
1317 union int_value v;
1318
1319 if (side_enum_get(elem_type->type) != side_enum_get(item->type)) {
1320 fprintf(stderr, "ERROR: Unexpected enum element type\n");
1321 abort();
1322 }
1323 v = tracer_load_integer_value(&elem_type->u.side_integer,
1324 &item->u.side_static.integer_value, 0, NULL);
1325 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
1326 printf("%s", mappings->nr_attr ? ", " : "");
1327 printf("{ ");
1328 tracer_print_integer(elem_type, item, priv);
1329 printf(" }");
1330 print_enum_labels(mappings, v);
1331 }
1332
1333 static void tracer_print_enum_bitmap(const struct side_type *type_desc,
1334 const struct side_arg *item, void *priv __attribute__((unused)))
1335 {
1336 const struct side_enum_bitmap_mappings *side_enum_mappings = side_ptr_get(type_desc->u.side_enum_bitmap.mappings);
1337 const struct side_type *enum_elem_type = side_ptr_get(type_desc->u.side_enum_bitmap.elem_type), *elem_type;
1338 uint32_t i, print_count = 0, stride_bit, nr_items;
1339 const struct side_arg *array_item;
1340
1341 switch (side_enum_get(enum_elem_type->type)) {
1342 case SIDE_TYPE_U8: /* Fall-through */
1343 case SIDE_TYPE_BYTE: /* Fall-through */
1344 case SIDE_TYPE_U16: /* Fall-through */
1345 case SIDE_TYPE_U32: /* Fall-through */
1346 case SIDE_TYPE_U64: /* Fall-through */
1347 case SIDE_TYPE_U128: /* Fall-through */
1348 case SIDE_TYPE_S8: /* Fall-through */
1349 case SIDE_TYPE_S16: /* Fall-through */
1350 case SIDE_TYPE_S32: /* Fall-through */
1351 case SIDE_TYPE_S64: /* Fall-through */
1352 case SIDE_TYPE_S128:
1353 elem_type = enum_elem_type;
1354 array_item = item;
1355 nr_items = 1;
1356 break;
1357 case SIDE_TYPE_ARRAY:
1358 elem_type = side_ptr_get(enum_elem_type->u.side_array.elem_type);
1359 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_array)->sav);
1360 nr_items = type_desc->u.side_array.length;
1361 break;
1362 case SIDE_TYPE_VLA:
1363 elem_type = side_ptr_get(enum_elem_type->u.side_vla.elem_type);
1364 array_item = side_ptr_get(side_ptr_get(item->u.side_static.side_vla)->sav);
1365 nr_items = side_ptr_get(item->u.side_static.side_vla)->len;
1366 break;
1367 default:
1368 fprintf(stderr, "ERROR: Unexpected enum element type\n");
1369 abort();
1370 }
1371 stride_bit = elem_type_to_stride(elem_type);
1372
1373 print_attributes("attr", ":", side_ptr_get(side_enum_mappings->attr), side_enum_mappings->nr_attr);
1374 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
1375 printf("labels: [ ");
1376 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
1377 const struct side_enum_bitmap_mapping *mapping = &side_ptr_get(side_enum_mappings->mappings)[i];
1378 bool match = false;
1379 uint64_t bit;
1380
1381 if (mapping->range_end < mapping->range_begin) {
1382 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
1383 mapping->range_begin, mapping->range_end);
1384 abort();
1385 }
1386 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
1387 if (bit > (nr_items * stride_bit) - 1)
1388 break;
1389 if (side_enum_get(elem_type->type) == SIDE_TYPE_BYTE) {
1390 uint8_t v = array_item[bit / 8].u.side_static.byte_value;
1391 if (v & (1ULL << (bit % 8))) {
1392 match = true;
1393 goto match;
1394 }
1395 } else {
1396 union int_value v = {};
1397
1398 v = tracer_load_integer_value(&elem_type->u.side_integer,
1399 &array_item[bit / stride_bit].u.side_static.integer_value,
1400 0, NULL);
1401 side_check_value_u64(v);
1402 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (bit % stride_bit))) {
1403 match = true;
1404 goto match;
1405 }
1406 }
1407 }
1408 match:
1409 if (match) {
1410 printf("%s", print_count++ ? ", " : "");
1411 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
1412 side_enum_get(mapping->label.byte_order), NULL);
1413 }
1414 }
1415 if (!print_count)
1416 printf("<NO LABEL>");
1417 printf(" ]");
1418 }
1419
1420 static
1421 void tracer_print_gather_bool(const struct side_type_gather_bool *type,
1422 const union side_bool_value *value,
1423 void *priv __attribute__((unused)))
1424 {
1425 tracer_print_type_bool(":", &type->type, value, type->offset_bits);
1426 }
1427
1428 static
1429 void tracer_print_gather_byte(const struct side_type_gather_byte *type,
1430 const uint8_t *_ptr,
1431 void *priv __attribute__((unused)))
1432 {
1433 tracer_print_type_header("value", ":", side_ptr_get(type->type.attr),
1434 type->type.nr_attr);
1435 printf("0x%" PRIx8, *_ptr);
1436 }
1437
1438 static
1439 void tracer_print_gather_integer(const struct side_type_gather_integer *type,
1440 const union side_integer_value *value,
1441 void *priv __attribute__((unused)))
1442 {
1443 tracer_print_type_integer(":", &type->type, value, type->offset_bits, TRACER_DISPLAY_BASE_10);
1444 }
1445
1446 static
1447 void tracer_print_gather_pointer(const struct side_type_gather_integer *type,
1448 const union side_integer_value *value,
1449 void *priv __attribute__((unused)))
1450 {
1451 tracer_print_type_integer(":", &type->type, value, type->offset_bits, TRACER_DISPLAY_BASE_16);
1452 }
1453
1454 static
1455 void tracer_print_gather_float(const struct side_type_gather_float *type,
1456 const union side_float_value *value,
1457 void *priv __attribute__((unused)))
1458 {
1459 tracer_print_type_float(":", &type->type, value);
1460 }
1461
1462 static
1463 void tracer_print_gather_string(const struct side_type_gather_string *type,
1464 const void *p, uint8_t unit_size,
1465 enum side_type_label_byte_order byte_order,
1466 size_t strlen_with_null __attribute__((unused)),
1467 void *priv __attribute__((unused)))
1468 {
1469 //TODO use strlen_with_null input
1470 tracer_print_type_header("value", ":", side_ptr_get(type->type.attr),
1471 type->type.nr_attr);
1472 tracer_print_type_string(p, unit_size, byte_order, NULL);
1473 }
1474
1475 static
1476 void tracer_before_print_gather_struct(const struct side_type_struct *side_struct, void *priv)
1477 {
1478 tracer_before_print_struct(side_struct, NULL, priv);
1479 }
1480
1481 static
1482 void tracer_after_print_gather_struct(const struct side_type_struct *side_struct, void *priv)
1483 {
1484 tracer_after_print_struct(side_struct, NULL, priv);
1485 }
1486
1487 static
1488 void tracer_before_print_gather_array(const struct side_type_array *side_array, void *priv)
1489 {
1490 tracer_before_print_array(side_array, NULL, priv);
1491 }
1492
1493 static
1494 void tracer_after_print_gather_array(const struct side_type_array *side_array, void *priv)
1495 {
1496 tracer_after_print_array(side_array, NULL, priv);
1497 }
1498
1499 static
1500 void tracer_before_print_gather_vla(const struct side_type_vla *side_vla,
1501 uint32_t length __attribute__((unused)), void *priv)
1502 {
1503 switch (side_enum_get(side_ptr_get(side_vla->length_type)->type)) {
1504 case SIDE_TYPE_GATHER_INTEGER:
1505 break;
1506 default:
1507 fprintf(stderr, "ERROR: Unexpected vla length type\n");
1508 abort();
1509 }
1510 do_tracer_before_print_vla(side_vla, NULL, priv);
1511 }
1512
1513
1514 static
1515 void tracer_after_print_gather_vla(const struct side_type_vla *side_vla,
1516 uint32_t length __attribute__((unused)), void *priv)
1517 {
1518 do_tracer_after_print_vla(side_vla, NULL, priv);
1519 }
1520
1521 static
1522 void tracer_print_gather_enum(const struct side_type_gather_enum *type,
1523 const union side_integer_value *value,
1524 void *priv __attribute__((unused)))
1525 {
1526 const struct side_enum_mappings *mappings = side_ptr_get(type->mappings);
1527 const struct side_type *enum_elem_type = side_ptr_get(type->elem_type);
1528 const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer;
1529 union int_value v;
1530
1531 v = tracer_load_integer_value(&side_integer->type, value, 0, NULL);
1532 print_attributes("attr", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
1533 printf("%s", mappings->nr_attr ? ", " : "");
1534 printf("{ ");
1535 tracer_print_type_integer(":", &side_integer->type, value, 0, TRACER_DISPLAY_BASE_10);
1536 printf(" }");
1537 print_enum_labels(mappings, v);
1538 }
1539
1540 static
1541 void tracer_before_print_dynamic_field(const struct side_arg_dynamic_field *field, void *priv)
1542 {
1543 struct print_ctx *ctx = (struct print_ctx *) priv;
1544
1545 if (get_nested_item_nr(ctx) != 0)
1546 printf(",");
1547 printf(" %s:: { ", side_ptr_get(field->field_name));
1548 }
1549
1550 static
1551 void tracer_after_print_dynamic_field(const struct side_arg_dynamic_field *field __attribute__((unused)), void *priv)
1552 {
1553 struct print_ctx *ctx = (struct print_ctx *) priv;
1554
1555 printf(" }");
1556 inc_nested_item_nr(ctx);
1557 }
1558
1559 static
1560 void tracer_before_print_dynamic_elem(const struct side_arg *dynamic_item __attribute__((unused)), void *priv)
1561 {
1562 tracer_before_print_elem(NULL, priv);
1563 }
1564
1565 static
1566 void tracer_after_print_dynamic_elem(const struct side_arg *dynamic_item __attribute__((unused)), void *priv)
1567 {
1568 tracer_after_print_elem(NULL, priv);
1569 }
1570
1571 static
1572 void tracer_print_dynamic_null(const struct side_arg *item,
1573 void *priv __attribute__((unused)))
1574 {
1575 tracer_print_type_header("value", "::", side_ptr_get(item->u.side_dynamic.side_null.attr),
1576 item->u.side_dynamic.side_null.nr_attr);
1577 printf("<NULL TYPE>");
1578 }
1579
1580 static
1581 void tracer_print_dynamic_bool(const struct side_arg *item,
1582 void *priv __attribute__((unused)))
1583 {
1584 tracer_print_type_bool("::", &item->u.side_dynamic.side_bool.type, &item->u.side_dynamic.side_bool.value, 0);
1585 }
1586
1587 static
1588 void tracer_print_dynamic_integer(const struct side_arg *item,
1589 void *priv __attribute__((unused)))
1590 {
1591 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
1592 TRACER_DISPLAY_BASE_10);
1593 }
1594
1595 static
1596 void tracer_print_dynamic_byte(const struct side_arg *item,
1597 void *priv __attribute__((unused)))
1598 {
1599 tracer_print_type_header("value", "::", side_ptr_get(item->u.side_dynamic.side_byte.type.attr), item->u.side_dynamic.side_byte.type.nr_attr);
1600 printf("0x%" PRIx8, item->u.side_dynamic.side_byte.value);
1601 }
1602
1603 static
1604 void tracer_print_dynamic_pointer(const struct side_arg *item,
1605 void *priv __attribute__((unused)))
1606 {
1607 tracer_print_type_integer("::", &item->u.side_dynamic.side_integer.type, &item->u.side_dynamic.side_integer.value, 0,
1608 TRACER_DISPLAY_BASE_16);
1609 }
1610
1611 static
1612 void tracer_print_dynamic_float(const struct side_arg *item,
1613 void *priv __attribute__((unused)))
1614 {
1615 tracer_print_type_float("::", &item->u.side_dynamic.side_float.type,
1616 &item->u.side_dynamic.side_float.value);
1617 }
1618
1619 static
1620 void tracer_print_dynamic_string(const struct side_arg *item,
1621 void *priv __attribute__((unused)))
1622 {
1623 tracer_print_type_header("value", "::", side_ptr_get(item->u.side_dynamic.side_string.type.attr), item->u.side_dynamic.side_string.type.nr_attr);
1624 tracer_print_type_string((const char *)(uintptr_t) item->u.side_dynamic.side_string.value,
1625 item->u.side_dynamic.side_string.type.unit_size,
1626 side_enum_get(item->u.side_dynamic.side_string.type.byte_order), NULL);
1627 }
1628
1629 static
1630 void tracer_before_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct,
1631 void *priv)
1632 {
1633 struct print_ctx *ctx = (struct print_ctx *) priv;
1634
1635 print_attributes("attr", "::", side_ptr_get(dynamic_struct->attr), dynamic_struct->nr_attr);
1636 printf("%s", dynamic_struct->nr_attr ? ", " : "");
1637 printf("fields:: {");
1638 push_nesting(ctx);
1639 }
1640
1641 static
1642 void tracer_after_print_dynamic_struct(const struct side_arg_dynamic_struct *dynamic_struct __attribute__((unused)),
1643 void *priv)
1644 {
1645 struct print_ctx *ctx = (struct print_ctx *) priv;
1646
1647 pop_nesting(ctx);
1648 printf(" }");
1649 }
1650
1651 static
1652 void tracer_before_print_dynamic_struct_visitor(const struct side_arg *item, void *priv)
1653 {
1654 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
1655 struct print_ctx *ctx = (struct print_ctx *) priv;
1656
1657 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
1658 if (!dynamic_struct_visitor)
1659 abort();
1660
1661 print_attributes("attr", "::", side_ptr_get(dynamic_struct_visitor->attr), dynamic_struct_visitor->nr_attr);
1662 printf("%s", dynamic_struct_visitor->nr_attr ? ", " : "");
1663 printf("fields:: {");
1664 push_nesting(ctx);
1665 }
1666
1667 static
1668 void tracer_after_print_dynamic_struct_visitor(const struct side_arg *item, void *priv)
1669 {
1670 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
1671 struct print_ctx *ctx = (struct print_ctx *) priv;
1672
1673 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
1674 if (!dynamic_struct_visitor)
1675 abort();
1676
1677 pop_nesting(ctx);
1678 printf(" }");
1679 }
1680
1681 static
1682 void tracer_before_print_dynamic_vla(const struct side_arg_dynamic_vla *dynamic_vla, void *priv)
1683 {
1684 struct print_ctx *ctx = (struct print_ctx *) priv;
1685
1686 print_attributes("attr", "::", side_ptr_get(dynamic_vla->attr), dynamic_vla->nr_attr);
1687 printf("%s", dynamic_vla->nr_attr ? ", " : "");
1688 printf("elements:: [");
1689 push_nesting(ctx);
1690 }
1691
1692 static
1693 void tracer_after_print_dynamic_vla(const struct side_arg_dynamic_vla *dynamic_vla __attribute__((unused)), void *priv)
1694 {
1695 struct print_ctx *ctx = (struct print_ctx *) priv;
1696
1697 pop_nesting(ctx);
1698 printf(" ]");
1699 }
1700
1701 static
1702 void tracer_before_print_dynamic_vla_visitor(const struct side_arg *item, void *priv)
1703 {
1704 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
1705 struct print_ctx *ctx = (struct print_ctx *) priv;
1706
1707 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
1708 if (!dynamic_vla_visitor)
1709 abort();
1710
1711 print_attributes("attr", "::", side_ptr_get(dynamic_vla_visitor->attr), dynamic_vla_visitor->nr_attr);
1712 printf("%s", dynamic_vla_visitor->nr_attr ? ", " : "");
1713 printf("elements:: [");
1714 push_nesting(ctx);
1715 }
1716
1717 static
1718 void tracer_after_print_dynamic_vla_visitor(const struct side_arg *item, void *priv)
1719 {
1720 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
1721 struct print_ctx *ctx = (struct print_ctx *) priv;
1722
1723 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
1724 if (!dynamic_vla_visitor)
1725 abort();
1726
1727 pop_nesting(ctx);
1728 printf(" ]");
1729 }
1730
1731 static struct side_type_visitor type_visitor = {
1732 .before_event_func = tracer_before_print_event,
1733 .after_event_func = tracer_after_print_event,
1734 .before_static_fields_func = tracer_before_print_static_fields,
1735 .after_static_fields_func = tracer_after_print_static_fields,
1736 .before_variadic_fields_func = tracer_before_print_variadic_fields,
1737 .after_variadic_fields_func = tracer_after_print_variadic_fields,
1738
1739 /* Stack-copy basic types. */
1740 .before_field_func = tracer_before_print_field,
1741 .after_field_func = tracer_after_print_field,
1742 .before_elem_func = tracer_before_print_elem,
1743 .after_elem_func = tracer_after_print_elem,
1744 .null_type_func = tracer_print_null,
1745 .bool_type_func = tracer_print_bool,
1746 .integer_type_func = tracer_print_integer,
1747 .byte_type_func = tracer_print_byte,
1748 .pointer_type_func = tracer_print_pointer,
1749 .float_type_func = tracer_print_float,
1750 .string_type_func = tracer_print_string,
1751
1752 /* Stack-copy compound types. */
1753 .before_struct_type_func = tracer_before_print_struct,
1754 .after_struct_type_func = tracer_after_print_struct,
1755 .before_array_type_func = tracer_before_print_array,
1756 .after_array_type_func = tracer_after_print_array,
1757 .before_vla_type_func = tracer_before_print_vla,
1758 .after_vla_type_func = tracer_after_print_vla,
1759 .before_vla_visitor_type_func = tracer_before_print_vla_visitor,
1760 .after_vla_visitor_type_func = tracer_after_print_vla_visitor,
1761
1762 /* Stack-copy enumeration types. */
1763 .enum_type_func = tracer_print_enum,
1764 .enum_bitmap_type_func = tracer_print_enum_bitmap,
1765
1766 /* Gather basic types. */
1767 .gather_bool_type_func = tracer_print_gather_bool,
1768 .gather_byte_type_func = tracer_print_gather_byte,
1769 .gather_integer_type_func = tracer_print_gather_integer,
1770 .gather_pointer_type_func = tracer_print_gather_pointer,
1771 .gather_float_type_func = tracer_print_gather_float,
1772 .gather_string_type_func = tracer_print_gather_string,
1773
1774 /* Gather compound types. */
1775 .before_gather_struct_type_func = tracer_before_print_gather_struct,
1776 .after_gather_struct_type_func = tracer_after_print_gather_struct,
1777 .before_gather_array_type_func = tracer_before_print_gather_array,
1778 .after_gather_array_type_func = tracer_after_print_gather_array,
1779 .before_gather_vla_type_func = tracer_before_print_gather_vla,
1780 .after_gather_vla_type_func = tracer_after_print_gather_vla,
1781
1782 /* Gather enumeration types. */
1783 .gather_enum_type_func = tracer_print_gather_enum,
1784
1785 /* Dynamic basic types. */
1786 .before_dynamic_field_func = tracer_before_print_dynamic_field,
1787 .after_dynamic_field_func = tracer_after_print_dynamic_field,
1788 .before_dynamic_elem_func = tracer_before_print_dynamic_elem,
1789 .after_dynamic_elem_func = tracer_after_print_dynamic_elem,
1790
1791 .dynamic_null_func = tracer_print_dynamic_null,
1792 .dynamic_bool_func = tracer_print_dynamic_bool,
1793 .dynamic_integer_func = tracer_print_dynamic_integer,
1794 .dynamic_byte_func = tracer_print_dynamic_byte,
1795 .dynamic_pointer_func = tracer_print_dynamic_pointer,
1796 .dynamic_float_func = tracer_print_dynamic_float,
1797 .dynamic_string_func = tracer_print_dynamic_string,
1798
1799 /* Dynamic compound types. */
1800 .before_dynamic_struct_func = tracer_before_print_dynamic_struct,
1801 .after_dynamic_struct_func = tracer_after_print_dynamic_struct,
1802 .before_dynamic_struct_visitor_func = tracer_before_print_dynamic_struct_visitor,
1803 .after_dynamic_struct_visitor_func = tracer_after_print_dynamic_struct_visitor,
1804 .before_dynamic_vla_func = tracer_before_print_dynamic_vla,
1805 .after_dynamic_vla_func = tracer_after_print_dynamic_vla,
1806 .before_dynamic_vla_visitor_func = tracer_before_print_dynamic_vla_visitor,
1807 .after_dynamic_vla_visitor_func = tracer_after_print_dynamic_vla_visitor,
1808 };
1809
1810 static
1811 void tracer_call(const struct side_event_description *desc,
1812 const struct side_arg_vec *side_arg_vec,
1813 void *priv __attribute__((unused)),
1814 void *caller_addr)
1815 {
1816 struct print_ctx ctx = {};
1817
1818 type_visitor_event(&type_visitor, desc, side_arg_vec, NULL, caller_addr, &ctx);
1819 }
1820
1821 static
1822 void tracer_call_variadic(const struct side_event_description *desc,
1823 const struct side_arg_vec *side_arg_vec,
1824 const struct side_arg_dynamic_struct *var_struct,
1825 void *priv __attribute__((unused)),
1826 void *caller_addr)
1827 {
1828 struct print_ctx ctx = {};
1829
1830 type_visitor_event(&type_visitor, desc, side_arg_vec, var_struct, caller_addr, &ctx);
1831 }
1832
1833 static
1834 void before_print_description_event(const struct side_event_description *desc, void *priv __attribute__((unused)))
1835 {
1836 printf("event description: provider: %s, event: %s", side_ptr_get(desc->provider_name), side_ptr_get(desc->event_name));
1837 print_attributes(", attr", ":", side_ptr_get(desc->attr), desc->nr_attr);
1838 }
1839
1840 static
1841 void after_print_description_event(const struct side_event_description *desc, void *priv __attribute__((unused)))
1842 {
1843 if (desc->flags & SIDE_EVENT_FLAG_VARIADIC)
1844 printf(", <variadic fields>");
1845 printf("\n");
1846 }
1847
1848 static
1849 void before_print_description_static_fields(const struct side_event_description *desc, void *priv)
1850 {
1851 struct print_ctx *ctx = (struct print_ctx *) priv;
1852 uint32_t len = desc->nr_fields;
1853
1854 printf("%s", len ? ", fields: {" : "");
1855 push_nesting(ctx);
1856 }
1857
1858 static
1859 void after_print_description_static_fields(const struct side_event_description *desc, void *priv)
1860 {
1861 struct print_ctx *ctx = (struct print_ctx *) priv;
1862 uint32_t len = desc->nr_fields;
1863
1864 pop_nesting(ctx);
1865 if (len)
1866 printf(" }");
1867 }
1868
1869 static
1870 void before_print_description_field(const struct side_event_field *item_desc, void *priv)
1871 {
1872 struct print_ctx *ctx = (struct print_ctx *) priv;
1873
1874 if (get_nested_item_nr(ctx) != 0)
1875 printf(",");
1876 printf(" %s: { ", side_ptr_get(item_desc->field_name));
1877 }
1878
1879 static
1880 void after_print_description_field(const struct side_event_field *item_desc __attribute__((unused)), void *priv)
1881 {
1882 struct print_ctx *ctx = (struct print_ctx *) priv;
1883
1884 printf(" }");
1885 inc_nested_item_nr(ctx);
1886 }
1887
1888 static
1889 void before_print_description_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1890 {
1891 struct print_ctx *ctx = (struct print_ctx *) priv;
1892
1893 if (get_nested_item_nr(ctx) != 0)
1894 printf(", { ");
1895 else
1896 printf(" { ");
1897 }
1898
1899 static
1900 void after_print_description_elem(const struct side_type *type_desc __attribute__((unused)), void *priv)
1901 {
1902 struct print_ctx *ctx = (struct print_ctx *) priv;
1903
1904 printf(" }");
1905 inc_nested_item_nr(ctx);
1906 }
1907
1908 static
1909 void before_print_description_option(const struct side_variant_option *option_desc, void *priv)
1910 {
1911 struct print_ctx *ctx = (struct print_ctx *) priv;
1912
1913 if (get_nested_item_nr(ctx) != 0)
1914 printf(",");
1915 if (option_desc->range_begin == option_desc->range_end)
1916 printf(" [ %" PRIu64 " ]: { ",
1917 option_desc->range_begin);
1918 else
1919 printf(" [ %" PRIu64 " - %" PRIu64 " ]: { ",
1920 option_desc->range_begin,
1921 option_desc->range_end);
1922 }
1923
1924 static
1925 void after_print_description_option(const struct side_variant_option *option_desc __attribute__((unused)), void *priv)
1926 {
1927 struct print_ctx *ctx = (struct print_ctx *) priv;
1928
1929 printf(" }");
1930 inc_nested_item_nr(ctx);
1931 }
1932
1933 static
1934 void print_description_null(const struct side_type *type_desc,
1935 void *priv __attribute__((unused)))
1936 {
1937 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_null.attr),
1938 type_desc->u.side_null.nr_attr);
1939 printf("null");
1940 }
1941
1942 static
1943 void print_description_bool(const struct side_type *type_desc,
1944 void *priv __attribute__((unused)))
1945 {
1946 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_bool.attr),
1947 type_desc->u.side_bool.nr_attr);
1948 printf("bool { size: %" PRIu16, type_desc->u.side_bool.bool_size);
1949 if (type_desc->u.side_bool.len_bits)
1950 printf(", len_bits: %" PRIu16, type_desc->u.side_bool.len_bits);
1951 printf(" }");
1952 }
1953
1954 static
1955 void print_description_integer(const struct side_type *type_desc,
1956 void *priv __attribute__((unused)))
1957 {
1958 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_integer.attr),
1959 type_desc->u.side_integer.nr_attr);
1960 printf("integer { size: %" PRIu16 ", signedness: %s, byte_order: \"%s\"",
1961 type_desc->u.side_integer.integer_size,
1962 type_desc->u.side_integer.signedness ? "true" : "false",
1963 side_enum_get(type_desc->u.side_integer.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
1964 if (type_desc->u.side_integer.len_bits)
1965 printf(", len_bits: %" PRIu16, type_desc->u.side_integer.len_bits);
1966 printf(" }");
1967 }
1968
1969 static
1970 void print_description_byte(const struct side_type *type_desc,
1971 void *priv __attribute__((unused)))
1972 {
1973 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_byte.attr),
1974 type_desc->u.side_byte.nr_attr);
1975 printf("byte");
1976 }
1977
1978 static
1979 void print_description_pointer(const struct side_type *type_desc,
1980 void *priv __attribute__((unused)))
1981 {
1982 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_integer.attr),
1983 type_desc->u.side_integer.nr_attr);
1984 printf("pointer { size: %" PRIu16 ", signedness: %s, byte_order: \"%s\"",
1985 type_desc->u.side_integer.integer_size,
1986 type_desc->u.side_integer.signedness ? "true" : "false",
1987 side_enum_get(type_desc->u.side_integer.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
1988 if (type_desc->u.side_integer.len_bits)
1989 printf(", len_bits: %" PRIu16, type_desc->u.side_integer.len_bits);
1990 printf(" }");
1991 }
1992
1993 static
1994 void print_description_float(const struct side_type *type_desc,
1995 void *priv __attribute__((unused)))
1996 {
1997 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_float.attr),
1998 type_desc->u.side_float.nr_attr);
1999 printf("float { size: %" PRIu16 ", byte_order: \"%s\"",
2000 type_desc->u.side_float.float_size,
2001 side_enum_get(type_desc->u.side_float.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
2002 printf(" }");
2003 }
2004
2005 static
2006 void print_description_string(const struct side_type *type_desc,
2007 void *priv __attribute__((unused)))
2008 {
2009 tracer_print_type_header("type", ":", side_ptr_get(type_desc->u.side_string.attr),
2010 type_desc->u.side_string.nr_attr);
2011 printf("string { unit_size: %" PRIu8,
2012 type_desc->u.side_string.unit_size);
2013 if (type_desc->u.side_string.unit_size > 1)
2014 printf(", byte_order: \"%s\"",
2015 side_enum_get(type_desc->u.side_string.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
2016 printf(" }");
2017 }
2018
2019 static
2020 void before_print_description_struct(const struct side_type_struct *side_struct, void *priv)
2021 {
2022 struct print_ctx *ctx = (struct print_ctx *) priv;
2023
2024 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
2025 printf("%s", side_struct->nr_attr ? ", " : "");
2026 printf("type: struct { fields: {");
2027 push_nesting(ctx);
2028 }
2029
2030
2031 static
2032 void after_print_description_struct(const struct side_type_struct *side_struct __attribute__((unused)), void *priv)
2033 {
2034 struct print_ctx *ctx = (struct print_ctx *) priv;
2035
2036 pop_nesting(ctx);
2037 printf(" } }");
2038 }
2039
2040 static
2041 void before_print_description_variant(const struct side_type_variant *side_variant, void *priv)
2042 {
2043 struct print_ctx *ctx = (struct print_ctx *) priv;
2044
2045 print_attributes("attr", ":", side_ptr_get(side_variant->attr), side_variant->nr_attr);
2046 printf("%s", side_variant->nr_attr ? ", " : "");
2047 printf("type: variant { options: {");
2048 push_nesting(ctx);
2049 }
2050
2051 static
2052 void after_print_description_variant(const struct side_type_variant *side_variant __attribute__((unused)), void *priv)
2053 {
2054 struct print_ctx *ctx = (struct print_ctx *) priv;
2055
2056 pop_nesting(ctx);
2057 printf(" } }");
2058 }
2059
2060 static
2061 void before_print_description_array(const struct side_type_array *side_array, void *priv)
2062 {
2063 struct print_ctx *ctx = (struct print_ctx *) priv;
2064
2065 print_attributes("attr", ":", side_ptr_get(side_array->attr), side_array->nr_attr);
2066 printf("%s", side_array->nr_attr ? ", " : "");
2067 printf("type: array { length: %" PRIu32 ", element:", side_array->length);
2068 push_nesting(ctx);
2069 }
2070
2071
2072 static
2073 void after_print_description_array(const struct side_type_array *side_array __attribute__((unused)), void *priv)
2074 {
2075 struct print_ctx *ctx = (struct print_ctx *) priv;
2076
2077 pop_nesting(ctx);
2078 printf(" }");
2079 }
2080
2081 static
2082 void before_print_description_vla(const struct side_type_vla *side_vla, void *priv)
2083 {
2084 struct print_ctx *ctx = (struct print_ctx *) priv;
2085
2086 print_attributes("attr", ":", side_ptr_get(side_vla->attr), side_vla->nr_attr);
2087 printf("%s", side_vla->nr_attr ? ", " : "");
2088 printf("type: vla { length:");
2089 push_nesting(ctx);
2090 }
2091
2092 static
2093 void after_length_print_description_vla(const struct side_type_vla *side_vla __attribute__((unused)), void *priv)
2094 {
2095 struct print_ctx *ctx = (struct print_ctx *) priv;
2096
2097 pop_nesting(ctx);
2098 printf(", element:");
2099 push_nesting(ctx);
2100 }
2101
2102 static
2103 void after_element_print_description_vla(const struct side_type_vla *side_vla __attribute__((unused)), void *priv)
2104 {
2105 struct print_ctx *ctx = (struct print_ctx *) priv;
2106
2107 pop_nesting(ctx);
2108 printf(" }");
2109 }
2110
2111 static
2112 void before_print_description_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor, void *priv)
2113 {
2114 struct print_ctx *ctx = (struct print_ctx *) priv;
2115
2116 print_attributes("attr", ":", side_ptr_get(side_vla_visitor->attr), side_vla_visitor->nr_attr);
2117 printf("%s", side_vla_visitor->nr_attr ? ", " : "");
2118 printf("type: vla_visitor { length:");
2119 push_nesting(ctx);
2120 }
2121
2122 static
2123 void after_length_print_description_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor __attribute__((unused)), void *priv)
2124 {
2125 struct print_ctx *ctx = (struct print_ctx *) priv;
2126
2127 pop_nesting(ctx);
2128 printf(", element:");
2129 push_nesting(ctx);
2130 }
2131
2132 static
2133 void after_element_print_description_vla_visitor(const struct side_type_vla_visitor *side_vla_visitor __attribute__((unused)), void *priv)
2134 {
2135 struct print_ctx *ctx = (struct print_ctx *) priv;
2136
2137 pop_nesting(ctx);
2138 printf(" }");
2139 }
2140
2141 static
2142 void do_before_print_description_enum(const char *type_name, const struct side_enum_mappings *mappings, void *priv __attribute__((unused)))
2143 {
2144 uint32_t i, print_count = 0;
2145
2146 tracer_print_type_header("type", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
2147 printf("%s { labels: { ", type_name);
2148 for (i = 0; i < mappings->nr_mappings; i++) {
2149 const struct side_enum_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
2150
2151 if (mapping->range_end < mapping->range_begin) {
2152 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
2153 mapping->range_begin, mapping->range_end);
2154 abort();
2155 }
2156 printf("%s", print_count++ ? ", " : "");
2157 if (mapping->range_begin == mapping->range_end)
2158 printf("[ %" PRIu64 " ]: ", mapping->range_begin);
2159 else
2160 printf("[ %" PRIu64 " - %" PRIu64 " ]: ",
2161 mapping->range_begin, mapping->range_end);
2162 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
2163 side_enum_get(mapping->label.byte_order), NULL);
2164 }
2165 if (!print_count)
2166 printf("<NO LABEL>");
2167
2168 printf(" }, element: { ");
2169 }
2170
2171
2172 static
2173 void do_after_print_description_enum(const char *type_name __attribute__((unused)), const struct side_enum_mappings *mappings __attribute__((unused)), void *priv __attribute__((unused)))
2174 {
2175 printf(" }");
2176 }
2177
2178 static
2179 void before_print_description_enum(const struct side_type *type_desc, void *priv)
2180 {
2181 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
2182 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum.elem_type);
2183
2184 switch (side_enum_get(elem_type->type)) {
2185 case SIDE_TYPE_U8:
2186 case SIDE_TYPE_U16:
2187 case SIDE_TYPE_U32:
2188 case SIDE_TYPE_U64:
2189 case SIDE_TYPE_U128:
2190 case SIDE_TYPE_S8:
2191 case SIDE_TYPE_S16:
2192 case SIDE_TYPE_S32:
2193 case SIDE_TYPE_S64:
2194 case SIDE_TYPE_S128:
2195 break;
2196 default:
2197 fprintf(stderr, "Unsupported enum element type.\n");
2198 abort();
2199 }
2200 do_before_print_description_enum("enum", mappings, priv);
2201 }
2202
2203 static
2204 void after_print_description_enum(const struct side_type *type_desc, void *priv)
2205 {
2206 const struct side_enum_mappings *mappings = side_ptr_get(type_desc->u.side_enum.mappings);
2207
2208 do_after_print_description_enum("enum", mappings, priv);
2209 }
2210
2211 static
2212 void before_print_description_enum_bitmap(const struct side_type *type_desc, void *priv __attribute__((unused)))
2213 {
2214 const struct side_type *elem_type = side_ptr_get(type_desc->u.side_enum_bitmap.elem_type);
2215 const struct side_enum_bitmap_mappings *mappings = side_ptr_get(type_desc->u.side_enum_bitmap.mappings);
2216 uint32_t i, print_count = 0;
2217
2218 switch (side_enum_get(elem_type->type)) {
2219 case SIDE_TYPE_BYTE:
2220 case SIDE_TYPE_U8:
2221 case SIDE_TYPE_U16:
2222 case SIDE_TYPE_U32:
2223 case SIDE_TYPE_U64:
2224 case SIDE_TYPE_U128:
2225 case SIDE_TYPE_ARRAY:
2226 case SIDE_TYPE_VLA:
2227 break;
2228 default:
2229 fprintf(stderr, "Unsupported enum element type.\n");
2230 abort();
2231 }
2232 tracer_print_type_header("type", ":", side_ptr_get(mappings->attr), mappings->nr_attr);
2233 printf("enum_bitmap { labels: { ");
2234 for (i = 0; i < mappings->nr_mappings; i++) {
2235 const struct side_enum_bitmap_mapping *mapping = &side_ptr_get(mappings->mappings)[i];
2236
2237 if (mapping->range_end < mapping->range_begin) {
2238 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
2239 mapping->range_begin, mapping->range_end);
2240 abort();
2241 }
2242 printf("%s", print_count++ ? ", " : "");
2243 if (mapping->range_begin == mapping->range_end)
2244 printf("[ %" PRIu64 " ]: ", mapping->range_begin);
2245 else
2246 printf("[ %" PRIu64 " - %" PRIu64 " ]: ",
2247 mapping->range_begin, mapping->range_end);
2248 tracer_print_type_string(side_ptr_get(mapping->label.p), mapping->label.unit_size,
2249 side_enum_get(mapping->label.byte_order), NULL);
2250 }
2251 if (!print_count)
2252 printf("<NO LABEL>");
2253
2254 printf(" }, element: { ");
2255 }
2256
2257 static
2258 void after_print_description_enum_bitmap(const struct side_type *type_desc __attribute__((unused)), void *priv __attribute__((unused)))
2259 {
2260 printf(" }");
2261 }
2262
2263 static
2264 void print_description_gather_bool(const struct side_type_gather_bool *type,
2265 void *priv __attribute__((unused)))
2266 {
2267 tracer_print_type_header("type", ":", side_ptr_get(type->type.attr),
2268 type->type.nr_attr);
2269 printf("gather_bool { size: %" PRIu16, type->type.bool_size);
2270 if (type->type.len_bits)
2271 printf(", len_bits: %" PRIu16, type->type.len_bits);
2272 printf(", offset: %" PRIu64 ", offset_bits: %" PRIu16 ", access_mode: %s",
2273 type->offset, type->offset_bits,
2274 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2275 printf(" }");
2276 }
2277
2278 static
2279 void print_description_gather_byte(const struct side_type_gather_byte *type,
2280 void *priv __attribute__((unused)))
2281 {
2282 tracer_print_type_header("type", ":", side_ptr_get(type->type.attr),
2283 type->type.nr_attr);
2284 printf("gather_byte { offset: %" PRIu64 ", access_mode: %s }",
2285 type->offset,
2286 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2287 }
2288
2289 static
2290 void print_description_gather_integer(const struct side_type_gather_integer *type,
2291 void *priv __attribute__((unused)))
2292 {
2293 tracer_print_type_header("type", ":", side_ptr_get(type->type.attr),
2294 type->type.nr_attr);
2295 printf("gather_integer { size: %" PRIu16 ", signedness: %s, byte_order: \"%s\"",
2296 type->type.integer_size,
2297 type->type.signedness ? "true" : "false",
2298 side_enum_get(type->type.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
2299 if (type->type.len_bits)
2300 printf(", len_bits: %" PRIu16, type->type.len_bits);
2301 printf(", offset: %" PRIu64 ", offset_bits: %" PRIu16 ", access_mode: %s",
2302 type->offset, type->offset_bits,
2303 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2304 printf(" }");
2305 }
2306
2307 static
2308 void print_description_gather_pointer(const struct side_type_gather_integer *type,
2309 void *priv __attribute__((unused)))
2310 {
2311 tracer_print_type_header("type", ":", side_ptr_get(type->type.attr),
2312 type->type.nr_attr);
2313 printf("gather_pointer { size: %" PRIu16 ", signedness: %s, byte_order: \"%s\"",
2314 type->type.integer_size,
2315 type->type.signedness ? "true" : "false",
2316 side_enum_get(type->type.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
2317 if (type->type.len_bits)
2318 printf(", len_bits: %" PRIu16, type->type.len_bits);
2319 printf(", offset: %" PRIu64 ", offset_bits: %" PRIu16 ", access_mode: %s",
2320 type->offset, type->offset_bits,
2321 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2322 printf(" }");
2323 }
2324
2325 static
2326 void print_description_gather_float(const struct side_type_gather_float *type,
2327 void *priv __attribute__((unused)))
2328 {
2329 tracer_print_type_header("type", ":", side_ptr_get(type->type.attr),
2330 type->type.nr_attr);
2331 printf("gather_float { size: %" PRIu16 ", byte_order: \"%s\"",
2332 type->type.float_size,
2333 side_enum_get(type->type.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
2334 printf(", offset: %" PRIu64 ", access_mode: %s",
2335 type->offset,
2336 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2337 printf(" }");
2338 }
2339
2340 static
2341 void print_description_gather_string(const struct side_type_gather_string *type,
2342 void *priv __attribute__((unused)))
2343 {
2344 tracer_print_type_header("type", ":", side_ptr_get(type->type.attr),
2345 type->type.nr_attr);
2346 printf("gather_string { unit_size: %" PRIu8,
2347 type->type.unit_size);
2348 if (type->type.unit_size > 1)
2349 printf(", byte_order: \"%s\"",
2350 side_enum_get(type->type.byte_order) == SIDE_TYPE_BYTE_ORDER_LE ? "le" : "be");
2351 printf(", offset: %" PRIu64 ", access_mode: %s",
2352 type->offset,
2353 side_enum_get(type->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2354 printf(" }");
2355 }
2356
2357 static
2358 void before_print_description_gather_struct(const struct side_type_gather_struct *side_gather_struct, void *priv)
2359 {
2360 const struct side_type_struct *side_struct = side_ptr_get(side_gather_struct->type);
2361 struct print_ctx *ctx = (struct print_ctx *) priv;
2362
2363 print_attributes("attr", ":", side_ptr_get(side_struct->attr), side_struct->nr_attr);
2364 printf("%s", side_struct->nr_attr ? ", " : "");
2365 printf("type: gather_struct { size: %" PRIu32 ", offset: %" PRIu64 ", access_mode: %s, fields: {",
2366 side_gather_struct->size, side_gather_struct->offset,
2367 side_enum_get(side_gather_struct->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2368 push_nesting(ctx);
2369 }
2370
2371 static
2372 void after_print_description_gather_struct(const struct side_type_gather_struct *side_gather_struct __attribute__((unused)), void *priv)
2373 {
2374 struct print_ctx *ctx = (struct print_ctx *) priv;
2375
2376 pop_nesting(ctx);
2377 printf(" } }");
2378 }
2379
2380 static
2381 void before_print_description_gather_array(const struct side_type_gather_array *side_gather_array, void *priv)
2382 {
2383 const struct side_type_array *side_array = &side_gather_array->type;
2384 struct print_ctx *ctx = (struct print_ctx *) priv;
2385
2386 print_attributes("attr", ":", side_ptr_get(side_array->attr), side_array->nr_attr);
2387 printf("%s", side_array->nr_attr ? ", " : "");
2388 printf("type: gather_array { offset: %" PRIu64 ", access_mode: %s, element:",
2389 side_gather_array->offset,
2390 side_enum_get(side_gather_array->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2391 push_nesting(ctx);
2392 }
2393
2394 static
2395 void after_print_description_gather_array(const struct side_type_gather_array *side_gather_array __attribute__((unused)), void *priv)
2396 {
2397 struct print_ctx *ctx = (struct print_ctx *) priv;
2398
2399 pop_nesting(ctx);
2400 printf(" }");
2401 }
2402
2403 static
2404 void before_print_description_gather_vla(const struct side_type_gather_vla *side_gather_vla, void *priv)
2405 {
2406 const struct side_type_vla *side_vla = &side_gather_vla->type;
2407 struct print_ctx *ctx = (struct print_ctx *) priv;
2408
2409 print_attributes("attr", ":", side_ptr_get(side_vla->attr), side_vla->nr_attr);
2410 printf("%s", side_vla->nr_attr ? ", " : "");
2411 printf("type: gather_vla { offset: %" PRIu64 ", access_mode: %s, length:",
2412 side_gather_vla->offset,
2413 side_enum_get(side_gather_vla->access_mode) == SIDE_TYPE_GATHER_ACCESS_DIRECT ? "\"direct\"" : "\"pointer\"");
2414 push_nesting(ctx);
2415 }
2416
2417 static
2418 void after_length_print_description_gather_vla(const struct side_type_gather_vla *side_gather_vla __attribute__((unused)), void *priv)
2419 {
2420 struct print_ctx *ctx = (struct print_ctx *) priv;
2421
2422 pop_nesting(ctx);
2423 printf(", element:");
2424 push_nesting(ctx);
2425 }
2426
2427 static
2428 void after_element_print_description_gather_vla(const struct side_type_gather_vla *side_gather_vla __attribute__((unused)), void *priv)
2429 {
2430 struct print_ctx *ctx = (struct print_ctx *) priv;
2431
2432 pop_nesting(ctx);
2433 printf(" }");
2434 }
2435
2436 static
2437 void before_print_description_gather_enum(const struct side_type_gather_enum *type, void *priv)
2438 {
2439 const struct side_enum_mappings *mappings = side_ptr_get(type->mappings);
2440 const struct side_type *elem_type = side_ptr_get(type->elem_type);
2441
2442 if (side_enum_get(elem_type->type) != SIDE_TYPE_GATHER_INTEGER) {
2443 fprintf(stderr, "Unsupported enum element type.\n");
2444 abort();
2445 }
2446 do_before_print_description_enum("gather_enum", mappings, priv);
2447 }
2448
2449 static
2450 void after_print_description_gather_enum(const struct side_type_gather_enum *type, void *priv)
2451 {
2452 const struct side_enum_mappings *mappings = side_ptr_get(type->mappings);
2453
2454 do_after_print_description_enum("gather_enum", mappings, priv);
2455 }
2456
2457 static
2458 void print_description_dynamic(const struct side_type *type_desc __attribute__((unused)), void *priv __attribute__((unused)))
2459 {
2460 printf("type: dynamic");
2461 }
2462
2463 static
2464 struct side_description_visitor description_visitor = {
2465 .before_event_func = before_print_description_event,
2466 .after_event_func = after_print_description_event,
2467 .before_static_fields_func = before_print_description_static_fields,
2468 .after_static_fields_func = after_print_description_static_fields,
2469
2470 /* Stack-copy basic types. */
2471 .before_field_func = before_print_description_field,
2472 .after_field_func = after_print_description_field,
2473 .before_elem_func = before_print_description_elem,
2474 .after_elem_func = after_print_description_elem,
2475 .before_option_func = before_print_description_option,
2476 .after_option_func = after_print_description_option,
2477 .null_type_func = print_description_null,
2478 .bool_type_func = print_description_bool,
2479 .integer_type_func = print_description_integer,
2480 .byte_type_func = print_description_byte,
2481 .pointer_type_func = print_description_pointer,
2482 .float_type_func = print_description_float,
2483 .string_type_func = print_description_string,
2484
2485 /* Stack-copy compound types. */
2486 .before_struct_type_func = before_print_description_struct,
2487 .after_struct_type_func = after_print_description_struct,
2488 .before_variant_type_func = before_print_description_variant,
2489 .after_variant_type_func = after_print_description_variant,
2490 .before_array_type_func = before_print_description_array,
2491 .after_array_type_func = after_print_description_array,
2492 .before_vla_type_func = before_print_description_vla,
2493 .after_length_vla_type_func = after_length_print_description_vla,
2494 .after_element_vla_type_func = after_element_print_description_vla,
2495 .before_vla_visitor_type_func = before_print_description_vla_visitor,
2496 .after_length_vla_visitor_type_func = after_length_print_description_vla_visitor,
2497 .after_element_vla_visitor_type_func = after_element_print_description_vla_visitor,
2498
2499 /* Stack-copy enumeration types. */
2500 .before_enum_type_func = before_print_description_enum,
2501 .after_enum_type_func = after_print_description_enum,
2502 .before_enum_bitmap_type_func = before_print_description_enum_bitmap,
2503 .after_enum_bitmap_type_func = after_print_description_enum_bitmap,
2504
2505 /* Gather basic types. */
2506 .gather_bool_type_func = print_description_gather_bool,
2507 .gather_byte_type_func = print_description_gather_byte,
2508 .gather_integer_type_func = print_description_gather_integer,
2509 .gather_pointer_type_func = print_description_gather_pointer,
2510 .gather_float_type_func = print_description_gather_float,
2511 .gather_string_type_func = print_description_gather_string,
2512
2513 /* Gather compound types. */
2514 .before_gather_struct_type_func = before_print_description_gather_struct,
2515 .after_gather_struct_type_func = after_print_description_gather_struct,
2516 .before_gather_array_type_func = before_print_description_gather_array,
2517 .after_gather_array_type_func = after_print_description_gather_array,
2518 .before_gather_vla_type_func = before_print_description_gather_vla,
2519 .after_length_gather_vla_type_func = after_length_print_description_gather_vla,
2520 .after_element_gather_vla_type_func = after_element_print_description_gather_vla,
2521
2522 /* Gather enumeration types. */
2523 .before_gather_enum_type_func = before_print_description_gather_enum,
2524 .after_gather_enum_type_func = after_print_description_gather_enum,
2525
2526 /* Dynamic types. */
2527 .dynamic_type_func = print_description_dynamic,
2528 };
2529
2530 static
2531 void print_event_description(const struct side_event_description *desc)
2532 {
2533 struct print_ctx ctx = {};
2534
2535 description_visitor_event(&description_visitor, desc, &ctx);
2536 }
2537
2538 static
2539 void tracer_event_notification(enum side_tracer_notification notif,
2540 struct side_event_description **events, uint32_t nr_events,
2541 void *priv __attribute__((unused)))
2542 {
2543 uint32_t i;
2544 int ret;
2545
2546 printf("----------------------------------------------------------\n");
2547 printf("Tracer notified of events %s\n",
2548 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
2549 for (i = 0; i < nr_events; i++) {
2550 struct side_event_description *event = events[i];
2551
2552 /* Skip NULL pointers */
2553 if (!event)
2554 continue;
2555 if (event->version != SIDE_EVENT_DESCRIPTION_ABI_VERSION) {
2556 printf("Error: event description ABI version (%u) does not match the version supported by the tracer (%u)\n",
2557 event->version, SIDE_EVENT_DESCRIPTION_ABI_VERSION);
2558 return;
2559 }
2560 printf("provider: %s, event: %s\n",
2561 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
2562 if (event->struct_size != side_offsetofend(struct side_event_description, side_event_description_orig_abi_last)) {
2563 printf("Warning: Event %s.%s description contains fields unknown to the tracer\n",
2564 side_ptr_get(event->provider_name), side_ptr_get(event->event_name));
2565 }
2566 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
2567 if (event->nr_side_type_label > _NR_SIDE_TYPE_LABEL) {
2568 printf("Warning: event %s:%s may contain unknown field types (%u unknown types)\n",
2569 side_ptr_get(event->provider_name), side_ptr_get(event->event_name),
2570 event->nr_side_type_label - _NR_SIDE_TYPE_LABEL);
2571 }
2572 if (event->nr_side_attr_type > _NR_SIDE_ATTR_TYPE) {
2573 printf("Warning: event %s:%s may contain unknown attribute types (%u unknown types)\n",
2574 side_ptr_get(event->provider_name), side_ptr_get(event->event_name),
2575 event->nr_side_attr_type - _NR_SIDE_ATTR_TYPE);
2576 }
2577 print_event_description(event);
2578 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
2579 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL, tracer_key);
2580 if (ret)
2581 abort();
2582 } else {
2583 ret = side_tracer_callback_register(event, tracer_call, NULL, tracer_key);
2584 if (ret)
2585 abort();
2586 }
2587 } else {
2588 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
2589 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL, tracer_key);
2590 if (ret)
2591 abort();
2592 } else {
2593 ret = side_tracer_callback_unregister(event, tracer_call, NULL, tracer_key);
2594 if (ret)
2595 abort();
2596 }
2597 }
2598 }
2599 printf("----------------------------------------------------------\n");
2600 }
2601
2602 static __attribute__((constructor))
2603 void tracer_init(void);
2604 static
2605 void tracer_init(void)
2606 {
2607 if (side_tracer_request_key(&tracer_key))
2608 abort();
2609 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
2610 if (!tracer_handle)
2611 abort();
2612 }
2613
2614 static __attribute__((destructor))
2615 void tracer_exit(void);
2616 static
2617 void tracer_exit(void)
2618 {
2619 side_tracer_event_notification_unregister(tracer_handle);
2620 }
This page took 0.113438 seconds and 5 git commands to generate.