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