237b4ba0c7d47d19405abc256af357780d4b8b9e
[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("elements: ");
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("elements: ");
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("elements: ");
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("elements: ");
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 printf("elements: ");
612 switch (item->type) {
613 case SIDE_TYPE_VLA_U8:
614 if (elem_type->type != SIDE_TYPE_U8)
615 goto type_error;
616 break;
617 case SIDE_TYPE_VLA_U16:
618 if (elem_type->type != SIDE_TYPE_U16)
619 goto type_error;
620 break;
621 case SIDE_TYPE_VLA_U32:
622 if (elem_type->type != SIDE_TYPE_U32)
623 goto type_error;
624 break;
625 case SIDE_TYPE_VLA_U64:
626 if (elem_type->type != SIDE_TYPE_U64)
627 goto type_error;
628 break;
629 case SIDE_TYPE_VLA_S8:
630 if (elem_type->type != SIDE_TYPE_S8)
631 goto type_error;
632 break;
633 case SIDE_TYPE_VLA_S16:
634 if (elem_type->type != SIDE_TYPE_S16)
635 goto type_error;
636 break;
637 case SIDE_TYPE_VLA_S32:
638 if (elem_type->type != SIDE_TYPE_S32)
639 goto type_error;
640 break;
641 case SIDE_TYPE_VLA_S64:
642 if (elem_type->type != SIDE_TYPE_S64)
643 goto type_error;
644 break;
645 case SIDE_TYPE_VLA_BLOB:
646 if (elem_type->type != SIDE_TYPE_BLOB)
647 goto type_error;
648 break;
649 default:
650 goto type_error;
651 }
652 side_type = elem_type->type;
653
654 printf("[ ");
655 for (i = 0; i < side_sav_len; i++) {
656 struct side_arg_vec sav_elem = {
657 .type = side_type,
658 };
659
660 switch (side_type) {
661 case SIDE_TYPE_U8:
662 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
663 break;
664 case SIDE_TYPE_S8:
665 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
666 break;
667 case SIDE_TYPE_U16:
668 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
669 break;
670 case SIDE_TYPE_S16:
671 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
672 break;
673 case SIDE_TYPE_U32:
674 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
675 break;
676 case SIDE_TYPE_S32:
677 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
678 break;
679 case SIDE_TYPE_U64:
680 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
681 break;
682 case SIDE_TYPE_S64:
683 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
684 break;
685 case SIDE_TYPE_BLOB:
686 sav_elem.u.side_blob = ((const uint8_t *) p)[i];
687 break;
688
689 default:
690 printf("ERROR: Unexpected type\n");
691 abort();
692 }
693
694 printf("%s", i ? ", " : "");
695 tracer_print_type(elem_type, &sav_elem);
696 }
697 printf(" ]");
698 return;
699
700 type_error:
701 printf("ERROR: type mismatch\n");
702 abort();
703 }
704
705 static
706 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct)
707 {
708 const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields;
709 uint32_t len = dynamic_struct->len;
710 int i;
711
712 printf("[ ");
713 for (i = 0; i < len; i++) {
714 printf("%s", i ? ", " : "");
715 printf("%s:: ", fields[i].field_name);
716 tracer_print_dynamic(&fields[i].elem);
717 }
718 printf(" ]");
719 }
720
721 struct tracer_dynamic_struct_visitor_priv {
722 int i;
723 };
724
725 static
726 enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
727 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
728 const struct side_arg_dynamic_event_field *dynamic_field)
729 {
730 struct tracer_dynamic_struct_visitor_priv *tracer_priv = tracer_ctx->priv;
731
732 printf("%s", tracer_priv->i++ ? ", " : "");
733 printf("%s:: ", dynamic_field->field_name);
734 tracer_print_dynamic(&dynamic_field->elem);
735 return SIDE_VISITOR_STATUS_OK;
736 }
737
738 static
739 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item)
740 {
741 enum side_visitor_status status;
742 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
743 .i = 0,
744 };
745 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
746 .write_field = tracer_dynamic_struct_write_elem_cb,
747 .priv = &tracer_priv,
748 };
749 void *app_ctx = item->u.side_dynamic_struct_visitor.app_ctx;
750
751 printf("[ ");
752 status = item->u.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
753 switch (status) {
754 case SIDE_VISITOR_STATUS_OK:
755 break;
756 case SIDE_VISITOR_STATUS_ERROR:
757 printf("ERROR: Visitor error\n");
758 abort();
759 }
760 printf(" ]");
761 }
762
763 static
764 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla)
765 {
766 const struct side_arg_dynamic_vec *sav = vla->sav;
767 uint32_t side_sav_len = vla->len;
768 int i;
769
770 printf("[ ");
771 for (i = 0; i < side_sav_len; i++) {
772 printf("%s", i ? ", " : "");
773 tracer_print_dynamic(&sav[i]);
774 }
775 printf(" ]");
776 }
777
778 struct tracer_dynamic_vla_visitor_priv {
779 int i;
780 };
781
782 static
783 enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
784 const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
785 const struct side_arg_dynamic_vec *elem)
786 {
787 struct tracer_dynamic_vla_visitor_priv *tracer_priv = tracer_ctx->priv;
788
789 printf("%s", tracer_priv->i++ ? ", " : "");
790 tracer_print_dynamic(elem);
791 return SIDE_VISITOR_STATUS_OK;
792 }
793
794 static
795 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item)
796 {
797 enum side_visitor_status status;
798 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
799 .i = 0,
800 };
801 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx = {
802 .write_elem = tracer_dynamic_vla_write_elem_cb,
803 .priv = &tracer_priv,
804 };
805 void *app_ctx = item->u.side_dynamic_vla_visitor.app_ctx;
806
807 printf("[ ");
808 status = item->u.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
809 switch (status) {
810 case SIDE_VISITOR_STATUS_OK:
811 break;
812 case SIDE_VISITOR_STATUS_ERROR:
813 printf("ERROR: Visitor error\n");
814 abort();
815 }
816 printf(" ]");
817 }
818
819 static
820 void tracer_print_dynamic(const struct side_arg_dynamic_vec *item)
821 {
822 printf("{ ");
823 print_attributes("attr: ", item->attr, item->nr_attr);
824 printf("%s", item->nr_attr ? ", " : "");
825 printf("value: ");
826 switch (item->dynamic_type) {
827 case SIDE_DYNAMIC_TYPE_NULL:
828 printf("<NULL TYPE>");
829 break;
830 case SIDE_DYNAMIC_TYPE_BOOL:
831 printf("%s", item->u.side_bool ? "true" : "false");
832 break;
833 case SIDE_DYNAMIC_TYPE_U8:
834 printf("%" PRIu8, item->u.side_u8);
835 break;
836 case SIDE_DYNAMIC_TYPE_U16:
837 printf("%" PRIu16, item->u.side_u16);
838 break;
839 case SIDE_DYNAMIC_TYPE_U32:
840 printf("%" PRIu32, item->u.side_u32);
841 break;
842 case SIDE_DYNAMIC_TYPE_U64:
843 printf("%" PRIu64, item->u.side_u64);
844 break;
845 case SIDE_DYNAMIC_TYPE_S8:
846 printf("%" PRId8, item->u.side_s8);
847 break;
848 case SIDE_DYNAMIC_TYPE_S16:
849 printf("%" PRId16, item->u.side_s16);
850 break;
851 case SIDE_DYNAMIC_TYPE_S32:
852 printf("%" PRId32, item->u.side_s32);
853 break;
854 case SIDE_DYNAMIC_TYPE_S64:
855 printf("%" PRId64, item->u.side_s64);
856 break;
857 case SIDE_DYNAMIC_TYPE_BLOB:
858 printf("0x%" PRIx8, item->u.side_blob);
859 break;
860
861 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
862 #if __HAVE_FLOAT16
863 printf("%g", (double) item->u.side_float_binary16);
864 break;
865 #else
866 printf("ERROR: Unsupported binary16 float type\n");
867 abort();
868 #endif
869 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
870 #if __HAVE_FLOAT32
871 printf("%g", (double) item->u.side_float_binary32);
872 break;
873 #else
874 printf("ERROR: Unsupported binary32 float type\n");
875 abort();
876 #endif
877 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
878 #if __HAVE_FLOAT64
879 printf("%g", (double) item->u.side_float_binary64);
880 break;
881 #else
882 printf("ERROR: Unsupported binary64 float type\n");
883 abort();
884 #endif
885 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
886 #if __HAVE_FLOAT128
887 printf("%Lg", (long double) item->u.side_float_binary128);
888 break;
889 #else
890 printf("ERROR: Unsupported binary128 float type\n");
891 abort();
892 #endif
893 case SIDE_DYNAMIC_TYPE_STRING:
894 printf("\"%s\"", item->u.string);
895 break;
896 case SIDE_DYNAMIC_TYPE_STRUCT:
897 tracer_print_dynamic_struct(item->u.side_dynamic_struct);
898 break;
899 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR:
900 tracer_print_dynamic_struct_visitor(item);
901 break;
902 case SIDE_DYNAMIC_TYPE_VLA:
903 tracer_print_dynamic_vla(item->u.side_dynamic_vla);
904 break;
905 case SIDE_DYNAMIC_TYPE_VLA_VISITOR:
906 tracer_print_dynamic_vla_visitor(item);
907 break;
908 default:
909 printf("<UNKNOWN TYPE>");
910 abort();
911 }
912 printf(" }");
913 }
914
915 static
916 void tracer_print_static_fields(const struct side_event_description *desc,
917 const struct side_arg_vec_description *sav_desc,
918 int *nr_items)
919 {
920 const struct side_arg_vec *sav = sav_desc->sav;
921 uint32_t side_sav_len = sav_desc->len;
922 int i;
923
924 printf("provider: %s, event: %s", desc->provider_name, desc->event_name);
925 if (desc->nr_fields != side_sav_len) {
926 printf("ERROR: number of fields mismatch between description and arguments\n");
927 abort();
928 }
929 print_attributes(", attributes: ", desc->attr, desc->nr_attr);
930 printf("%s", side_sav_len ? ", fields: [ " : "");
931 for (i = 0; i < side_sav_len; i++) {
932 printf("%s", i ? ", " : "");
933 tracer_print_field(&desc->fields[i], &sav[i]);
934 }
935 if (nr_items)
936 *nr_items = i;
937 }
938
939 void tracer_call(const struct side_event_description *desc,
940 const struct side_arg_vec_description *sav_desc,
941 void *priv __attribute__((unused)))
942 {
943 int nr_fields = 0;
944
945 tracer_print_static_fields(desc, sav_desc, &nr_fields);
946 if (nr_fields)
947 printf(" ]");
948 printf("\n");
949 }
950
951 void tracer_call_variadic(const struct side_event_description *desc,
952 const struct side_arg_vec_description *sav_desc,
953 const struct side_arg_dynamic_event_struct *var_struct,
954 void *priv __attribute__((unused)))
955 {
956 uint32_t var_struct_len = var_struct->len;
957 int nr_fields = 0, i;
958
959 tracer_print_static_fields(desc, sav_desc, &nr_fields);
960
961 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
962 printf("ERROR: unexpected non-variadic event description\n");
963 abort();
964 }
965 printf("%s", var_struct_len && !nr_fields ? ", fields: [ " : "");
966 for (i = 0; i < var_struct_len; i++, nr_fields++) {
967 printf("%s", nr_fields ? ", " : "");
968 printf("%s:: ", var_struct->fields[i].field_name);
969 tracer_print_dynamic(&var_struct->fields[i].elem);
970 }
971 if (i)
972 printf(" ]");
973 printf("\n");
974 }
This page took 0.048676 seconds and 3 git commands to generate.