Refactor enum bitmap
[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
12 #include <side/trace.h>
13
14 static
15 void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
16 static
17 void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
18 static
19 void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
20 static
21 void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx);
22 static
23 void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
24 static
25 void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
26 static
27 void tracer_print_dynamic(const struct side_arg_dynamic_vec *dynamic_item);
28 static
29 void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item);
30
31 static
32 void tracer_print_attr_type(const struct side_attr *attr)
33 {
34 printf("{ key: \"%s\", value: ", attr->key);
35 switch (attr->value.type) {
36 case SIDE_ATTR_TYPE_BOOL:
37 printf("%s", attr->value.u.side_bool ? "true" : "false");
38 break;
39 case SIDE_ATTR_TYPE_U8:
40 printf("%" PRIu8, attr->value.u.side_u8);
41 break;
42 case SIDE_ATTR_TYPE_U16:
43 printf("%" PRIu16, attr->value.u.side_u16);
44 break;
45 case SIDE_ATTR_TYPE_U32:
46 printf("%" PRIu32, attr->value.u.side_u32);
47 break;
48 case SIDE_ATTR_TYPE_U64:
49 printf("%" PRIu64, attr->value.u.side_u64);
50 break;
51 case SIDE_ATTR_TYPE_S8:
52 printf("%" PRId8, attr->value.u.side_s8);
53 break;
54 case SIDE_ATTR_TYPE_S16:
55 printf("%" PRId16, attr->value.u.side_s16);
56 break;
57 case SIDE_ATTR_TYPE_S32:
58 printf("%" PRId32, attr->value.u.side_s32);
59 break;
60 case SIDE_ATTR_TYPE_S64:
61 printf("%" PRId64, attr->value.u.side_s64);
62 break;
63 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
64 #if __HAVE_FLOAT16
65 printf("%g", (double) attr->value.u.side_float_binary16);
66 break;
67 #else
68 printf("ERROR: Unsupported binary16 float type\n");
69 abort();
70 #endif
71 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
72 #if __HAVE_FLOAT32
73 printf("%g", (double) attr->value.u.side_float_binary32);
74 break;
75 #else
76 printf("ERROR: Unsupported binary32 float type\n");
77 abort();
78 #endif
79 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
80 #if __HAVE_FLOAT64
81 printf("%g", (double) attr->value.u.side_float_binary64);
82 break;
83 #else
84 printf("ERROR: Unsupported binary64 float type\n");
85 abort();
86 #endif
87 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
88 #if __HAVE_FLOAT128
89 printf("%Lg", (long double) attr->value.u.side_float_binary128);
90 break;
91 #else
92 printf("ERROR: Unsupported binary128 float type\n");
93 abort();
94 #endif
95 case SIDE_ATTR_TYPE_STRING:
96 printf("\"%s\"", attr->value.u.string);
97 break;
98 default:
99 printf("<UNKNOWN TYPE>");
100 abort();
101 }
102 printf(" }");
103 }
104
105 static
106 void print_attributes(const char *prefix_str, const struct side_attr *attr, uint32_t nr_attr)
107 {
108 int i;
109
110 if (!nr_attr)
111 return;
112 printf("%s[ ", prefix_str);
113 for (i = 0; i < nr_attr; i++) {
114 printf("%s", i ? ", " : "");
115 tracer_print_attr_type(&attr[i]);
116 }
117 printf(" ]");
118 }
119
120 static
121 void print_enum(const struct side_type_description *type_desc, const struct side_arg_vec *item)
122 {
123 const struct side_enum_mappings *mappings = type_desc->u.side_enum.mappings;
124 int i, print_count = 0;
125 int64_t value;
126
127 if (type_desc->u.side_enum.elem_type->type != item->type) {
128 printf("ERROR: Unexpected enum element type\n");
129 abort();
130 }
131 switch (item->type) {
132 case SIDE_TYPE_U8:
133 value = (int64_t) item->u.side_u8;
134 break;
135 case SIDE_TYPE_U16:
136 value = (int64_t) item->u.side_u16;
137 break;
138 case SIDE_TYPE_U32:
139 value = (int64_t) item->u.side_u32;
140 break;
141 case SIDE_TYPE_U64:
142 value = (int64_t) item->u.side_u64;
143 break;
144 case SIDE_TYPE_S8:
145 value = (int64_t) item->u.side_s8;
146 break;
147 case SIDE_TYPE_S16:
148 value = (int64_t) item->u.side_s16;
149 break;
150 case SIDE_TYPE_S32:
151 value = (int64_t) item->u.side_s32;
152 break;
153 case SIDE_TYPE_S64:
154 value = (int64_t) item->u.side_s64;
155 break;
156 default:
157 printf("ERROR: Unexpected enum element type\n");
158 abort();
159 }
160 print_attributes("attr: ", mappings->attr, mappings->nr_attr);
161 printf("%s", mappings->nr_attr ? ", " : "");
162 tracer_print_type(type_desc->u.side_enum.elem_type, item);
163 printf(", labels: [ ");
164 for (i = 0; i < mappings->nr_mappings; i++) {
165 const struct side_enum_mapping *mapping = &mappings->mappings[i];
166
167 if (mapping->range_end < mapping->range_begin) {
168 printf("ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
169 mapping->range_begin, mapping->range_end);
170 abort();
171 }
172 if (value >= mapping->range_begin && value <= mapping->range_end) {
173 printf("%s", print_count++ ? ", " : "");
174 printf("\"%s\"", mapping->label);
175 }
176 }
177 if (!print_count)
178 printf("<NO LABEL>");
179 printf(" ]");
180 }
181
182 static
183 uint32_t enum_elem_type_to_stride(const struct side_type_description *elem_type)
184 {
185 uint32_t stride_bit;
186
187 switch (elem_type->type) {
188 case SIDE_TYPE_U8:
189 case SIDE_TYPE_S8:
190 stride_bit = 8;
191 break;
192 case SIDE_TYPE_U16:
193 case SIDE_TYPE_S16:
194 stride_bit = 16;
195 break;
196 case SIDE_TYPE_U32:
197 case SIDE_TYPE_S32:
198 stride_bit = 32;
199 break;
200 case SIDE_TYPE_U64:
201 case SIDE_TYPE_S64:
202 stride_bit = 64;
203 break;
204 case SIDE_TYPE_ARRAY:
205 return enum_elem_type_to_stride(elem_type->u.side_array.elem_type);
206 case SIDE_TYPE_VLA:
207 return enum_elem_type_to_stride(elem_type->u.side_vla.elem_type);
208 default:
209 abort();
210 }
211 return stride_bit;
212 }
213
214 static
215 void print_enum_bitmap(const struct side_type_description *type_desc,
216 const struct side_arg_vec *item)
217 {
218 const struct side_type_description *elem_type = type_desc->u.side_enum_bitmap.elem_type;
219 const struct side_enum_bitmap_mappings *side_enum_mappings = type_desc->u.side_enum_bitmap.mappings;
220 int i, print_count = 0;
221 uint32_t stride_bit, nr_items;
222 const struct side_arg_vec *array_item;
223
224 stride_bit = enum_elem_type_to_stride(elem_type);
225
226 switch (elem_type->type) {
227 case SIDE_TYPE_U8: /* Fall-through */
228 case SIDE_TYPE_U16: /* Fall-through */
229 case SIDE_TYPE_U32: /* Fall-through */
230 case SIDE_TYPE_U64: /* Fall-through */
231 case SIDE_TYPE_S8: /* Fall-through */
232 case SIDE_TYPE_S16: /* Fall-through */
233 case SIDE_TYPE_S32: /* Fall-through */
234 case SIDE_TYPE_S64:
235 array_item = item;
236 nr_items = 1;
237 break;
238 case SIDE_TYPE_ARRAY:
239 array_item = item->u.side_array->sav;
240 nr_items = type_desc->u.side_array.length;
241 break;
242 case SIDE_TYPE_VLA:
243 array_item = item->u.side_vla->sav;
244 nr_items = item->u.side_vla->len;
245 break;
246 default:
247 printf("ERROR: Unexpected enum element type\n");
248 abort();
249 }
250
251 print_attributes("attr: ", side_enum_mappings->attr, side_enum_mappings->nr_attr);
252 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
253 printf("labels: [ ");
254 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
255 const struct side_enum_bitmap_mapping *mapping = &side_enum_mappings->mappings[i];
256 bool match = false;
257 int64_t bit;
258
259 if (mapping->range_begin < 0 || mapping->range_end < mapping->range_begin) {
260 printf("ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
261 mapping->range_begin, mapping->range_end);
262 abort();
263 }
264 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
265 if (bit > (nr_items * stride_bit) - 1)
266 break;
267 switch (stride_bit) {
268 case 8:
269 {
270 uint8_t v = array_item[bit / 8].u.side_u8;
271 if (v & (1ULL << (bit % 8))) {
272 match = true;
273 goto match;
274 }
275 break;
276 }
277 case 16:
278 {
279 uint16_t v = array_item[bit / 16].u.side_u16;
280 if (v & (1ULL << (bit % 16))) {
281 match = true;
282 goto match;
283 }
284 break;
285 }
286 case 32:
287 {
288 uint32_t v = array_item[bit / 32].u.side_u32;
289 if (v & (1ULL << (bit % 32))) {
290 match = true;
291 goto match;
292 }
293 break;
294 }
295 case 64:
296 {
297 uint64_t v = array_item[bit / 64].u.side_u64;
298 if (v & (1ULL << (bit % 64))) {
299 match = true;
300 goto match;
301 }
302 break;
303 }
304 default:
305 abort();
306 }
307 }
308 match:
309 if (match) {
310 printf("%s", print_count++ ? ", " : "");
311 printf("\"%s\"", mapping->label);
312 }
313 }
314 if (!print_count)
315 printf("<NO LABEL>");
316 printf(" ]");
317 }
318
319 static
320 void tracer_print_basic_type_header(const struct side_type_description *type_desc)
321 {
322 print_attributes("attr: ", type_desc->u.side_basic.attr, type_desc->u.side_basic.nr_attr);
323 printf("%s", type_desc->u.side_basic.nr_attr ? ", " : "");
324 printf("value: ");
325 }
326
327 static
328 void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item)
329 {
330 enum side_type type;
331
332 switch (item->type) {
333 case SIDE_TYPE_ARRAY_U8:
334 case SIDE_TYPE_ARRAY_U16:
335 case SIDE_TYPE_ARRAY_U32:
336 case SIDE_TYPE_ARRAY_U64:
337 case SIDE_TYPE_ARRAY_S8:
338 case SIDE_TYPE_ARRAY_S16:
339 case SIDE_TYPE_ARRAY_S32:
340 case SIDE_TYPE_ARRAY_S64:
341 case SIDE_TYPE_ARRAY_BLOB:
342 if (type_desc->type != SIDE_TYPE_ARRAY) {
343 printf("ERROR: type mismatch between description and arguments\n");
344 abort();
345 }
346 break;
347 case SIDE_TYPE_VLA_U8:
348 case SIDE_TYPE_VLA_U16:
349 case SIDE_TYPE_VLA_U32:
350 case SIDE_TYPE_VLA_U64:
351 case SIDE_TYPE_VLA_S8:
352 case SIDE_TYPE_VLA_S16:
353 case SIDE_TYPE_VLA_S32:
354 case SIDE_TYPE_VLA_S64:
355 case SIDE_TYPE_VLA_BLOB:
356 if (type_desc->type != SIDE_TYPE_VLA) {
357 printf("ERROR: type mismatch between description and arguments\n");
358 abort();
359 }
360 break;
361
362 case SIDE_TYPE_U8:
363 case SIDE_TYPE_U16:
364 case SIDE_TYPE_U32:
365 case SIDE_TYPE_U64:
366 case SIDE_TYPE_S8:
367 case SIDE_TYPE_S16:
368 case SIDE_TYPE_S32:
369 case SIDE_TYPE_S64:
370 case SIDE_TYPE_ARRAY:
371 case SIDE_TYPE_VLA:
372 switch (type_desc->type) {
373 case SIDE_TYPE_ENUM: /* Fall-through */
374 case SIDE_TYPE_ENUM_BITMAP:
375 break;
376 default:
377 if (type_desc->type != item->type) {
378 printf("ERROR: type mismatch between description and arguments\n");
379 abort();
380 }
381 }
382 break;
383
384 default:
385 if (type_desc->type != item->type) {
386 printf("ERROR: type mismatch between description and arguments\n");
387 abort();
388 }
389 break;
390 }
391
392 if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP)
393 type = type_desc->type;
394 else
395 type = item->type;
396
397 printf("{ ");
398 switch (type) {
399 case SIDE_TYPE_BOOL:
400 tracer_print_basic_type_header(type_desc);
401 printf("%s", item->u.side_bool ? "true" : "false");
402 break;
403 case SIDE_TYPE_U8:
404 tracer_print_basic_type_header(type_desc);
405 printf("%" PRIu8, item->u.side_u8);
406 break;
407 case SIDE_TYPE_U16:
408 tracer_print_basic_type_header(type_desc);
409 printf("%" PRIu16, item->u.side_u16);
410 break;
411 case SIDE_TYPE_U32:
412 tracer_print_basic_type_header(type_desc);
413 printf("%" PRIu32, item->u.side_u32);
414 break;
415 case SIDE_TYPE_U64:
416 tracer_print_basic_type_header(type_desc);
417 printf("%" PRIu64, item->u.side_u64);
418 break;
419 case SIDE_TYPE_S8:
420 tracer_print_basic_type_header(type_desc);
421 printf("%" PRId8, item->u.side_s8);
422 break;
423 case SIDE_TYPE_S16:
424 tracer_print_basic_type_header(type_desc);
425 printf("%" PRId16, item->u.side_s16);
426 break;
427 case SIDE_TYPE_S32:
428 tracer_print_basic_type_header(type_desc);
429 printf("%" PRId32, item->u.side_s32);
430 break;
431 case SIDE_TYPE_S64:
432 tracer_print_basic_type_header(type_desc);
433 printf("%" PRId64, item->u.side_s64);
434 break;
435 case SIDE_TYPE_BLOB:
436 tracer_print_basic_type_header(type_desc);
437 printf("0x%" PRIx8, item->u.side_blob);
438 break;
439
440 case SIDE_TYPE_ENUM:
441 print_enum(type_desc, item);
442 break;
443
444 case SIDE_TYPE_ENUM_BITMAP:
445 print_enum_bitmap(type_desc, item);
446 break;
447
448 case SIDE_TYPE_FLOAT_BINARY16:
449 tracer_print_basic_type_header(type_desc);
450 #if __HAVE_FLOAT16
451 printf("%g", (double) item->u.side_float_binary16);
452 break;
453 #else
454 printf("ERROR: Unsupported binary16 float type\n");
455 abort();
456 #endif
457 case SIDE_TYPE_FLOAT_BINARY32:
458 tracer_print_basic_type_header(type_desc);
459 #if __HAVE_FLOAT32
460 printf("%g", (double) item->u.side_float_binary32);
461 break;
462 #else
463 printf("ERROR: Unsupported binary32 float type\n");
464 abort();
465 #endif
466 case SIDE_TYPE_FLOAT_BINARY64:
467 tracer_print_basic_type_header(type_desc);
468 #if __HAVE_FLOAT64
469 printf("%g", (double) item->u.side_float_binary64);
470 break;
471 #else
472 printf("ERROR: Unsupported binary64 float type\n");
473 abort();
474 #endif
475 case SIDE_TYPE_FLOAT_BINARY128:
476 tracer_print_basic_type_header(type_desc);
477 #if __HAVE_FLOAT128
478 printf("%Lg", (long double) item->u.side_float_binary128);
479 break;
480 #else
481 printf("ERROR: Unsupported binary128 float type\n");
482 abort();
483 #endif
484 case SIDE_TYPE_STRING:
485 tracer_print_basic_type_header(type_desc);
486 printf("\"%s\"", item->u.string);
487 break;
488 case SIDE_TYPE_STRUCT:
489 tracer_print_struct(type_desc, item->u.side_struct);
490 break;
491 case SIDE_TYPE_ARRAY:
492 tracer_print_array(type_desc, item->u.side_array);
493 break;
494 case SIDE_TYPE_VLA:
495 tracer_print_vla(type_desc, item->u.side_vla);
496 break;
497 case SIDE_TYPE_VLA_VISITOR:
498 tracer_print_vla_visitor(type_desc, item->u.side_vla_app_visitor_ctx);
499 break;
500 case SIDE_TYPE_ARRAY_U8:
501 case SIDE_TYPE_ARRAY_U16:
502 case SIDE_TYPE_ARRAY_U32:
503 case SIDE_TYPE_ARRAY_U64:
504 case SIDE_TYPE_ARRAY_S8:
505 case SIDE_TYPE_ARRAY_S16:
506 case SIDE_TYPE_ARRAY_S32:
507 case SIDE_TYPE_ARRAY_S64:
508 case SIDE_TYPE_ARRAY_BLOB:
509 tracer_print_array_fixint(type_desc, item);
510 break;
511 case SIDE_TYPE_VLA_U8:
512 case SIDE_TYPE_VLA_U16:
513 case SIDE_TYPE_VLA_U32:
514 case SIDE_TYPE_VLA_U64:
515 case SIDE_TYPE_VLA_S8:
516 case SIDE_TYPE_VLA_S16:
517 case SIDE_TYPE_VLA_S32:
518 case SIDE_TYPE_VLA_S64:
519 case SIDE_TYPE_VLA_BLOB:
520 tracer_print_vla_fixint(type_desc, item);
521 break;
522 case SIDE_TYPE_DYNAMIC:
523 tracer_print_basic_type_header(type_desc);
524 tracer_print_dynamic(&item->u.dynamic);
525 break;
526 default:
527 printf("<UNKNOWN TYPE>");
528 abort();
529 }
530 printf(" }");
531 }
532
533 static
534 void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg_vec *item)
535 {
536 printf("%s: ", item_desc->field_name);
537 tracer_print_type(&item_desc->side_type, item);
538 }
539
540 static
541 void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
542 {
543 const struct side_arg_vec *sav = sav_desc->sav;
544 uint32_t side_sav_len = sav_desc->len;
545 int i;
546
547 if (type_desc->u.side_struct->nr_fields != side_sav_len) {
548 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
549 abort();
550 }
551 print_attributes("attr: ", type_desc->u.side_struct->attr, type_desc->u.side_struct->nr_attr);
552 printf("%s", type_desc->u.side_struct->nr_attr ? ", " : "");
553 printf("fields: { ");
554 for (i = 0; i < side_sav_len; i++) {
555 printf("%s", i ? ", " : "");
556 tracer_print_field(&type_desc->u.side_struct->fields[i], &sav[i]);
557 }
558 printf(" }");
559 }
560
561 static
562 void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
563 {
564 const struct side_arg_vec *sav = sav_desc->sav;
565 uint32_t side_sav_len = sav_desc->len;
566 int i;
567
568 if (type_desc->u.side_array.length != side_sav_len) {
569 printf("ERROR: length mismatch between description and arguments of array\n");
570 abort();
571 }
572 print_attributes("attr: ", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
573 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
574 printf("elements: ");
575 printf("[ ");
576 for (i = 0; i < side_sav_len; i++) {
577 printf("%s", i ? ", " : "");
578 tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]);
579 }
580 printf(" ]");
581 }
582
583 static
584 void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
585 {
586 const struct side_arg_vec *sav = sav_desc->sav;
587 uint32_t side_sav_len = sav_desc->len;
588 int i;
589
590 print_attributes("attr: ", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
591 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
592 printf("elements: ");
593 printf("[ ");
594 for (i = 0; i < side_sav_len; i++) {
595 printf("%s", i ? ", " : "");
596 tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]);
597 }
598 printf(" ]");
599 }
600
601 struct tracer_visitor_priv {
602 const struct side_type_description *elem_type;
603 int i;
604 };
605
606 static
607 enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
608 const struct side_arg_vec *elem)
609 {
610 struct tracer_visitor_priv *tracer_priv = tracer_ctx->priv;
611
612 printf("%s", tracer_priv->i++ ? ", " : "");
613 tracer_print_type(tracer_priv->elem_type, elem);
614 return SIDE_VISITOR_STATUS_OK;
615 }
616
617 static
618 void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx)
619 {
620 enum side_visitor_status status;
621 struct tracer_visitor_priv tracer_priv = {
622 .elem_type = type_desc->u.side_vla_visitor.elem_type,
623 .i = 0,
624 };
625 const struct side_tracer_visitor_ctx tracer_ctx = {
626 .write_elem = tracer_write_elem_cb,
627 .priv = &tracer_priv,
628 };
629
630 print_attributes("attr: ", type_desc->u.side_vla_visitor.attr, type_desc->u.side_vla_visitor.nr_attr);
631 printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : "");
632 printf("elements: ");
633 printf("[ ");
634 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
635 switch (status) {
636 case SIDE_VISITOR_STATUS_OK:
637 break;
638 case SIDE_VISITOR_STATUS_ERROR:
639 printf("ERROR: Visitor error\n");
640 abort();
641 }
642 printf(" ]");
643 }
644
645 void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
646 {
647 const struct side_type_description *elem_type = type_desc->u.side_array.elem_type;
648 uint32_t side_sav_len = type_desc->u.side_array.length;
649 void *p = item->u.side_array_fixint;
650 enum side_type side_type;
651 int i;
652
653 print_attributes("attr: ", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
654 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
655 printf("elements: ");
656 switch (item->type) {
657 case SIDE_TYPE_ARRAY_U8:
658 if (elem_type->type != SIDE_TYPE_U8)
659 goto type_error;
660 break;
661 case SIDE_TYPE_ARRAY_U16:
662 if (elem_type->type != SIDE_TYPE_U16)
663 goto type_error;
664 break;
665 case SIDE_TYPE_ARRAY_U32:
666 if (elem_type->type != SIDE_TYPE_U32)
667 goto type_error;
668 break;
669 case SIDE_TYPE_ARRAY_U64:
670 if (elem_type->type != SIDE_TYPE_U64)
671 goto type_error;
672 break;
673 case SIDE_TYPE_ARRAY_S8:
674 if (elem_type->type != SIDE_TYPE_S8)
675 goto type_error;
676 break;
677 case SIDE_TYPE_ARRAY_S16:
678 if (elem_type->type != SIDE_TYPE_S16)
679 goto type_error;
680 break;
681 case SIDE_TYPE_ARRAY_S32:
682 if (elem_type->type != SIDE_TYPE_S32)
683 goto type_error;
684 break;
685 case SIDE_TYPE_ARRAY_S64:
686 if (elem_type->type != SIDE_TYPE_S64)
687 goto type_error;
688 break;
689 case SIDE_TYPE_ARRAY_BLOB:
690 if (elem_type->type != SIDE_TYPE_BLOB)
691 goto type_error;
692 break;
693 default:
694 goto type_error;
695 }
696 side_type = elem_type->type;
697
698 printf("[ ");
699 for (i = 0; i < side_sav_len; i++) {
700 struct side_arg_vec sav_elem = {
701 .type = side_type,
702 };
703
704 switch (side_type) {
705 case SIDE_TYPE_U8:
706 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
707 break;
708 case SIDE_TYPE_S8:
709 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
710 break;
711 case SIDE_TYPE_U16:
712 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
713 break;
714 case SIDE_TYPE_S16:
715 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
716 break;
717 case SIDE_TYPE_U32:
718 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
719 break;
720 case SIDE_TYPE_S32:
721 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
722 break;
723 case SIDE_TYPE_U64:
724 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
725 break;
726 case SIDE_TYPE_S64:
727 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
728 break;
729 case SIDE_TYPE_BLOB:
730 sav_elem.u.side_blob = ((const uint8_t *) p)[i];
731 break;
732
733 default:
734 printf("ERROR: Unexpected type\n");
735 abort();
736 }
737
738 printf("%s", i ? ", " : "");
739 tracer_print_type(elem_type, &sav_elem);
740 }
741 printf(" ]");
742 return;
743
744 type_error:
745 printf("ERROR: type mismatch\n");
746 abort();
747 }
748
749 void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
750 {
751 const struct side_type_description *elem_type = type_desc->u.side_vla.elem_type;
752 uint32_t side_sav_len = item->u.side_vla_fixint.length;
753 void *p = item->u.side_vla_fixint.p;
754 enum side_type side_type;
755 int i;
756
757 print_attributes("attr: ", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
758 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
759 printf("elements: ");
760 switch (item->type) {
761 case SIDE_TYPE_VLA_U8:
762 if (elem_type->type != SIDE_TYPE_U8)
763 goto type_error;
764 break;
765 case SIDE_TYPE_VLA_U16:
766 if (elem_type->type != SIDE_TYPE_U16)
767 goto type_error;
768 break;
769 case SIDE_TYPE_VLA_U32:
770 if (elem_type->type != SIDE_TYPE_U32)
771 goto type_error;
772 break;
773 case SIDE_TYPE_VLA_U64:
774 if (elem_type->type != SIDE_TYPE_U64)
775 goto type_error;
776 break;
777 case SIDE_TYPE_VLA_S8:
778 if (elem_type->type != SIDE_TYPE_S8)
779 goto type_error;
780 break;
781 case SIDE_TYPE_VLA_S16:
782 if (elem_type->type != SIDE_TYPE_S16)
783 goto type_error;
784 break;
785 case SIDE_TYPE_VLA_S32:
786 if (elem_type->type != SIDE_TYPE_S32)
787 goto type_error;
788 break;
789 case SIDE_TYPE_VLA_S64:
790 if (elem_type->type != SIDE_TYPE_S64)
791 goto type_error;
792 break;
793 case SIDE_TYPE_VLA_BLOB:
794 if (elem_type->type != SIDE_TYPE_BLOB)
795 goto type_error;
796 break;
797 default:
798 goto type_error;
799 }
800 side_type = elem_type->type;
801
802 printf("[ ");
803 for (i = 0; i < side_sav_len; i++) {
804 struct side_arg_vec sav_elem = {
805 .type = side_type,
806 };
807
808 switch (side_type) {
809 case SIDE_TYPE_U8:
810 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
811 break;
812 case SIDE_TYPE_S8:
813 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
814 break;
815 case SIDE_TYPE_U16:
816 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
817 break;
818 case SIDE_TYPE_S16:
819 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
820 break;
821 case SIDE_TYPE_U32:
822 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
823 break;
824 case SIDE_TYPE_S32:
825 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
826 break;
827 case SIDE_TYPE_U64:
828 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
829 break;
830 case SIDE_TYPE_S64:
831 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
832 break;
833 case SIDE_TYPE_BLOB:
834 sav_elem.u.side_blob = ((const uint8_t *) p)[i];
835 break;
836
837 default:
838 printf("ERROR: Unexpected type\n");
839 abort();
840 }
841
842 printf("%s", i ? ", " : "");
843 tracer_print_type(elem_type, &sav_elem);
844 }
845 printf(" ]");
846 return;
847
848 type_error:
849 printf("ERROR: type mismatch\n");
850 abort();
851 }
852
853 static
854 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct)
855 {
856 const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields;
857 uint32_t len = dynamic_struct->len;
858 int i;
859
860 print_attributes("attr:: ", dynamic_struct->attr, dynamic_struct->nr_attr);
861 printf("%s", dynamic_struct->nr_attr ? ", " : "");
862 printf("fields:: ");
863 printf("[ ");
864 for (i = 0; i < len; i++) {
865 printf("%s", i ? ", " : "");
866 printf("%s:: ", fields[i].field_name);
867 tracer_print_dynamic(&fields[i].elem);
868 }
869 printf(" ]");
870 }
871
872 struct tracer_dynamic_struct_visitor_priv {
873 int i;
874 };
875
876 static
877 enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
878 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
879 const struct side_arg_dynamic_event_field *dynamic_field)
880 {
881 struct tracer_dynamic_struct_visitor_priv *tracer_priv = tracer_ctx->priv;
882
883 printf("%s", tracer_priv->i++ ? ", " : "");
884 printf("%s:: ", dynamic_field->field_name);
885 tracer_print_dynamic(&dynamic_field->elem);
886 return SIDE_VISITOR_STATUS_OK;
887 }
888
889 static
890 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item)
891 {
892 enum side_visitor_status status;
893 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
894 .i = 0,
895 };
896 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
897 .write_field = tracer_dynamic_struct_write_elem_cb,
898 .priv = &tracer_priv,
899 };
900 void *app_ctx = item->u.side_dynamic_struct_visitor.app_ctx;
901
902 print_attributes("attr:: ", item->u.side_dynamic_struct_visitor.attr, item->u.side_dynamic_struct_visitor.nr_attr);
903 printf("%s", item->u.side_dynamic_struct_visitor.nr_attr ? ", " : "");
904 printf("fields:: ");
905 printf("[ ");
906 status = item->u.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
907 switch (status) {
908 case SIDE_VISITOR_STATUS_OK:
909 break;
910 case SIDE_VISITOR_STATUS_ERROR:
911 printf("ERROR: Visitor error\n");
912 abort();
913 }
914 printf(" ]");
915 }
916
917 static
918 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla)
919 {
920 const struct side_arg_dynamic_vec *sav = vla->sav;
921 uint32_t side_sav_len = vla->len;
922 int i;
923
924 print_attributes("attr:: ", vla->attr, vla->nr_attr);
925 printf("%s", vla->nr_attr ? ", " : "");
926 printf("elements:: ");
927 printf("[ ");
928 for (i = 0; i < side_sav_len; i++) {
929 printf("%s", i ? ", " : "");
930 tracer_print_dynamic(&sav[i]);
931 }
932 printf(" ]");
933 }
934
935 struct tracer_dynamic_vla_visitor_priv {
936 int i;
937 };
938
939 static
940 enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
941 const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
942 const struct side_arg_dynamic_vec *elem)
943 {
944 struct tracer_dynamic_vla_visitor_priv *tracer_priv = tracer_ctx->priv;
945
946 printf("%s", tracer_priv->i++ ? ", " : "");
947 tracer_print_dynamic(elem);
948 return SIDE_VISITOR_STATUS_OK;
949 }
950
951 static
952 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item)
953 {
954 enum side_visitor_status status;
955 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
956 .i = 0,
957 };
958 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx = {
959 .write_elem = tracer_dynamic_vla_write_elem_cb,
960 .priv = &tracer_priv,
961 };
962 void *app_ctx = item->u.side_dynamic_vla_visitor.app_ctx;
963
964 print_attributes("attr:: ", item->u.side_dynamic_vla_visitor.attr, item->u.side_dynamic_vla_visitor.nr_attr);
965 printf("%s", item->u.side_dynamic_vla_visitor.nr_attr ? ", " : "");
966 printf("elements:: ");
967 printf("[ ");
968 status = item->u.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
969 switch (status) {
970 case SIDE_VISITOR_STATUS_OK:
971 break;
972 case SIDE_VISITOR_STATUS_ERROR:
973 printf("ERROR: Visitor error\n");
974 abort();
975 }
976 printf(" ]");
977 }
978
979 static
980 void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec *item)
981 {
982 print_attributes("attr:: ", item->u.side_basic.attr, item->u.side_basic.nr_attr);
983 printf("%s", item->u.side_basic.nr_attr ? ", " : "");
984 printf("value:: ");
985 }
986
987 static
988 void tracer_print_dynamic(const struct side_arg_dynamic_vec *item)
989 {
990 printf("{ ");
991 switch (item->dynamic_type) {
992 case SIDE_DYNAMIC_TYPE_NULL:
993 tracer_print_dynamic_basic_type_header(item);
994 printf("<NULL TYPE>");
995 break;
996 case SIDE_DYNAMIC_TYPE_BOOL:
997 tracer_print_dynamic_basic_type_header(item);
998 printf("%s", item->u.side_basic.u.side_bool ? "true" : "false");
999 break;
1000 case SIDE_DYNAMIC_TYPE_U8:
1001 tracer_print_dynamic_basic_type_header(item);
1002 printf("%" PRIu8, item->u.side_basic.u.side_u8);
1003 break;
1004 case SIDE_DYNAMIC_TYPE_U16:
1005 tracer_print_dynamic_basic_type_header(item);
1006 printf("%" PRIu16, item->u.side_basic.u.side_u16);
1007 break;
1008 case SIDE_DYNAMIC_TYPE_U32:
1009 tracer_print_dynamic_basic_type_header(item);
1010 printf("%" PRIu32, item->u.side_basic.u.side_u32);
1011 break;
1012 case SIDE_DYNAMIC_TYPE_U64:
1013 tracer_print_dynamic_basic_type_header(item);
1014 printf("%" PRIu64, item->u.side_basic.u.side_u64);
1015 break;
1016 case SIDE_DYNAMIC_TYPE_S8:
1017 tracer_print_dynamic_basic_type_header(item);
1018 printf("%" PRId8, item->u.side_basic.u.side_s8);
1019 break;
1020 case SIDE_DYNAMIC_TYPE_S16:
1021 tracer_print_dynamic_basic_type_header(item);
1022 printf("%" PRId16, item->u.side_basic.u.side_s16);
1023 break;
1024 case SIDE_DYNAMIC_TYPE_S32:
1025 tracer_print_dynamic_basic_type_header(item);
1026 printf("%" PRId32, item->u.side_basic.u.side_s32);
1027 break;
1028 case SIDE_DYNAMIC_TYPE_S64:
1029 tracer_print_dynamic_basic_type_header(item);
1030 printf("%" PRId64, item->u.side_basic.u.side_s64);
1031 break;
1032 case SIDE_DYNAMIC_TYPE_BLOB:
1033 tracer_print_dynamic_basic_type_header(item);
1034 printf("0x%" PRIx8, item->u.side_basic.u.side_blob);
1035 break;
1036
1037 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
1038 tracer_print_dynamic_basic_type_header(item);
1039 #if __HAVE_FLOAT16
1040 printf("%g", (double) item->u.side_basic.u.side_float_binary16);
1041 break;
1042 #else
1043 printf("ERROR: Unsupported binary16 float type\n");
1044 abort();
1045 #endif
1046 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
1047 tracer_print_dynamic_basic_type_header(item);
1048 #if __HAVE_FLOAT32
1049 printf("%g", (double) item->u.side_basic.u.side_float_binary32);
1050 break;
1051 #else
1052 printf("ERROR: Unsupported binary32 float type\n");
1053 abort();
1054 #endif
1055 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
1056 tracer_print_dynamic_basic_type_header(item);
1057 #if __HAVE_FLOAT64
1058 printf("%g", (double) item->u.side_basic.u.side_float_binary64);
1059 break;
1060 #else
1061 printf("ERROR: Unsupported binary64 float type\n");
1062 abort();
1063 #endif
1064 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
1065 tracer_print_dynamic_basic_type_header(item);
1066 #if __HAVE_FLOAT128
1067 printf("%Lg", (long double) item->u.side_basic.u.side_float_binary128);
1068 break;
1069 #else
1070 printf("ERROR: Unsupported binary128 float type\n");
1071 abort();
1072 #endif
1073 case SIDE_DYNAMIC_TYPE_STRING:
1074 tracer_print_dynamic_basic_type_header(item);
1075 printf("\"%s\"", item->u.side_basic.u.string);
1076 break;
1077 case SIDE_DYNAMIC_TYPE_STRUCT:
1078 tracer_print_dynamic_struct(item->u.side_dynamic_struct);
1079 break;
1080 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR:
1081 tracer_print_dynamic_struct_visitor(item);
1082 break;
1083 case SIDE_DYNAMIC_TYPE_VLA:
1084 tracer_print_dynamic_vla(item->u.side_dynamic_vla);
1085 break;
1086 case SIDE_DYNAMIC_TYPE_VLA_VISITOR:
1087 tracer_print_dynamic_vla_visitor(item);
1088 break;
1089 default:
1090 printf("<UNKNOWN TYPE>");
1091 abort();
1092 }
1093 printf(" }");
1094 }
1095
1096 static
1097 void tracer_print_static_fields(const struct side_event_description *desc,
1098 const struct side_arg_vec_description *sav_desc,
1099 int *nr_items)
1100 {
1101 const struct side_arg_vec *sav = sav_desc->sav;
1102 uint32_t side_sav_len = sav_desc->len;
1103 int i;
1104
1105 printf("provider: %s, event: %s", desc->provider_name, desc->event_name);
1106 if (desc->nr_fields != side_sav_len) {
1107 printf("ERROR: number of fields mismatch between description and arguments\n");
1108 abort();
1109 }
1110 print_attributes(", attributes: ", desc->attr, desc->nr_attr);
1111 printf("%s", side_sav_len ? ", fields: [ " : "");
1112 for (i = 0; i < side_sav_len; i++) {
1113 printf("%s", i ? ", " : "");
1114 tracer_print_field(&desc->fields[i], &sav[i]);
1115 }
1116 if (nr_items)
1117 *nr_items = i;
1118 if (side_sav_len)
1119 printf(" ]");
1120 }
1121
1122 void tracer_call(const struct side_event_description *desc,
1123 const struct side_arg_vec_description *sav_desc,
1124 void *priv __attribute__((unused)))
1125 {
1126 int nr_fields = 0;
1127
1128 tracer_print_static_fields(desc, sav_desc, &nr_fields);
1129 printf("\n");
1130 }
1131
1132 void tracer_call_variadic(const struct side_event_description *desc,
1133 const struct side_arg_vec_description *sav_desc,
1134 const struct side_arg_dynamic_event_struct *var_struct,
1135 void *priv __attribute__((unused)))
1136 {
1137 uint32_t var_struct_len = var_struct->len;
1138 int nr_fields = 0, i;
1139
1140 tracer_print_static_fields(desc, sav_desc, &nr_fields);
1141
1142 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
1143 printf("ERROR: unexpected non-variadic event description\n");
1144 abort();
1145 }
1146 printf("%s", var_struct->nr_attr && nr_fields ? ", " : "");
1147 print_attributes("attributes:: ", var_struct->attr, var_struct->nr_attr);
1148 printf("%s", var_struct_len && (nr_fields || var_struct->nr_attr) ? ", fields:: [ " : "");
1149 for (i = 0; i < var_struct_len; i++, nr_fields++) {
1150 printf("%s", i ? ", " : "");
1151 printf("%s:: ", var_struct->fields[i].field_name);
1152 tracer_print_dynamic(&var_struct->fields[i].elem);
1153 }
1154 if (i)
1155 printf(" ]");
1156 printf("\n");
1157 }
This page took 0.051801 seconds and 5 git commands to generate.