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