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