Commit | Line | Data |
---|---|---|
f611d0c3 MD |
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> | |
ea32e5fc | 10 | #include <stdbool.h> |
f611d0c3 MD |
11 | |
12 | #include <side/trace.h> | |
13 | ||
1e8aec23 MD |
14 | static struct side_tracer_handle *tracer_handle; |
15 | ||
f611d0c3 MD |
16 | static |
17 | void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc); | |
18 | static | |
19 | void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc); | |
20 | static | |
21 | void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc); | |
22 | static | |
352a4b77 | 23 | void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx); |
ba845af5 MD |
24 | static |
25 | void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item); | |
1533629f MD |
26 | static |
27 | void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item); | |
a2e2357e MD |
28 | static |
29 | void tracer_print_dynamic(const struct side_arg_dynamic_vec *dynamic_item); | |
d8be25de MD |
30 | static |
31 | void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item); | |
f611d0c3 | 32 | |
8bdd5c12 MD |
33 | static |
34 | bool type_to_host_reverse_bo(const struct side_type_description *type_desc) | |
35 | { | |
36 | switch (type_desc->type) { | |
37 | case SIDE_TYPE_U8: | |
38 | case SIDE_TYPE_S8: | |
39 | case SIDE_TYPE_BYTE: | |
40 | return false; | |
41 | case SIDE_TYPE_U16: | |
42 | case SIDE_TYPE_U32: | |
43 | case SIDE_TYPE_U64: | |
44 | case SIDE_TYPE_S16: | |
45 | case SIDE_TYPE_S32: | |
46 | case SIDE_TYPE_S64: | |
47 | if (type_desc->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST) | |
48 | return true; | |
49 | else | |
50 | return false; | |
51 | break; | |
52 | case SIDE_TYPE_FLOAT_BINARY16: | |
53 | case SIDE_TYPE_FLOAT_BINARY32: | |
54 | case SIDE_TYPE_FLOAT_BINARY64: | |
55 | case SIDE_TYPE_FLOAT_BINARY128: | |
56 | if (type_desc->u.side_basic.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST) | |
57 | return true; | |
58 | else | |
59 | return false; | |
60 | break; | |
61 | default: | |
62 | fprintf(stderr, "Unexpected type\n"); | |
63 | abort(); | |
64 | } | |
65 | } | |
66 | ||
67 | static | |
68 | bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec *item) | |
69 | { | |
70 | switch (item->dynamic_type) { | |
71 | case SIDE_DYNAMIC_TYPE_U8: | |
72 | case SIDE_DYNAMIC_TYPE_S8: | |
73 | case SIDE_DYNAMIC_TYPE_BYTE: | |
74 | return false; | |
75 | case SIDE_DYNAMIC_TYPE_U16: | |
76 | case SIDE_DYNAMIC_TYPE_U32: | |
77 | case SIDE_DYNAMIC_TYPE_U64: | |
78 | case SIDE_DYNAMIC_TYPE_S16: | |
79 | case SIDE_DYNAMIC_TYPE_S32: | |
80 | case SIDE_DYNAMIC_TYPE_S64: | |
81 | if (item->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST) | |
82 | return true; | |
83 | else | |
84 | return false; | |
85 | break; | |
86 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16: | |
87 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32: | |
88 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64: | |
89 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128: | |
90 | if (item->u.side_basic.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST) | |
91 | return true; | |
92 | else | |
93 | return false; | |
94 | break; | |
95 | default: | |
96 | fprintf(stderr, "Unexpected type\n"); | |
97 | abort(); | |
98 | } | |
99 | } | |
100 | ||
bc3c89b3 | 101 | static |
905c328e | 102 | void tracer_print_attr_type(const char *separator, const struct side_attr *attr) |
bc3c89b3 | 103 | { |
905c328e | 104 | printf("{ key%s \"%s\", value%s ", separator, attr->key, separator); |
bc3c89b3 MD |
105 | switch (attr->value.type) { |
106 | case SIDE_ATTR_TYPE_BOOL: | |
107 | printf("%s", attr->value.u.side_bool ? "true" : "false"); | |
108 | break; | |
109 | case SIDE_ATTR_TYPE_U8: | |
110 | printf("%" PRIu8, attr->value.u.side_u8); | |
111 | break; | |
112 | case SIDE_ATTR_TYPE_U16: | |
113 | printf("%" PRIu16, attr->value.u.side_u16); | |
114 | break; | |
115 | case SIDE_ATTR_TYPE_U32: | |
116 | printf("%" PRIu32, attr->value.u.side_u32); | |
117 | break; | |
118 | case SIDE_ATTR_TYPE_U64: | |
119 | printf("%" PRIu64, attr->value.u.side_u64); | |
120 | break; | |
121 | case SIDE_ATTR_TYPE_S8: | |
122 | printf("%" PRId8, attr->value.u.side_s8); | |
123 | break; | |
124 | case SIDE_ATTR_TYPE_S16: | |
125 | printf("%" PRId16, attr->value.u.side_s16); | |
126 | break; | |
127 | case SIDE_ATTR_TYPE_S32: | |
128 | printf("%" PRId32, attr->value.u.side_s32); | |
129 | break; | |
130 | case SIDE_ATTR_TYPE_S64: | |
131 | printf("%" PRId64, attr->value.u.side_s64); | |
132 | break; | |
133 | case SIDE_ATTR_TYPE_FLOAT_BINARY16: | |
134 | #if __HAVE_FLOAT16 | |
135 | printf("%g", (double) attr->value.u.side_float_binary16); | |
136 | break; | |
137 | #else | |
de1b3cd2 | 138 | fprintf(stderr, "ERROR: Unsupported binary16 float type\n"); |
bc3c89b3 MD |
139 | abort(); |
140 | #endif | |
141 | case SIDE_ATTR_TYPE_FLOAT_BINARY32: | |
142 | #if __HAVE_FLOAT32 | |
143 | printf("%g", (double) attr->value.u.side_float_binary32); | |
144 | break; | |
145 | #else | |
de1b3cd2 | 146 | fprintf(stderr, "ERROR: Unsupported binary32 float type\n"); |
bc3c89b3 MD |
147 | abort(); |
148 | #endif | |
149 | case SIDE_ATTR_TYPE_FLOAT_BINARY64: | |
150 | #if __HAVE_FLOAT64 | |
151 | printf("%g", (double) attr->value.u.side_float_binary64); | |
152 | break; | |
153 | #else | |
de1b3cd2 | 154 | fprintf(stderr, "ERROR: Unsupported binary64 float type\n"); |
bc3c89b3 MD |
155 | abort(); |
156 | #endif | |
157 | case SIDE_ATTR_TYPE_FLOAT_BINARY128: | |
158 | #if __HAVE_FLOAT128 | |
159 | printf("%Lg", (long double) attr->value.u.side_float_binary128); | |
160 | break; | |
161 | #else | |
de1b3cd2 | 162 | fprintf(stderr, "ERROR: Unsupported binary128 float type\n"); |
bc3c89b3 MD |
163 | abort(); |
164 | #endif | |
165 | case SIDE_ATTR_TYPE_STRING: | |
166 | printf("\"%s\"", attr->value.u.string); | |
167 | break; | |
168 | default: | |
de1b3cd2 | 169 | fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>"); |
bc3c89b3 MD |
170 | abort(); |
171 | } | |
172 | printf(" }"); | |
173 | } | |
174 | ||
7d21cf51 | 175 | static |
905c328e MD |
176 | void print_attributes(const char *prefix_str, const char *separator, |
177 | const struct side_attr *attr, uint32_t nr_attr) | |
7d21cf51 MD |
178 | { |
179 | int i; | |
180 | ||
181 | if (!nr_attr) | |
182 | return; | |
905c328e | 183 | printf("%s%s [ ", prefix_str, separator); |
7d21cf51 MD |
184 | for (i = 0; i < nr_attr; i++) { |
185 | printf("%s", i ? ", " : ""); | |
905c328e | 186 | tracer_print_attr_type(separator, &attr[i]); |
7d21cf51 MD |
187 | } |
188 | printf(" ]"); | |
189 | } | |
190 | ||
79f677ba | 191 | static |
d8be25de | 192 | void print_enum(const struct side_type_description *type_desc, const struct side_arg_vec *item) |
79f677ba | 193 | { |
d8be25de | 194 | const struct side_enum_mappings *mappings = type_desc->u.side_enum.mappings; |
8bdd5c12 | 195 | const struct side_type_description *elem_type = type_desc->u.side_enum.elem_type; |
79f677ba | 196 | int i, print_count = 0; |
d8be25de | 197 | int64_t value; |
79f677ba | 198 | |
8bdd5c12 | 199 | if (elem_type->type != item->type) { |
de1b3cd2 | 200 | fprintf(stderr, "ERROR: Unexpected enum element type\n"); |
d8be25de MD |
201 | abort(); |
202 | } | |
203 | switch (item->type) { | |
204 | case SIDE_TYPE_U8: | |
205 | value = (int64_t) item->u.side_u8; | |
206 | break; | |
207 | case SIDE_TYPE_U16: | |
8bdd5c12 MD |
208 | { |
209 | uint16_t v; | |
210 | ||
211 | v = item->u.side_u16; | |
212 | if (type_to_host_reverse_bo(elem_type)) | |
213 | v = side_bswap_16(v); | |
214 | value = (int64_t) v; | |
d8be25de | 215 | break; |
8bdd5c12 | 216 | } |
d8be25de | 217 | case SIDE_TYPE_U32: |
8bdd5c12 MD |
218 | { |
219 | uint32_t v; | |
220 | ||
221 | v = item->u.side_u32; | |
222 | if (type_to_host_reverse_bo(elem_type)) | |
223 | v = side_bswap_32(v); | |
224 | value = (int64_t) v; | |
d8be25de | 225 | break; |
8bdd5c12 | 226 | } |
d8be25de | 227 | case SIDE_TYPE_U64: |
8bdd5c12 MD |
228 | { |
229 | uint64_t v; | |
230 | ||
231 | v = item->u.side_u64; | |
232 | if (type_to_host_reverse_bo(elem_type)) | |
233 | v = side_bswap_64(v); | |
234 | value = (int64_t) v; | |
d8be25de | 235 | break; |
8bdd5c12 | 236 | } |
d8be25de MD |
237 | case SIDE_TYPE_S8: |
238 | value = (int64_t) item->u.side_s8; | |
239 | break; | |
240 | case SIDE_TYPE_S16: | |
8bdd5c12 MD |
241 | { |
242 | int16_t v; | |
243 | ||
244 | v = item->u.side_s16; | |
245 | if (type_to_host_reverse_bo(elem_type)) | |
246 | v = side_bswap_16(v); | |
247 | value = (int64_t) v; | |
d8be25de | 248 | break; |
8bdd5c12 | 249 | } |
d8be25de | 250 | case SIDE_TYPE_S32: |
8bdd5c12 MD |
251 | { |
252 | int32_t v; | |
253 | ||
254 | v = item->u.side_s32; | |
255 | if (type_to_host_reverse_bo(elem_type)) | |
256 | v = side_bswap_32(v); | |
257 | value = (int64_t) v; | |
d8be25de | 258 | break; |
8bdd5c12 | 259 | } |
d8be25de | 260 | case SIDE_TYPE_S64: |
8bdd5c12 MD |
261 | { |
262 | int64_t v; | |
263 | ||
264 | v = item->u.side_s64; | |
265 | if (type_to_host_reverse_bo(elem_type)) | |
266 | v = side_bswap_64(v); | |
267 | value = v; | |
d8be25de | 268 | break; |
8bdd5c12 | 269 | } |
d8be25de | 270 | default: |
de1b3cd2 | 271 | fprintf(stderr, "ERROR: Unexpected enum element type\n"); |
d8be25de MD |
272 | abort(); |
273 | } | |
905c328e | 274 | print_attributes("attr", ":", mappings->attr, mappings->nr_attr); |
d8be25de MD |
275 | printf("%s", mappings->nr_attr ? ", " : ""); |
276 | tracer_print_type(type_desc->u.side_enum.elem_type, item); | |
277 | printf(", labels: [ "); | |
278 | for (i = 0; i < mappings->nr_mappings; i++) { | |
279 | const struct side_enum_mapping *mapping = &mappings->mappings[i]; | |
79f677ba | 280 | |
ea32e5fc | 281 | if (mapping->range_end < mapping->range_begin) { |
de1b3cd2 | 282 | fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n", |
ea32e5fc MD |
283 | mapping->range_begin, mapping->range_end); |
284 | abort(); | |
285 | } | |
79f677ba MD |
286 | if (value >= mapping->range_begin && value <= mapping->range_end) { |
287 | printf("%s", print_count++ ? ", " : ""); | |
288 | printf("\"%s\"", mapping->label); | |
289 | } | |
290 | } | |
291 | if (!print_count) | |
292 | printf("<NO LABEL>"); | |
293 | printf(" ]"); | |
294 | } | |
295 | ||
ea32e5fc | 296 | static |
bab5d6e4 | 297 | uint32_t enum_elem_type_to_stride(const struct side_type_description *elem_type) |
ea32e5fc | 298 | { |
af6aa6e1 MD |
299 | uint32_t stride_bit; |
300 | ||
bab5d6e4 | 301 | switch (elem_type->type) { |
4cc2880b MD |
302 | case SIDE_TYPE_U8: /* Fall-through */ |
303 | case SIDE_TYPE_BYTE: | |
af6aa6e1 MD |
304 | stride_bit = 8; |
305 | break; | |
af6aa6e1 | 306 | case SIDE_TYPE_U16: |
af6aa6e1 MD |
307 | stride_bit = 16; |
308 | break; | |
af6aa6e1 | 309 | case SIDE_TYPE_U32: |
af6aa6e1 MD |
310 | stride_bit = 32; |
311 | break; | |
af6aa6e1 | 312 | case SIDE_TYPE_U64: |
af6aa6e1 MD |
313 | stride_bit = 64; |
314 | break; | |
af6aa6e1 | 315 | default: |
de1b3cd2 | 316 | fprintf(stderr, "ERROR: Unexpected enum element type\n"); |
af6aa6e1 MD |
317 | abort(); |
318 | } | |
319 | return stride_bit; | |
320 | } | |
321 | ||
322 | static | |
323 | void print_enum_bitmap(const struct side_type_description *type_desc, | |
324 | const struct side_arg_vec *item) | |
325 | { | |
bab5d6e4 MD |
326 | const struct side_type_description *elem_type = type_desc->u.side_enum_bitmap.elem_type; |
327 | const struct side_enum_bitmap_mappings *side_enum_mappings = type_desc->u.side_enum_bitmap.mappings; | |
ea32e5fc | 328 | int i, print_count = 0; |
af6aa6e1 | 329 | uint32_t stride_bit, nr_items; |
8bdd5c12 | 330 | bool reverse_byte_order = false; |
af6aa6e1 MD |
331 | const struct side_arg_vec *array_item; |
332 | ||
bab5d6e4 MD |
333 | switch (elem_type->type) { |
334 | case SIDE_TYPE_U8: /* Fall-through */ | |
4cc2880b | 335 | case SIDE_TYPE_BYTE: /* Fall-through */ |
bab5d6e4 MD |
336 | case SIDE_TYPE_U16: /* Fall-through */ |
337 | case SIDE_TYPE_U32: /* Fall-through */ | |
4cc2880b | 338 | case SIDE_TYPE_U64: |
45392033 | 339 | stride_bit = enum_elem_type_to_stride(elem_type); |
8bdd5c12 | 340 | reverse_byte_order = type_to_host_reverse_bo(elem_type); |
af6aa6e1 MD |
341 | array_item = item; |
342 | nr_items = 1; | |
af6aa6e1 | 343 | break; |
bab5d6e4 | 344 | case SIDE_TYPE_ARRAY: |
45392033 | 345 | stride_bit = enum_elem_type_to_stride(elem_type->u.side_array.elem_type); |
8bdd5c12 | 346 | reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_array.elem_type); |
af6aa6e1 | 347 | array_item = item->u.side_array->sav; |
bab5d6e4 | 348 | nr_items = type_desc->u.side_array.length; |
af6aa6e1 | 349 | break; |
bab5d6e4 | 350 | case SIDE_TYPE_VLA: |
45392033 | 351 | stride_bit = enum_elem_type_to_stride(elem_type->u.side_vla.elem_type); |
8bdd5c12 | 352 | reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_vla.elem_type); |
af6aa6e1 | 353 | array_item = item->u.side_vla->sav; |
bab5d6e4 | 354 | nr_items = item->u.side_vla->len; |
af6aa6e1 MD |
355 | break; |
356 | default: | |
de1b3cd2 | 357 | fprintf(stderr, "ERROR: Unexpected enum element type\n"); |
af6aa6e1 MD |
358 | abort(); |
359 | } | |
ea32e5fc | 360 | |
905c328e | 361 | print_attributes("attr", ":", side_enum_mappings->attr, side_enum_mappings->nr_attr); |
d4328528 | 362 | printf("%s", side_enum_mappings->nr_attr ? ", " : ""); |
af6aa6e1 | 363 | printf("labels: [ "); |
ea32e5fc | 364 | for (i = 0; i < side_enum_mappings->nr_mappings; i++) { |
66cff328 | 365 | const struct side_enum_bitmap_mapping *mapping = &side_enum_mappings->mappings[i]; |
ea32e5fc | 366 | bool match = false; |
9ff49ee4 | 367 | uint64_t bit; |
ea32e5fc | 368 | |
9ff49ee4 | 369 | if (mapping->range_end < mapping->range_begin) { |
de1b3cd2 | 370 | fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n", |
ea32e5fc MD |
371 | mapping->range_begin, mapping->range_end); |
372 | abort(); | |
373 | } | |
374 | for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) { | |
af6aa6e1 MD |
375 | if (bit > (nr_items * stride_bit) - 1) |
376 | break; | |
377 | switch (stride_bit) { | |
378 | case 8: | |
379 | { | |
380 | uint8_t v = array_item[bit / 8].u.side_u8; | |
381 | if (v & (1ULL << (bit % 8))) { | |
382 | match = true; | |
383 | goto match; | |
384 | } | |
385 | break; | |
386 | } | |
387 | case 16: | |
388 | { | |
389 | uint16_t v = array_item[bit / 16].u.side_u16; | |
8bdd5c12 MD |
390 | if (reverse_byte_order) |
391 | v = side_bswap_16(v); | |
af6aa6e1 MD |
392 | if (v & (1ULL << (bit % 16))) { |
393 | match = true; | |
394 | goto match; | |
395 | } | |
396 | break; | |
397 | } | |
398 | case 32: | |
399 | { | |
400 | uint32_t v = array_item[bit / 32].u.side_u32; | |
8bdd5c12 MD |
401 | if (reverse_byte_order) |
402 | v = side_bswap_32(v); | |
af6aa6e1 MD |
403 | if (v & (1ULL << (bit % 32))) { |
404 | match = true; | |
405 | goto match; | |
406 | } | |
ea32e5fc MD |
407 | break; |
408 | } | |
af6aa6e1 MD |
409 | case 64: |
410 | { | |
411 | uint64_t v = array_item[bit / 64].u.side_u64; | |
8bdd5c12 MD |
412 | if (reverse_byte_order) |
413 | v = side_bswap_64(v); | |
af6aa6e1 MD |
414 | if (v & (1ULL << (bit % 64))) { |
415 | match = true; | |
416 | goto match; | |
417 | } | |
418 | break; | |
419 | } | |
420 | default: | |
421 | abort(); | |
422 | } | |
ea32e5fc | 423 | } |
af6aa6e1 | 424 | match: |
ea32e5fc MD |
425 | if (match) { |
426 | printf("%s", print_count++ ? ", " : ""); | |
427 | printf("\"%s\"", mapping->label); | |
428 | } | |
429 | } | |
430 | if (!print_count) | |
431 | printf("<NO LABEL>"); | |
432 | printf(" ]"); | |
433 | } | |
434 | ||
0e9be766 MD |
435 | static |
436 | void tracer_print_basic_type_header(const struct side_type_description *type_desc) | |
437 | { | |
905c328e | 438 | print_attributes("attr", ":", type_desc->u.side_basic.attr, type_desc->u.side_basic.nr_attr); |
0e9be766 MD |
439 | printf("%s", type_desc->u.side_basic.nr_attr ? ", " : ""); |
440 | printf("value: "); | |
441 | } | |
442 | ||
f611d0c3 MD |
443 | static |
444 | void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item) | |
445 | { | |
d8be25de MD |
446 | enum side_type type; |
447 | ||
45392033 MD |
448 | switch (type_desc->type) { |
449 | case SIDE_TYPE_ARRAY: | |
450 | switch (item->type) { | |
451 | case SIDE_TYPE_ARRAY_U8: | |
452 | case SIDE_TYPE_ARRAY_U16: | |
453 | case SIDE_TYPE_ARRAY_U32: | |
454 | case SIDE_TYPE_ARRAY_U64: | |
455 | case SIDE_TYPE_ARRAY_S8: | |
456 | case SIDE_TYPE_ARRAY_S16: | |
457 | case SIDE_TYPE_ARRAY_S32: | |
458 | case SIDE_TYPE_ARRAY_S64: | |
f7653b43 | 459 | case SIDE_TYPE_ARRAY_BYTE: |
45392033 MD |
460 | case SIDE_TYPE_ARRAY: |
461 | break; | |
462 | default: | |
de1b3cd2 | 463 | fprintf(stderr, "ERROR: type mismatch between description and arguments\n"); |
ba845af5 | 464 | abort(); |
45392033 | 465 | break; |
ba845af5 MD |
466 | } |
467 | break; | |
45392033 MD |
468 | |
469 | case SIDE_TYPE_VLA: | |
470 | switch (item->type) { | |
471 | case SIDE_TYPE_VLA_U8: | |
472 | case SIDE_TYPE_VLA_U16: | |
473 | case SIDE_TYPE_VLA_U32: | |
474 | case SIDE_TYPE_VLA_U64: | |
475 | case SIDE_TYPE_VLA_S8: | |
476 | case SIDE_TYPE_VLA_S16: | |
477 | case SIDE_TYPE_VLA_S32: | |
478 | case SIDE_TYPE_VLA_S64: | |
f7653b43 | 479 | case SIDE_TYPE_VLA_BYTE: |
45392033 MD |
480 | case SIDE_TYPE_VLA: |
481 | break; | |
482 | default: | |
de1b3cd2 | 483 | fprintf(stderr, "ERROR: type mismatch between description and arguments\n"); |
1533629f | 484 | abort(); |
45392033 | 485 | break; |
1533629f MD |
486 | } |
487 | break; | |
488 | ||
45392033 MD |
489 | case SIDE_TYPE_ENUM: |
490 | switch (item->type) { | |
491 | case SIDE_TYPE_U8: | |
492 | case SIDE_TYPE_U16: | |
493 | case SIDE_TYPE_U32: | |
494 | case SIDE_TYPE_U64: | |
495 | case SIDE_TYPE_S8: | |
496 | case SIDE_TYPE_S16: | |
497 | case SIDE_TYPE_S32: | |
498 | case SIDE_TYPE_S64: | |
bab5d6e4 MD |
499 | break; |
500 | default: | |
de1b3cd2 | 501 | fprintf(stderr, "ERROR: type mismatch between description and arguments\n"); |
45392033 MD |
502 | abort(); |
503 | break; | |
504 | } | |
505 | break; | |
506 | ||
507 | case SIDE_TYPE_ENUM_BITMAP: | |
508 | switch (item->type) { | |
509 | case SIDE_TYPE_U8: | |
4cc2880b | 510 | case SIDE_TYPE_BYTE: |
45392033 MD |
511 | case SIDE_TYPE_U16: |
512 | case SIDE_TYPE_U32: | |
513 | case SIDE_TYPE_U64: | |
514 | case SIDE_TYPE_ARRAY: | |
515 | case SIDE_TYPE_VLA: | |
516 | break; | |
517 | default: | |
de1b3cd2 | 518 | fprintf(stderr, "ERROR: type mismatch between description and arguments\n"); |
45392033 MD |
519 | abort(); |
520 | break; | |
d8be25de MD |
521 | } |
522 | break; | |
523 | ||
ba845af5 | 524 | default: |
a2e2357e | 525 | if (type_desc->type != item->type) { |
de1b3cd2 | 526 | fprintf(stderr, "ERROR: type mismatch between description and arguments\n"); |
ba845af5 MD |
527 | abort(); |
528 | } | |
529 | break; | |
f611d0c3 | 530 | } |
d8be25de | 531 | |
bab5d6e4 MD |
532 | if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP) |
533 | type = type_desc->type; | |
d8be25de MD |
534 | else |
535 | type = item->type; | |
536 | ||
a848763d | 537 | printf("{ "); |
d8be25de | 538 | switch (type) { |
4f40d951 | 539 | case SIDE_TYPE_BOOL: |
0e9be766 | 540 | tracer_print_basic_type_header(type_desc); |
4f40d951 MD |
541 | printf("%s", item->u.side_bool ? "true" : "false"); |
542 | break; | |
f611d0c3 | 543 | case SIDE_TYPE_U8: |
0e9be766 | 544 | tracer_print_basic_type_header(type_desc); |
f611d0c3 MD |
545 | printf("%" PRIu8, item->u.side_u8); |
546 | break; | |
547 | case SIDE_TYPE_U16: | |
8bdd5c12 MD |
548 | { |
549 | uint16_t v; | |
550 | ||
551 | v = item->u.side_u16; | |
552 | if (type_to_host_reverse_bo(type_desc)) | |
553 | v = side_bswap_16(v); | |
0e9be766 | 554 | tracer_print_basic_type_header(type_desc); |
8bdd5c12 | 555 | printf("%" PRIu16, v); |
f611d0c3 | 556 | break; |
8bdd5c12 | 557 | } |
f611d0c3 | 558 | case SIDE_TYPE_U32: |
8bdd5c12 MD |
559 | { |
560 | uint32_t v; | |
561 | ||
562 | v = item->u.side_u32; | |
563 | if (type_to_host_reverse_bo(type_desc)) | |
564 | v = side_bswap_32(v); | |
0e9be766 | 565 | tracer_print_basic_type_header(type_desc); |
8bdd5c12 | 566 | printf("%" PRIu32, v); |
f611d0c3 | 567 | break; |
8bdd5c12 | 568 | } |
f611d0c3 | 569 | case SIDE_TYPE_U64: |
8bdd5c12 MD |
570 | { |
571 | uint64_t v; | |
572 | ||
573 | v = item->u.side_u64; | |
574 | if (type_to_host_reverse_bo(type_desc)) | |
575 | v = side_bswap_64(v); | |
0e9be766 | 576 | tracer_print_basic_type_header(type_desc); |
8bdd5c12 | 577 | printf("%" PRIu64, v); |
f611d0c3 | 578 | break; |
8bdd5c12 | 579 | } |
f611d0c3 | 580 | case SIDE_TYPE_S8: |
0e9be766 | 581 | tracer_print_basic_type_header(type_desc); |
f611d0c3 MD |
582 | printf("%" PRId8, item->u.side_s8); |
583 | break; | |
584 | case SIDE_TYPE_S16: | |
8bdd5c12 MD |
585 | { |
586 | int16_t v; | |
587 | ||
588 | v = item->u.side_s16; | |
589 | if (type_to_host_reverse_bo(type_desc)) | |
590 | v = side_bswap_16(v); | |
0e9be766 | 591 | tracer_print_basic_type_header(type_desc); |
8bdd5c12 | 592 | printf("%" PRId16, v); |
f611d0c3 | 593 | break; |
8bdd5c12 | 594 | } |
f611d0c3 | 595 | case SIDE_TYPE_S32: |
8bdd5c12 MD |
596 | { |
597 | int32_t v; | |
598 | ||
599 | v = item->u.side_s32; | |
600 | if (type_to_host_reverse_bo(type_desc)) | |
601 | v = side_bswap_32(v); | |
0e9be766 | 602 | tracer_print_basic_type_header(type_desc); |
8bdd5c12 | 603 | printf("%" PRId32, v); |
f611d0c3 | 604 | break; |
8bdd5c12 | 605 | } |
f611d0c3 | 606 | case SIDE_TYPE_S64: |
8bdd5c12 MD |
607 | { |
608 | int64_t v; | |
609 | ||
610 | v = item->u.side_s64; | |
611 | if (type_to_host_reverse_bo(type_desc)) | |
612 | v = side_bswap_64(v); | |
0e9be766 | 613 | tracer_print_basic_type_header(type_desc); |
8bdd5c12 | 614 | printf("%" PRId64, v); |
f611d0c3 | 615 | break; |
8bdd5c12 | 616 | } |
f7653b43 | 617 | case SIDE_TYPE_BYTE: |
0e9be766 | 618 | tracer_print_basic_type_header(type_desc); |
f7653b43 | 619 | printf("0x%" PRIx8, item->u.side_byte); |
7aec0d09 | 620 | break; |
79f677ba | 621 | |
d8be25de MD |
622 | case SIDE_TYPE_ENUM: |
623 | print_enum(type_desc, item); | |
79f677ba MD |
624 | break; |
625 | ||
bab5d6e4 | 626 | case SIDE_TYPE_ENUM_BITMAP: |
af6aa6e1 | 627 | print_enum_bitmap(type_desc, item); |
ea32e5fc MD |
628 | break; |
629 | ||
fb25b355 | 630 | case SIDE_TYPE_FLOAT_BINARY16: |
8bdd5c12 | 631 | { |
fb25b355 | 632 | #if __HAVE_FLOAT16 |
8bdd5c12 MD |
633 | union { |
634 | _Float16 f; | |
635 | uint16_t u; | |
636 | } float16 = { | |
637 | .f = item->u.side_float_binary16, | |
638 | }; | |
639 | ||
640 | if (type_to_host_reverse_bo(type_desc)) | |
641 | float16.u = side_bswap_16(float16.u); | |
642 | tracer_print_basic_type_header(type_desc); | |
643 | printf("%g", (double) float16.f); | |
fb25b355 MD |
644 | break; |
645 | #else | |
de1b3cd2 | 646 | fprintf(stderr, "ERROR: Unsupported binary16 float type\n"); |
fb25b355 MD |
647 | abort(); |
648 | #endif | |
8bdd5c12 | 649 | } |
fb25b355 | 650 | case SIDE_TYPE_FLOAT_BINARY32: |
8bdd5c12 | 651 | { |
fb25b355 | 652 | #if __HAVE_FLOAT32 |
8bdd5c12 MD |
653 | union { |
654 | _Float32 f; | |
655 | uint32_t u; | |
656 | } float32 = { | |
657 | .f = item->u.side_float_binary32, | |
658 | }; | |
659 | ||
660 | if (type_to_host_reverse_bo(type_desc)) | |
661 | float32.u = side_bswap_32(float32.u); | |
662 | tracer_print_basic_type_header(type_desc); | |
663 | printf("%g", (double) float32.f); | |
fb25b355 MD |
664 | break; |
665 | #else | |
de1b3cd2 | 666 | fprintf(stderr, "ERROR: Unsupported binary32 float type\n"); |
fb25b355 MD |
667 | abort(); |
668 | #endif | |
8bdd5c12 | 669 | } |
fb25b355 | 670 | case SIDE_TYPE_FLOAT_BINARY64: |
8bdd5c12 | 671 | { |
fb25b355 | 672 | #if __HAVE_FLOAT64 |
8bdd5c12 MD |
673 | union { |
674 | _Float64 f; | |
675 | uint64_t u; | |
676 | } float64 = { | |
677 | .f = item->u.side_float_binary64, | |
678 | }; | |
679 | ||
680 | if (type_to_host_reverse_bo(type_desc)) | |
681 | float64.u = side_bswap_64(float64.u); | |
682 | tracer_print_basic_type_header(type_desc); | |
683 | printf("%g", (double) float64.f); | |
fb25b355 MD |
684 | break; |
685 | #else | |
de1b3cd2 | 686 | fprintf(stderr, "ERROR: Unsupported binary64 float type\n"); |
fb25b355 MD |
687 | abort(); |
688 | #endif | |
8bdd5c12 | 689 | } |
fb25b355 | 690 | case SIDE_TYPE_FLOAT_BINARY128: |
8bdd5c12 | 691 | { |
fb25b355 | 692 | #if __HAVE_FLOAT128 |
8bdd5c12 MD |
693 | union { |
694 | _Float128 f; | |
695 | char arr[16]; | |
696 | } float128 = { | |
697 | .f = item->u.side_float_binary128, | |
698 | }; | |
699 | ||
700 | if (type_to_host_reverse_bo(type_desc)) | |
701 | side_bswap_128p(float128.arr); | |
702 | tracer_print_basic_type_header(type_desc); | |
703 | printf("%Lg", (long double) float128.f); | |
fb25b355 MD |
704 | break; |
705 | #else | |
de1b3cd2 | 706 | fprintf(stderr, "ERROR: Unsupported binary128 float type\n"); |
fb25b355 MD |
707 | abort(); |
708 | #endif | |
8bdd5c12 | 709 | } |
f611d0c3 | 710 | case SIDE_TYPE_STRING: |
0e9be766 | 711 | tracer_print_basic_type_header(type_desc); |
a2e2357e | 712 | printf("\"%s\"", item->u.string); |
f611d0c3 MD |
713 | break; |
714 | case SIDE_TYPE_STRUCT: | |
715 | tracer_print_struct(type_desc, item->u.side_struct); | |
716 | break; | |
717 | case SIDE_TYPE_ARRAY: | |
718 | tracer_print_array(type_desc, item->u.side_array); | |
719 | break; | |
720 | case SIDE_TYPE_VLA: | |
721 | tracer_print_vla(type_desc, item->u.side_vla); | |
722 | break; | |
723 | case SIDE_TYPE_VLA_VISITOR: | |
352a4b77 | 724 | tracer_print_vla_visitor(type_desc, item->u.side_vla_app_visitor_ctx); |
f611d0c3 | 725 | break; |
ba845af5 MD |
726 | case SIDE_TYPE_ARRAY_U8: |
727 | case SIDE_TYPE_ARRAY_U16: | |
728 | case SIDE_TYPE_ARRAY_U32: | |
729 | case SIDE_TYPE_ARRAY_U64: | |
730 | case SIDE_TYPE_ARRAY_S8: | |
731 | case SIDE_TYPE_ARRAY_S16: | |
732 | case SIDE_TYPE_ARRAY_S32: | |
733 | case SIDE_TYPE_ARRAY_S64: | |
f7653b43 | 734 | case SIDE_TYPE_ARRAY_BYTE: |
ba845af5 MD |
735 | tracer_print_array_fixint(type_desc, item); |
736 | break; | |
1533629f MD |
737 | case SIDE_TYPE_VLA_U8: |
738 | case SIDE_TYPE_VLA_U16: | |
739 | case SIDE_TYPE_VLA_U32: | |
740 | case SIDE_TYPE_VLA_U64: | |
741 | case SIDE_TYPE_VLA_S8: | |
742 | case SIDE_TYPE_VLA_S16: | |
743 | case SIDE_TYPE_VLA_S32: | |
744 | case SIDE_TYPE_VLA_S64: | |
f7653b43 | 745 | case SIDE_TYPE_VLA_BYTE: |
1533629f MD |
746 | tracer_print_vla_fixint(type_desc, item); |
747 | break; | |
a2e2357e | 748 | case SIDE_TYPE_DYNAMIC: |
0e9be766 | 749 | tracer_print_basic_type_header(type_desc); |
a2e2357e MD |
750 | tracer_print_dynamic(&item->u.dynamic); |
751 | break; | |
f611d0c3 | 752 | default: |
de1b3cd2 | 753 | fprintf(stderr, "<UNKNOWN TYPE>"); |
f611d0c3 MD |
754 | abort(); |
755 | } | |
a848763d | 756 | printf(" }"); |
f611d0c3 MD |
757 | } |
758 | ||
759 | static | |
760 | void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg_vec *item) | |
761 | { | |
19fa6aa2 | 762 | printf("%s: ", item_desc->field_name); |
f611d0c3 | 763 | tracer_print_type(&item_desc->side_type, item); |
f611d0c3 MD |
764 | } |
765 | ||
766 | static | |
767 | void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc) | |
768 | { | |
769 | const struct side_arg_vec *sav = sav_desc->sav; | |
770 | uint32_t side_sav_len = sav_desc->len; | |
771 | int i; | |
772 | ||
c7a14585 | 773 | if (type_desc->u.side_struct->nr_fields != side_sav_len) { |
de1b3cd2 | 774 | fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n"); |
f611d0c3 MD |
775 | abort(); |
776 | } | |
905c328e | 777 | print_attributes("attr", ":", type_desc->u.side_struct->attr, type_desc->u.side_struct->nr_attr); |
73b2b0c2 MD |
778 | printf("%s", type_desc->u.side_struct->nr_attr ? ", " : ""); |
779 | printf("fields: { "); | |
f611d0c3 MD |
780 | for (i = 0; i < side_sav_len; i++) { |
781 | printf("%s", i ? ", " : ""); | |
c7a14585 | 782 | tracer_print_field(&type_desc->u.side_struct->fields[i], &sav[i]); |
f611d0c3 | 783 | } |
d4328528 | 784 | printf(" }"); |
f611d0c3 MD |
785 | } |
786 | ||
787 | static | |
788 | void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc) | |
789 | { | |
790 | const struct side_arg_vec *sav = sav_desc->sav; | |
791 | uint32_t side_sav_len = sav_desc->len; | |
792 | int i; | |
793 | ||
794 | if (type_desc->u.side_array.length != side_sav_len) { | |
de1b3cd2 | 795 | fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n"); |
f611d0c3 MD |
796 | abort(); |
797 | } | |
905c328e | 798 | print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr); |
d4328528 | 799 | printf("%s", type_desc->u.side_array.nr_attr ? ", " : ""); |
20574104 | 800 | printf("elements: "); |
f611d0c3 MD |
801 | printf("[ "); |
802 | for (i = 0; i < side_sav_len; i++) { | |
803 | printf("%s", i ? ", " : ""); | |
804 | tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]); | |
805 | } | |
806 | printf(" ]"); | |
807 | } | |
808 | ||
809 | static | |
810 | void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc) | |
811 | { | |
812 | const struct side_arg_vec *sav = sav_desc->sav; | |
813 | uint32_t side_sav_len = sav_desc->len; | |
814 | int i; | |
815 | ||
905c328e | 816 | print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr); |
d4328528 | 817 | printf("%s", type_desc->u.side_vla.nr_attr ? ", " : ""); |
20574104 | 818 | printf("elements: "); |
f611d0c3 MD |
819 | printf("[ "); |
820 | for (i = 0; i < side_sav_len; i++) { | |
821 | printf("%s", i ? ", " : ""); | |
822 | tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]); | |
823 | } | |
824 | printf(" ]"); | |
825 | } | |
826 | ||
352a4b77 MD |
827 | struct tracer_visitor_priv { |
828 | const struct side_type_description *elem_type; | |
829 | int i; | |
830 | }; | |
831 | ||
832 | static | |
833 | enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx, | |
834 | const struct side_arg_vec *elem) | |
835 | { | |
836 | struct tracer_visitor_priv *tracer_priv = tracer_ctx->priv; | |
837 | ||
838 | printf("%s", tracer_priv->i++ ? ", " : ""); | |
839 | tracer_print_type(tracer_priv->elem_type, elem); | |
840 | return SIDE_VISITOR_STATUS_OK; | |
841 | } | |
842 | ||
f611d0c3 | 843 | static |
352a4b77 | 844 | void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx) |
f611d0c3 MD |
845 | { |
846 | enum side_visitor_status status; | |
352a4b77 MD |
847 | struct tracer_visitor_priv tracer_priv = { |
848 | .elem_type = type_desc->u.side_vla_visitor.elem_type, | |
849 | .i = 0, | |
850 | }; | |
851 | const struct side_tracer_visitor_ctx tracer_ctx = { | |
852 | .write_elem = tracer_write_elem_cb, | |
853 | .priv = &tracer_priv, | |
854 | }; | |
f611d0c3 | 855 | |
905c328e | 856 | print_attributes("attr", ":", type_desc->u.side_vla_visitor.attr, type_desc->u.side_vla_visitor.nr_attr); |
d4328528 | 857 | printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : ""); |
20574104 | 858 | printf("elements: "); |
352a4b77 MD |
859 | printf("[ "); |
860 | status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx); | |
861 | switch (status) { | |
862 | case SIDE_VISITOR_STATUS_OK: | |
863 | break; | |
864 | case SIDE_VISITOR_STATUS_ERROR: | |
de1b3cd2 | 865 | fprintf(stderr, "ERROR: Visitor error\n"); |
f611d0c3 | 866 | abort(); |
f611d0c3 MD |
867 | } |
868 | printf(" ]"); | |
f611d0c3 MD |
869 | } |
870 | ||
ba845af5 MD |
871 | void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item) |
872 | { | |
873 | const struct side_type_description *elem_type = type_desc->u.side_array.elem_type; | |
874 | uint32_t side_sav_len = type_desc->u.side_array.length; | |
875 | void *p = item->u.side_array_fixint; | |
876 | enum side_type side_type; | |
877 | int i; | |
878 | ||
905c328e | 879 | print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr); |
d4328528 | 880 | printf("%s", type_desc->u.side_array.nr_attr ? ", " : ""); |
20574104 | 881 | printf("elements: "); |
1e8256c9 MD |
882 | switch (item->type) { |
883 | case SIDE_TYPE_ARRAY_U8: | |
884 | if (elem_type->type != SIDE_TYPE_U8) | |
885 | goto type_error; | |
886 | break; | |
887 | case SIDE_TYPE_ARRAY_U16: | |
888 | if (elem_type->type != SIDE_TYPE_U16) | |
889 | goto type_error; | |
890 | break; | |
891 | case SIDE_TYPE_ARRAY_U32: | |
892 | if (elem_type->type != SIDE_TYPE_U32) | |
893 | goto type_error; | |
894 | break; | |
895 | case SIDE_TYPE_ARRAY_U64: | |
896 | if (elem_type->type != SIDE_TYPE_U64) | |
897 | goto type_error; | |
898 | break; | |
899 | case SIDE_TYPE_ARRAY_S8: | |
900 | if (elem_type->type != SIDE_TYPE_S8) | |
901 | goto type_error; | |
902 | break; | |
903 | case SIDE_TYPE_ARRAY_S16: | |
904 | if (elem_type->type != SIDE_TYPE_S16) | |
905 | goto type_error; | |
906 | break; | |
907 | case SIDE_TYPE_ARRAY_S32: | |
908 | if (elem_type->type != SIDE_TYPE_S32) | |
909 | goto type_error; | |
910 | break; | |
911 | case SIDE_TYPE_ARRAY_S64: | |
912 | if (elem_type->type != SIDE_TYPE_S64) | |
913 | goto type_error; | |
914 | break; | |
f7653b43 MD |
915 | case SIDE_TYPE_ARRAY_BYTE: |
916 | if (elem_type->type != SIDE_TYPE_BYTE) | |
7aec0d09 MD |
917 | goto type_error; |
918 | break; | |
1e8256c9 MD |
919 | default: |
920 | goto type_error; | |
ba845af5 | 921 | } |
1e8256c9 | 922 | side_type = elem_type->type; |
ba845af5 | 923 | |
1533629f MD |
924 | printf("[ "); |
925 | for (i = 0; i < side_sav_len; i++) { | |
926 | struct side_arg_vec sav_elem = { | |
927 | .type = side_type, | |
928 | }; | |
929 | ||
930 | switch (side_type) { | |
931 | case SIDE_TYPE_U8: | |
932 | sav_elem.u.side_u8 = ((const uint8_t *) p)[i]; | |
933 | break; | |
934 | case SIDE_TYPE_S8: | |
935 | sav_elem.u.side_s8 = ((const int8_t *) p)[i]; | |
936 | break; | |
937 | case SIDE_TYPE_U16: | |
938 | sav_elem.u.side_u16 = ((const uint16_t *) p)[i]; | |
939 | break; | |
940 | case SIDE_TYPE_S16: | |
941 | sav_elem.u.side_s16 = ((const int16_t *) p)[i]; | |
942 | break; | |
943 | case SIDE_TYPE_U32: | |
944 | sav_elem.u.side_u32 = ((const uint32_t *) p)[i]; | |
945 | break; | |
946 | case SIDE_TYPE_S32: | |
947 | sav_elem.u.side_s32 = ((const int32_t *) p)[i]; | |
948 | break; | |
949 | case SIDE_TYPE_U64: | |
950 | sav_elem.u.side_u64 = ((const uint64_t *) p)[i]; | |
951 | break; | |
952 | case SIDE_TYPE_S64: | |
953 | sav_elem.u.side_s64 = ((const int64_t *) p)[i]; | |
954 | break; | |
f7653b43 MD |
955 | case SIDE_TYPE_BYTE: |
956 | sav_elem.u.side_byte = ((const uint8_t *) p)[i]; | |
7aec0d09 | 957 | break; |
1533629f MD |
958 | |
959 | default: | |
de1b3cd2 | 960 | fprintf(stderr, "ERROR: Unexpected type\n"); |
1533629f MD |
961 | abort(); |
962 | } | |
963 | ||
964 | printf("%s", i ? ", " : ""); | |
965 | tracer_print_type(elem_type, &sav_elem); | |
966 | } | |
967 | printf(" ]"); | |
968 | return; | |
969 | ||
970 | type_error: | |
de1b3cd2 | 971 | fprintf(stderr, "ERROR: type mismatch\n"); |
1533629f MD |
972 | abort(); |
973 | } | |
974 | ||
975 | void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item) | |
976 | { | |
977 | const struct side_type_description *elem_type = type_desc->u.side_vla.elem_type; | |
978 | uint32_t side_sav_len = item->u.side_vla_fixint.length; | |
979 | void *p = item->u.side_vla_fixint.p; | |
980 | enum side_type side_type; | |
981 | int i; | |
982 | ||
905c328e | 983 | print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr); |
d4328528 | 984 | printf("%s", type_desc->u.side_vla.nr_attr ? ", " : ""); |
20574104 | 985 | printf("elements: "); |
a2e2357e MD |
986 | switch (item->type) { |
987 | case SIDE_TYPE_VLA_U8: | |
988 | if (elem_type->type != SIDE_TYPE_U8) | |
1533629f | 989 | goto type_error; |
a2e2357e MD |
990 | break; |
991 | case SIDE_TYPE_VLA_U16: | |
992 | if (elem_type->type != SIDE_TYPE_U16) | |
1533629f | 993 | goto type_error; |
a2e2357e MD |
994 | break; |
995 | case SIDE_TYPE_VLA_U32: | |
996 | if (elem_type->type != SIDE_TYPE_U32) | |
997 | goto type_error; | |
998 | break; | |
999 | case SIDE_TYPE_VLA_U64: | |
1000 | if (elem_type->type != SIDE_TYPE_U64) | |
1001 | goto type_error; | |
1002 | break; | |
1003 | case SIDE_TYPE_VLA_S8: | |
1004 | if (elem_type->type != SIDE_TYPE_S8) | |
1005 | goto type_error; | |
1006 | break; | |
1007 | case SIDE_TYPE_VLA_S16: | |
1008 | if (elem_type->type != SIDE_TYPE_S16) | |
1009 | goto type_error; | |
1010 | break; | |
1011 | case SIDE_TYPE_VLA_S32: | |
1012 | if (elem_type->type != SIDE_TYPE_S32) | |
1013 | goto type_error; | |
1014 | break; | |
1015 | case SIDE_TYPE_VLA_S64: | |
1016 | if (elem_type->type != SIDE_TYPE_S64) | |
1017 | goto type_error; | |
1018 | break; | |
f7653b43 MD |
1019 | case SIDE_TYPE_VLA_BYTE: |
1020 | if (elem_type->type != SIDE_TYPE_BYTE) | |
7aec0d09 MD |
1021 | goto type_error; |
1022 | break; | |
a2e2357e MD |
1023 | default: |
1024 | goto type_error; | |
1533629f | 1025 | } |
a2e2357e | 1026 | side_type = elem_type->type; |
1533629f | 1027 | |
ba845af5 MD |
1028 | printf("[ "); |
1029 | for (i = 0; i < side_sav_len; i++) { | |
1030 | struct side_arg_vec sav_elem = { | |
1031 | .type = side_type, | |
1032 | }; | |
1033 | ||
1034 | switch (side_type) { | |
1035 | case SIDE_TYPE_U8: | |
1036 | sav_elem.u.side_u8 = ((const uint8_t *) p)[i]; | |
1037 | break; | |
1038 | case SIDE_TYPE_S8: | |
1039 | sav_elem.u.side_s8 = ((const int8_t *) p)[i]; | |
1040 | break; | |
1041 | case SIDE_TYPE_U16: | |
1042 | sav_elem.u.side_u16 = ((const uint16_t *) p)[i]; | |
1043 | break; | |
1044 | case SIDE_TYPE_S16: | |
1045 | sav_elem.u.side_s16 = ((const int16_t *) p)[i]; | |
1046 | break; | |
1047 | case SIDE_TYPE_U32: | |
1048 | sav_elem.u.side_u32 = ((const uint32_t *) p)[i]; | |
1049 | break; | |
1050 | case SIDE_TYPE_S32: | |
1051 | sav_elem.u.side_s32 = ((const int32_t *) p)[i]; | |
1052 | break; | |
1053 | case SIDE_TYPE_U64: | |
1054 | sav_elem.u.side_u64 = ((const uint64_t *) p)[i]; | |
1055 | break; | |
1056 | case SIDE_TYPE_S64: | |
1057 | sav_elem.u.side_s64 = ((const int64_t *) p)[i]; | |
1058 | break; | |
f7653b43 MD |
1059 | case SIDE_TYPE_BYTE: |
1060 | sav_elem.u.side_byte = ((const uint8_t *) p)[i]; | |
7aec0d09 | 1061 | break; |
ba845af5 MD |
1062 | |
1063 | default: | |
de1b3cd2 | 1064 | fprintf(stderr, "ERROR: Unexpected type\n"); |
ba845af5 MD |
1065 | abort(); |
1066 | } | |
1067 | ||
1068 | printf("%s", i ? ", " : ""); | |
1069 | tracer_print_type(elem_type, &sav_elem); | |
1070 | } | |
1071 | printf(" ]"); | |
1072 | return; | |
1073 | ||
1074 | type_error: | |
de1b3cd2 | 1075 | fprintf(stderr, "ERROR: type mismatch\n"); |
ba845af5 MD |
1076 | abort(); |
1077 | } | |
1078 | ||
a2e2357e | 1079 | static |
c208889e | 1080 | void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct) |
a2e2357e | 1081 | { |
c208889e MD |
1082 | const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields; |
1083 | uint32_t len = dynamic_struct->len; | |
465e5e7e MD |
1084 | int i; |
1085 | ||
905c328e | 1086 | print_attributes("attr", "::", dynamic_struct->attr, dynamic_struct->nr_attr); |
8d20e708 | 1087 | printf("%s", dynamic_struct->nr_attr ? ", " : ""); |
f0061366 | 1088 | printf("fields:: "); |
465e5e7e MD |
1089 | printf("[ "); |
1090 | for (i = 0; i < len; i++) { | |
1091 | printf("%s", i ? ", " : ""); | |
1092 | printf("%s:: ", fields[i].field_name); | |
1093 | tracer_print_dynamic(&fields[i].elem); | |
1094 | } | |
1095 | printf(" ]"); | |
a2e2357e MD |
1096 | } |
1097 | ||
2b359235 MD |
1098 | struct tracer_dynamic_struct_visitor_priv { |
1099 | int i; | |
1100 | }; | |
1101 | ||
1102 | static | |
1103 | enum side_visitor_status tracer_dynamic_struct_write_elem_cb( | |
1104 | const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx, | |
1105 | const struct side_arg_dynamic_event_field *dynamic_field) | |
1106 | { | |
1107 | struct tracer_dynamic_struct_visitor_priv *tracer_priv = tracer_ctx->priv; | |
1108 | ||
1109 | printf("%s", tracer_priv->i++ ? ", " : ""); | |
1110 | printf("%s:: ", dynamic_field->field_name); | |
1111 | tracer_print_dynamic(&dynamic_field->elem); | |
1112 | return SIDE_VISITOR_STATUS_OK; | |
1113 | } | |
1114 | ||
a2e2357e | 1115 | static |
c208889e | 1116 | void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item) |
a2e2357e | 1117 | { |
2b359235 MD |
1118 | enum side_visitor_status status; |
1119 | struct tracer_dynamic_struct_visitor_priv tracer_priv = { | |
1120 | .i = 0, | |
1121 | }; | |
1122 | const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = { | |
1123 | .write_field = tracer_dynamic_struct_write_elem_cb, | |
1124 | .priv = &tracer_priv, | |
1125 | }; | |
1126 | void *app_ctx = item->u.side_dynamic_struct_visitor.app_ctx; | |
1127 | ||
905c328e | 1128 | print_attributes("attr", "::", item->u.side_dynamic_struct_visitor.attr, item->u.side_dynamic_struct_visitor.nr_attr); |
8d20e708 | 1129 | printf("%s", item->u.side_dynamic_struct_visitor.nr_attr ? ", " : ""); |
f0061366 | 1130 | printf("fields:: "); |
2b359235 MD |
1131 | printf("[ "); |
1132 | status = item->u.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx); | |
1133 | switch (status) { | |
1134 | case SIDE_VISITOR_STATUS_OK: | |
1135 | break; | |
1136 | case SIDE_VISITOR_STATUS_ERROR: | |
de1b3cd2 | 1137 | fprintf(stderr, "ERROR: Visitor error\n"); |
2b359235 MD |
1138 | abort(); |
1139 | } | |
1140 | printf(" ]"); | |
a2e2357e MD |
1141 | } |
1142 | ||
1143 | static | |
1144 | void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla) | |
1145 | { | |
1146 | const struct side_arg_dynamic_vec *sav = vla->sav; | |
1147 | uint32_t side_sav_len = vla->len; | |
1148 | int i; | |
1149 | ||
905c328e | 1150 | print_attributes("attr", "::", vla->attr, vla->nr_attr); |
8d20e708 | 1151 | printf("%s", vla->nr_attr ? ", " : ""); |
f0061366 | 1152 | printf("elements:: "); |
a2e2357e MD |
1153 | printf("[ "); |
1154 | for (i = 0; i < side_sav_len; i++) { | |
1155 | printf("%s", i ? ", " : ""); | |
1156 | tracer_print_dynamic(&sav[i]); | |
1157 | } | |
1158 | printf(" ]"); | |
1159 | } | |
1160 | ||
8ceca0cd MD |
1161 | struct tracer_dynamic_vla_visitor_priv { |
1162 | int i; | |
1163 | }; | |
1164 | ||
1165 | static | |
1166 | enum side_visitor_status tracer_dynamic_vla_write_elem_cb( | |
1167 | const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx, | |
1168 | const struct side_arg_dynamic_vec *elem) | |
1169 | { | |
1170 | struct tracer_dynamic_vla_visitor_priv *tracer_priv = tracer_ctx->priv; | |
1171 | ||
1172 | printf("%s", tracer_priv->i++ ? ", " : ""); | |
1173 | tracer_print_dynamic(elem); | |
1174 | return SIDE_VISITOR_STATUS_OK; | |
1175 | } | |
1176 | ||
a2e2357e MD |
1177 | static |
1178 | void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item) | |
1179 | { | |
8ceca0cd MD |
1180 | enum side_visitor_status status; |
1181 | struct tracer_dynamic_vla_visitor_priv tracer_priv = { | |
1182 | .i = 0, | |
1183 | }; | |
1184 | const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx = { | |
1185 | .write_elem = tracer_dynamic_vla_write_elem_cb, | |
1186 | .priv = &tracer_priv, | |
1187 | }; | |
1188 | void *app_ctx = item->u.side_dynamic_vla_visitor.app_ctx; | |
1189 | ||
905c328e | 1190 | print_attributes("attr", "::", item->u.side_dynamic_vla_visitor.attr, item->u.side_dynamic_vla_visitor.nr_attr); |
8d20e708 | 1191 | printf("%s", item->u.side_dynamic_vla_visitor.nr_attr ? ", " : ""); |
f0061366 | 1192 | printf("elements:: "); |
8ceca0cd MD |
1193 | printf("[ "); |
1194 | status = item->u.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx); | |
1195 | switch (status) { | |
1196 | case SIDE_VISITOR_STATUS_OK: | |
1197 | break; | |
1198 | case SIDE_VISITOR_STATUS_ERROR: | |
de1b3cd2 | 1199 | fprintf(stderr, "ERROR: Visitor error\n"); |
8ceca0cd MD |
1200 | abort(); |
1201 | } | |
1202 | printf(" ]"); | |
a2e2357e MD |
1203 | } |
1204 | ||
0e9be766 MD |
1205 | static |
1206 | void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec *item) | |
1207 | { | |
905c328e | 1208 | print_attributes("attr", "::", item->u.side_basic.attr, item->u.side_basic.nr_attr); |
0e9be766 MD |
1209 | printf("%s", item->u.side_basic.nr_attr ? ", " : ""); |
1210 | printf("value:: "); | |
1211 | } | |
1212 | ||
a2e2357e MD |
1213 | static |
1214 | void tracer_print_dynamic(const struct side_arg_dynamic_vec *item) | |
1215 | { | |
808bd9bf | 1216 | printf("{ "); |
1e8256c9 | 1217 | switch (item->dynamic_type) { |
a2e2357e | 1218 | case SIDE_DYNAMIC_TYPE_NULL: |
0e9be766 | 1219 | tracer_print_dynamic_basic_type_header(item); |
a2e2357e MD |
1220 | printf("<NULL TYPE>"); |
1221 | break; | |
4f40d951 | 1222 | case SIDE_DYNAMIC_TYPE_BOOL: |
0e9be766 | 1223 | tracer_print_dynamic_basic_type_header(item); |
8d20e708 | 1224 | printf("%s", item->u.side_basic.u.side_bool ? "true" : "false"); |
4f40d951 | 1225 | break; |
a2e2357e | 1226 | case SIDE_DYNAMIC_TYPE_U8: |
0e9be766 | 1227 | tracer_print_dynamic_basic_type_header(item); |
8d20e708 | 1228 | printf("%" PRIu8, item->u.side_basic.u.side_u8); |
a2e2357e MD |
1229 | break; |
1230 | case SIDE_DYNAMIC_TYPE_U16: | |
8bdd5c12 MD |
1231 | { |
1232 | uint16_t v; | |
1233 | ||
1234 | v = item->u.side_basic.u.side_u16; | |
1235 | if (dynamic_type_to_host_reverse_bo(item)) | |
1236 | v = side_bswap_16(v); | |
0e9be766 | 1237 | tracer_print_dynamic_basic_type_header(item); |
8bdd5c12 | 1238 | printf("%" PRIu16, v); |
a2e2357e | 1239 | break; |
8bdd5c12 | 1240 | } |
a2e2357e | 1241 | case SIDE_DYNAMIC_TYPE_U32: |
8bdd5c12 MD |
1242 | { |
1243 | uint32_t v; | |
1244 | ||
1245 | v = item->u.side_basic.u.side_u32; | |
1246 | if (dynamic_type_to_host_reverse_bo(item)) | |
1247 | v = side_bswap_32(v); | |
0e9be766 | 1248 | tracer_print_dynamic_basic_type_header(item); |
8bdd5c12 | 1249 | printf("%" PRIu32, v); |
a2e2357e | 1250 | break; |
8bdd5c12 | 1251 | } |
a2e2357e | 1252 | case SIDE_DYNAMIC_TYPE_U64: |
8bdd5c12 MD |
1253 | { |
1254 | uint64_t v; | |
1255 | ||
1256 | v = item->u.side_basic.u.side_u64; | |
1257 | if (dynamic_type_to_host_reverse_bo(item)) | |
1258 | v = side_bswap_64(v); | |
0e9be766 | 1259 | tracer_print_dynamic_basic_type_header(item); |
8bdd5c12 | 1260 | printf("%" PRIu64, v); |
a2e2357e | 1261 | break; |
8bdd5c12 | 1262 | } |
a2e2357e | 1263 | case SIDE_DYNAMIC_TYPE_S8: |
0e9be766 | 1264 | tracer_print_dynamic_basic_type_header(item); |
8d20e708 | 1265 | printf("%" PRId8, item->u.side_basic.u.side_s8); |
a2e2357e MD |
1266 | break; |
1267 | case SIDE_DYNAMIC_TYPE_S16: | |
8bdd5c12 MD |
1268 | { |
1269 | int16_t v; | |
1270 | ||
1271 | v = item->u.side_basic.u.side_u16; | |
1272 | if (dynamic_type_to_host_reverse_bo(item)) | |
1273 | v = side_bswap_16(v); | |
0e9be766 | 1274 | tracer_print_dynamic_basic_type_header(item); |
8bdd5c12 | 1275 | printf("%" PRId16, v); |
a2e2357e | 1276 | break; |
8bdd5c12 | 1277 | } |
a2e2357e | 1278 | case SIDE_DYNAMIC_TYPE_S32: |
8bdd5c12 MD |
1279 | { |
1280 | int32_t v; | |
1281 | ||
1282 | v = item->u.side_basic.u.side_u32; | |
1283 | if (dynamic_type_to_host_reverse_bo(item)) | |
1284 | v = side_bswap_32(v); | |
0e9be766 | 1285 | tracer_print_dynamic_basic_type_header(item); |
8bdd5c12 | 1286 | printf("%" PRId32, v); |
a2e2357e | 1287 | break; |
8bdd5c12 | 1288 | } |
a2e2357e | 1289 | case SIDE_DYNAMIC_TYPE_S64: |
8bdd5c12 MD |
1290 | { |
1291 | int64_t v; | |
1292 | ||
1293 | v = item->u.side_basic.u.side_u64; | |
1294 | if (dynamic_type_to_host_reverse_bo(item)) | |
1295 | v = side_bswap_64(v); | |
0e9be766 | 1296 | tracer_print_dynamic_basic_type_header(item); |
8bdd5c12 | 1297 | printf("%" PRId64, v); |
a2e2357e | 1298 | break; |
8bdd5c12 | 1299 | } |
f7653b43 | 1300 | case SIDE_DYNAMIC_TYPE_BYTE: |
0e9be766 | 1301 | tracer_print_dynamic_basic_type_header(item); |
f7653b43 | 1302 | printf("0x%" PRIx8, item->u.side_basic.u.side_byte); |
199e7aa9 MD |
1303 | break; |
1304 | ||
fb25b355 | 1305 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16: |
8bdd5c12 | 1306 | { |
fb25b355 | 1307 | #if __HAVE_FLOAT16 |
8bdd5c12 MD |
1308 | union { |
1309 | _Float16 f; | |
1310 | uint16_t u; | |
1311 | } float16 = { | |
1312 | .f = item->u.side_basic.u.side_float_binary16, | |
1313 | }; | |
1314 | ||
1315 | if (dynamic_type_to_host_reverse_bo(item)) | |
1316 | float16.u = side_bswap_16(float16.u); | |
1317 | tracer_print_dynamic_basic_type_header(item); | |
1318 | printf("%g", (double) float16.f); | |
fb25b355 MD |
1319 | break; |
1320 | #else | |
de1b3cd2 | 1321 | fprintf(stderr, "ERROR: Unsupported binary16 float type\n"); |
fb25b355 MD |
1322 | abort(); |
1323 | #endif | |
8bdd5c12 | 1324 | } |
fb25b355 | 1325 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32: |
8bdd5c12 | 1326 | { |
fb25b355 | 1327 | #if __HAVE_FLOAT32 |
8bdd5c12 MD |
1328 | union { |
1329 | _Float32 f; | |
1330 | uint32_t u; | |
1331 | } float32 = { | |
1332 | .f = item->u.side_basic.u.side_float_binary32, | |
1333 | }; | |
1334 | ||
1335 | if (dynamic_type_to_host_reverse_bo(item)) | |
1336 | float32.u = side_bswap_32(float32.u); | |
1337 | tracer_print_dynamic_basic_type_header(item); | |
1338 | printf("%g", (double) float32.f); | |
fb25b355 MD |
1339 | break; |
1340 | #else | |
de1b3cd2 | 1341 | fprintf(stderr, "ERROR: Unsupported binary32 float type\n"); |
fb25b355 MD |
1342 | abort(); |
1343 | #endif | |
8bdd5c12 | 1344 | } |
fb25b355 | 1345 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64: |
8bdd5c12 | 1346 | { |
fb25b355 | 1347 | #if __HAVE_FLOAT64 |
8bdd5c12 MD |
1348 | union { |
1349 | _Float64 f; | |
1350 | uint64_t u; | |
1351 | } float64 = { | |
1352 | .f = item->u.side_basic.u.side_float_binary64, | |
1353 | }; | |
1354 | ||
1355 | if (dynamic_type_to_host_reverse_bo(item)) | |
1356 | float64.u = side_bswap_64(float64.u); | |
1357 | tracer_print_dynamic_basic_type_header(item); | |
1358 | printf("%g", (double) float64.f); | |
fb25b355 MD |
1359 | break; |
1360 | #else | |
de1b3cd2 | 1361 | fprintf(stderr, "ERROR: Unsupported binary64 float type\n"); |
fb25b355 MD |
1362 | abort(); |
1363 | #endif | |
8bdd5c12 | 1364 | } |
fb25b355 | 1365 | case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128: |
8bdd5c12 | 1366 | { |
fb25b355 | 1367 | #if __HAVE_FLOAT128 |
8bdd5c12 MD |
1368 | union { |
1369 | _Float128 f; | |
1370 | char arr[16]; | |
1371 | } float128 = { | |
1372 | .f = item->u.side_basic.u.side_float_binary128, | |
1373 | }; | |
1374 | ||
1375 | if (dynamic_type_to_host_reverse_bo(item)) | |
1376 | side_bswap_128p(float128.arr); | |
1377 | tracer_print_dynamic_basic_type_header(item); | |
1378 | printf("%Lg", (long double) float128.f); | |
fb25b355 MD |
1379 | break; |
1380 | #else | |
de1b3cd2 | 1381 | fprintf(stderr, "ERROR: Unsupported binary128 float type\n"); |
fb25b355 MD |
1382 | abort(); |
1383 | #endif | |
8bdd5c12 | 1384 | } |
a2e2357e | 1385 | case SIDE_DYNAMIC_TYPE_STRING: |
0e9be766 | 1386 | tracer_print_dynamic_basic_type_header(item); |
8d20e708 | 1387 | printf("\"%s\"", item->u.side_basic.u.string); |
a2e2357e | 1388 | break; |
c208889e MD |
1389 | case SIDE_DYNAMIC_TYPE_STRUCT: |
1390 | tracer_print_dynamic_struct(item->u.side_dynamic_struct); | |
a2e2357e | 1391 | break; |
c208889e MD |
1392 | case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR: |
1393 | tracer_print_dynamic_struct_visitor(item); | |
a2e2357e MD |
1394 | break; |
1395 | case SIDE_DYNAMIC_TYPE_VLA: | |
1396 | tracer_print_dynamic_vla(item->u.side_dynamic_vla); | |
1397 | break; | |
1398 | case SIDE_DYNAMIC_TYPE_VLA_VISITOR: | |
1399 | tracer_print_dynamic_vla_visitor(item); | |
1400 | break; | |
1401 | default: | |
de1b3cd2 | 1402 | fprintf(stderr, "<UNKNOWN TYPE>"); |
a2e2357e MD |
1403 | abort(); |
1404 | } | |
808bd9bf | 1405 | printf(" }"); |
a2e2357e MD |
1406 | } |
1407 | ||
68f8cfbe MD |
1408 | static |
1409 | void tracer_print_static_fields(const struct side_event_description *desc, | |
1410 | const struct side_arg_vec_description *sav_desc, | |
1411 | int *nr_items) | |
f611d0c3 MD |
1412 | { |
1413 | const struct side_arg_vec *sav = sav_desc->sav; | |
1414 | uint32_t side_sav_len = sav_desc->len; | |
1415 | int i; | |
1416 | ||
65010f43 | 1417 | printf("provider: %s, event: %s", desc->provider_name, desc->event_name); |
f611d0c3 | 1418 | if (desc->nr_fields != side_sav_len) { |
de1b3cd2 | 1419 | fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n"); |
f611d0c3 MD |
1420 | abort(); |
1421 | } | |
905c328e | 1422 | print_attributes(", attr", ":", desc->attr, desc->nr_attr); |
a848763d | 1423 | printf("%s", side_sav_len ? ", fields: [ " : ""); |
f611d0c3 MD |
1424 | for (i = 0; i < side_sav_len; i++) { |
1425 | printf("%s", i ? ", " : ""); | |
1426 | tracer_print_field(&desc->fields[i], &sav[i]); | |
1427 | } | |
68f8cfbe MD |
1428 | if (nr_items) |
1429 | *nr_items = i; | |
c7d338e2 MD |
1430 | if (side_sav_len) |
1431 | printf(" ]"); | |
68f8cfbe MD |
1432 | } |
1433 | ||
4a7d8700 MD |
1434 | void tracer_call(const struct side_event_description *desc, |
1435 | const struct side_arg_vec_description *sav_desc, | |
1436 | void *priv __attribute__((unused))) | |
68f8cfbe | 1437 | { |
a848763d MD |
1438 | int nr_fields = 0; |
1439 | ||
a848763d | 1440 | tracer_print_static_fields(desc, sav_desc, &nr_fields); |
f611d0c3 MD |
1441 | printf("\n"); |
1442 | } | |
19fa6aa2 MD |
1443 | |
1444 | void tracer_call_variadic(const struct side_event_description *desc, | |
4a7d8700 MD |
1445 | const struct side_arg_vec_description *sav_desc, |
1446 | const struct side_arg_dynamic_event_struct *var_struct, | |
1447 | void *priv __attribute__((unused))) | |
19fa6aa2 | 1448 | { |
68f8cfbe MD |
1449 | uint32_t var_struct_len = var_struct->len; |
1450 | int nr_fields = 0, i; | |
19fa6aa2 | 1451 | |
68f8cfbe MD |
1452 | tracer_print_static_fields(desc, sav_desc, &nr_fields); |
1453 | ||
8a25ce77 | 1454 | if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) { |
de1b3cd2 | 1455 | fprintf(stderr, "ERROR: unexpected non-variadic event description\n"); |
8a25ce77 MD |
1456 | abort(); |
1457 | } | |
905c328e MD |
1458 | print_attributes(", attr ", "::", var_struct->attr, var_struct->nr_attr); |
1459 | printf("%s", var_struct_len ? ", fields:: [ " : ""); | |
68f8cfbe | 1460 | for (i = 0; i < var_struct_len; i++, nr_fields++) { |
c7d338e2 | 1461 | printf("%s", i ? ", " : ""); |
68f8cfbe MD |
1462 | printf("%s:: ", var_struct->fields[i].field_name); |
1463 | tracer_print_dynamic(&var_struct->fields[i].elem); | |
19fa6aa2 | 1464 | } |
a848763d MD |
1465 | if (i) |
1466 | printf(" ]"); | |
19fa6aa2 MD |
1467 | printf("\n"); |
1468 | } | |
1e8aec23 MD |
1469 | |
1470 | void tracer_event_notification(enum side_tracer_notification notif, | |
1471 | struct side_event_description **events, uint32_t nr_events, void *priv) | |
1472 | { | |
1473 | uint32_t i; | |
314c22c3 | 1474 | int ret; |
1e8aec23 MD |
1475 | |
1476 | printf("----------------------------------------------------------\n"); | |
1477 | printf("Tracer notified of events %s\n", | |
314c22c3 | 1478 | notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed"); |
1e8aec23 MD |
1479 | for (i = 0; i < nr_events; i++) { |
1480 | struct side_event_description *event = events[i]; | |
1481 | ||
1482 | /* Skip NULL pointers */ | |
1483 | if (!event) | |
1484 | continue; | |
1485 | printf("provider: %s, event: %s\n", | |
1486 | event->provider_name, event->event_name); | |
314c22c3 MD |
1487 | if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) { |
1488 | if (event->flags & SIDE_EVENT_FLAG_VARIADIC) { | |
1489 | ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL); | |
1490 | if (ret) | |
1491 | abort(); | |
1492 | } else { | |
1493 | ret = side_tracer_callback_register(event, tracer_call, NULL); | |
1494 | if (ret) | |
1495 | abort(); | |
1496 | } | |
1497 | } else { | |
1498 | if (event->flags & SIDE_EVENT_FLAG_VARIADIC) { | |
1499 | ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL); | |
1500 | if (ret) | |
1501 | abort(); | |
1502 | } else { | |
1503 | ret = side_tracer_callback_unregister(event, tracer_call, NULL); | |
1504 | if (ret) | |
1505 | abort(); | |
1506 | } | |
1507 | } | |
1e8aec23 MD |
1508 | } |
1509 | printf("----------------------------------------------------------\n"); | |
1510 | } | |
1511 | ||
1512 | static __attribute__((constructor)) | |
1513 | void tracer_init(void); | |
1514 | static | |
1515 | void tracer_init(void) | |
1516 | { | |
1517 | tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL); | |
1518 | if (!tracer_handle) | |
1519 | abort(); | |
1520 | } | |
1521 | ||
1522 | static __attribute__((destructor)) | |
1523 | void tracer_exit(void); | |
1524 | static | |
1525 | void tracer_exit(void) | |
1526 | { | |
1527 | side_tracer_event_notification_unregister(tracer_handle); | |
1528 | } |