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