Introduce event/type description visitor
[libside.git] / src / visit-arg-vec.c
1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2022-2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6 #include <string.h>
7
8 #include "visit-arg-vec.h"
9
10 union int_value {
11 uint64_t u[NR_SIDE_INTEGER128_SPLIT];
12 int64_t s[NR_SIDE_INTEGER128_SPLIT];
13 };
14
15 static
16 void visit_dynamic_type(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv);
17
18 static
19 void visit_dynamic_elem(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv);
20
21 static
22 uint32_t visit_gather_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv);
23
24 static
25 uint32_t visit_gather_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv);
26
27 static
28 void side_visit_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv);
29
30 static
31 void side_visit_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv);
32
33 static
34 uint32_t type_visitor_gather_enum(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv);
35
36 static
37 uint32_t type_visitor_gather_struct(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv);
38
39 static
40 uint32_t type_visitor_gather_array(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv);
41
42 static
43 uint32_t type_visitor_gather_vla(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr,
44 const void *_length_ptr, void *priv);
45
46 static
47 union int_value tracer_load_integer_value(const struct side_type_integer *type_integer,
48 const union side_integer_value *value,
49 uint16_t offset_bits, uint16_t *_len_bits)
50 {
51 union int_value v = {};
52 uint16_t len_bits;
53 bool reverse_bo;
54
55 if (!type_integer->len_bits)
56 len_bits = type_integer->integer_size * CHAR_BIT;
57 else
58 len_bits = type_integer->len_bits;
59 if (len_bits + offset_bits > type_integer->integer_size * CHAR_BIT)
60 abort();
61 reverse_bo = side_enum_get(type_integer->byte_order) != SIDE_TYPE_BYTE_ORDER_HOST;
62 switch (type_integer->integer_size) {
63 case 1:
64 if (type_integer->signedness)
65 v.s[SIDE_INTEGER128_SPLIT_LOW] = value->side_s8;
66 else
67 v.u[SIDE_INTEGER128_SPLIT_LOW] = value->side_u8;
68 break;
69 case 2:
70 if (type_integer->signedness) {
71 int16_t side_s16;
72
73 side_s16 = value->side_s16;
74 if (reverse_bo)
75 side_s16 = side_bswap_16(side_s16);
76 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s16;
77 } else {
78 uint16_t side_u16;
79
80 side_u16 = value->side_u16;
81 if (reverse_bo)
82 side_u16 = side_bswap_16(side_u16);
83 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u16;
84 }
85 break;
86 case 4:
87 if (type_integer->signedness) {
88 int32_t side_s32;
89
90 side_s32 = value->side_s32;
91 if (reverse_bo)
92 side_s32 = side_bswap_32(side_s32);
93 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s32;
94 } else {
95 uint32_t side_u32;
96
97 side_u32 = value->side_u32;
98 if (reverse_bo)
99 side_u32 = side_bswap_32(side_u32);
100 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u32;
101 }
102 break;
103 case 8:
104 if (type_integer->signedness) {
105 int64_t side_s64;
106
107 side_s64 = value->side_s64;
108 if (reverse_bo)
109 side_s64 = side_bswap_64(side_s64);
110 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64;
111 } else {
112 uint64_t side_u64;
113
114 side_u64 = value->side_u64;
115 if (reverse_bo)
116 side_u64 = side_bswap_64(side_u64);
117 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64;
118 }
119 break;
120 case 16:
121 if (type_integer->signedness) {
122 int64_t side_s64[NR_SIDE_INTEGER128_SPLIT];
123
124 side_s64[SIDE_INTEGER128_SPLIT_LOW] = value->side_s128_split[SIDE_INTEGER128_SPLIT_LOW];
125 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_s128_split[SIDE_INTEGER128_SPLIT_HIGH];
126 if (reverse_bo) {
127 side_s64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_LOW]);
128 side_s64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_s64[SIDE_INTEGER128_SPLIT_HIGH]);
129 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
130 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
131 } else {
132 v.s[SIDE_INTEGER128_SPLIT_LOW] = side_s64[SIDE_INTEGER128_SPLIT_LOW];
133 v.s[SIDE_INTEGER128_SPLIT_HIGH] = side_s64[SIDE_INTEGER128_SPLIT_HIGH];
134 }
135 } else {
136 uint64_t side_u64[NR_SIDE_INTEGER128_SPLIT];
137
138 side_u64[SIDE_INTEGER128_SPLIT_LOW] = value->side_u128_split[SIDE_INTEGER128_SPLIT_LOW];
139 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = value->side_u128_split[SIDE_INTEGER128_SPLIT_HIGH];
140 if (reverse_bo) {
141 side_u64[SIDE_INTEGER128_SPLIT_LOW] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_LOW]);
142 side_u64[SIDE_INTEGER128_SPLIT_HIGH] = side_bswap_64(side_u64[SIDE_INTEGER128_SPLIT_HIGH]);
143 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
144 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
145 } else {
146 v.u[SIDE_INTEGER128_SPLIT_LOW] = side_u64[SIDE_INTEGER128_SPLIT_LOW];
147 v.u[SIDE_INTEGER128_SPLIT_HIGH] = side_u64[SIDE_INTEGER128_SPLIT_HIGH];
148 }
149 }
150 break;
151 default:
152 abort();
153 }
154 if (type_integer->integer_size <= 8) {
155 v.u[SIDE_INTEGER128_SPLIT_LOW] >>= offset_bits;
156 if (len_bits < 64) {
157 v.u[SIDE_INTEGER128_SPLIT_LOW] &= (1ULL << len_bits) - 1;
158 if (type_integer->signedness) {
159 /* Sign-extend. */
160 if (v.u[SIDE_INTEGER128_SPLIT_LOW] & (1ULL << (len_bits - 1))) {
161 v.u[SIDE_INTEGER128_SPLIT_LOW] |= ~((1ULL << len_bits) - 1);
162 v.u[SIDE_INTEGER128_SPLIT_HIGH] = ~0ULL;
163 }
164 }
165 }
166 } else {
167 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
168 if (len_bits < 128 || offset_bits != 0)
169 abort();
170 }
171 if (_len_bits)
172 *_len_bits = len_bits;
173 return v;
174 }
175
176 static
177 void side_check_value_u64(union int_value v)
178 {
179 if (v.u[SIDE_INTEGER128_SPLIT_HIGH]) {
180 fprintf(stderr, "Unexpected integer value\n");
181 abort();
182 }
183 }
184
185 /*
186 * return the size of the input string including the null terminator, in
187 * bytes.
188 */
189 static
190 size_t type_visitor_strlen(const void *p, uint8_t unit_size)
191 {
192 size_t inbytesleft = 0;
193
194 switch (unit_size) {
195 case 1:
196 {
197 const char *str = p;
198
199 return strlen(str) + 1;
200 }
201 case 2:
202 {
203 const uint16_t *p16 = p;
204
205 for (; *p16; p16++)
206 inbytesleft += 2;
207 return inbytesleft + 2; /* Include 2-byte null terminator. */
208 }
209 case 4:
210 {
211 const uint32_t *p32 = p;
212
213 for (; *p32; p32++)
214 inbytesleft += 4;
215 return inbytesleft + 4; /* Include 4-byte null terminator. */
216 }
217 default:
218 fprintf(stderr, "Unknown string unit size %" PRIu8 "\n", unit_size);
219 abort();
220 }
221 }
222
223 static
224 void side_visit_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv)
225 {
226 if (type_visitor->elem_func)
227 type_visitor->elem_func(SIDE_TYPE_VISITOR_BEFORE, type_desc, priv);
228 side_visit_type(type_visitor, type_desc, item, priv);
229 if (type_visitor->elem_func)
230 type_visitor->elem_func(SIDE_TYPE_VISITOR_AFTER, type_desc, priv);
231 }
232
233 static
234 void side_visit_field(const struct side_type_visitor *type_visitor, const struct side_event_field *item_desc, const struct side_arg *item, void *priv)
235 {
236 if (type_visitor->field_func)
237 type_visitor->field_func(SIDE_TYPE_VISITOR_BEFORE, item_desc, priv);
238 side_visit_type(type_visitor, &item_desc->side_type, item, priv);
239 if (type_visitor->field_func)
240 type_visitor->field_func(SIDE_TYPE_VISITOR_AFTER, item_desc, priv);
241 }
242
243 static
244 void type_visitor_struct(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec, void *priv)
245 {
246 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
247 const struct side_type_struct *side_struct = side_ptr_get(type_desc->u.side_struct);
248 uint32_t i, side_sav_len = side_arg_vec->len;
249
250 if (side_struct->nr_fields != side_sav_len) {
251 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n");
252 abort();
253 }
254 if (type_visitor->struct_type_func)
255 type_visitor->struct_type_func(SIDE_TYPE_VISITOR_BEFORE, side_struct, side_arg_vec, priv);
256 for (i = 0; i < side_sav_len; i++)
257 side_visit_field(type_visitor, &side_ptr_get(side_struct->fields)[i], &sav[i], priv);
258 if (type_visitor->struct_type_func)
259 type_visitor->struct_type_func(SIDE_TYPE_VISITOR_AFTER, side_struct, side_arg_vec, priv);
260 }
261
262 static
263 void type_visitor_variant(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg_variant *side_arg_variant, void *priv)
264 {
265 const struct side_type_variant *side_type_variant = side_ptr_get(type_desc->u.side_variant);
266 const struct side_type *selector_type = &side_type_variant->selector;
267 union int_value v;
268 uint32_t i;
269
270 if (side_enum_get(selector_type->type) != side_enum_get(side_arg_variant->selector.type)) {
271 fprintf(stderr, "ERROR: Unexpected variant selector type\n");
272 abort();
273 }
274 switch (side_enum_get(selector_type->type)) {
275 case SIDE_TYPE_U8:
276 case SIDE_TYPE_U16:
277 case SIDE_TYPE_U32:
278 case SIDE_TYPE_U64:
279 case SIDE_TYPE_U128:
280 case SIDE_TYPE_S8:
281 case SIDE_TYPE_S16:
282 case SIDE_TYPE_S32:
283 case SIDE_TYPE_S64:
284 case SIDE_TYPE_S128:
285 break;
286 default:
287 fprintf(stderr, "ERROR: Expecting integer variant selector type\n");
288 abort();
289 }
290 v = tracer_load_integer_value(&selector_type->u.side_integer,
291 &side_arg_variant->selector.u.side_static.integer_value, 0, NULL);
292 side_check_value_u64(v);
293 for (i = 0; i < side_type_variant->nr_options; i++) {
294 const struct side_variant_option *option = &side_ptr_get(side_type_variant->options)[i];
295
296 if (v.s[SIDE_INTEGER128_SPLIT_LOW] >= option->range_begin && v.s[SIDE_INTEGER128_SPLIT_LOW] <= option->range_end) {
297 side_visit_type(type_visitor, &option->side_type, &side_arg_variant->option, priv);
298 return;
299 }
300 }
301 fprintf(stderr, "ERROR: Variant selector value unknown %" PRId64 "\n", v.s[SIDE_INTEGER128_SPLIT_LOW]);
302 abort();
303 }
304
305 static
306 void type_visitor_array(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec, void *priv)
307 {
308 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
309 uint32_t i, side_sav_len = side_arg_vec->len;
310
311 if (type_desc->u.side_array.length != side_sav_len) {
312 fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n");
313 abort();
314 }
315 if (type_visitor->array_type_func)
316 type_visitor->array_type_func(SIDE_TYPE_VISITOR_BEFORE, &type_desc->u.side_array, side_arg_vec, priv);
317 for (i = 0; i < side_sav_len; i++)
318 side_visit_elem(type_visitor, side_ptr_get(type_desc->u.side_array.elem_type), &sav[i], priv);
319 if (type_visitor->array_type_func)
320 type_visitor->array_type_func(SIDE_TYPE_VISITOR_AFTER, &type_desc->u.side_array, side_arg_vec, priv);
321 }
322
323 static
324 void type_visitor_vla(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec, void *priv)
325 {
326 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
327 uint32_t i, side_sav_len = side_arg_vec->len;
328
329 if (type_visitor->vla_type_func)
330 type_visitor->vla_type_func(SIDE_TYPE_VISITOR_BEFORE, &type_desc->u.side_vla, side_arg_vec, priv);
331 for (i = 0; i < side_sav_len; i++)
332 side_visit_elem(type_visitor, side_ptr_get(type_desc->u.side_vla.elem_type), &sav[i], priv);
333 if (type_visitor->vla_type_func)
334 type_visitor->vla_type_func(SIDE_TYPE_VISITOR_AFTER, &type_desc->u.side_vla, side_arg_vec, priv);
335 }
336
337 struct tracer_visitor_priv {
338 const struct side_type_visitor *type_visitor;
339 void *priv;
340 const struct side_type *elem_type;
341 int i;
342 };
343
344 static
345 enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
346 const struct side_arg *elem)
347 {
348 struct tracer_visitor_priv *tracer_priv = (struct tracer_visitor_priv *) tracer_ctx->priv;
349
350 side_visit_elem(tracer_priv->type_visitor, tracer_priv->elem_type, elem, tracer_priv->priv);
351 return SIDE_VISITOR_STATUS_OK;
352 }
353
354 static
355 void type_visitor_vla_visitor(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, struct side_arg_vla_visitor *vla_visitor, void *priv)
356 {
357 struct tracer_visitor_priv tracer_priv = {
358 .type_visitor = type_visitor,
359 .priv = priv,
360 .elem_type = side_ptr_get(side_ptr_get(type_desc->u.side_vla_visitor)->elem_type),
361 .i = 0,
362 };
363 const struct side_tracer_visitor_ctx tracer_ctx = {
364 .write_elem = tracer_write_elem_cb,
365 .priv = &tracer_priv,
366 };
367 enum side_visitor_status status;
368 side_visitor_func func;
369 void *app_ctx;
370
371 if (!vla_visitor)
372 abort();
373 if (type_visitor->vla_visitor_type_func)
374 type_visitor->vla_visitor_type_func(SIDE_TYPE_VISITOR_BEFORE, side_ptr_get(type_desc->u.side_vla_visitor), vla_visitor, priv);
375 app_ctx = side_ptr_get(vla_visitor->app_ctx);
376 func = side_ptr_get(side_ptr_get(type_desc->u.side_vla_visitor)->visitor);
377 status = func(&tracer_ctx, app_ctx);
378 switch (status) {
379 case SIDE_VISITOR_STATUS_OK:
380 break;
381 case SIDE_VISITOR_STATUS_ERROR:
382 fprintf(stderr, "ERROR: Visitor error\n");
383 abort();
384 }
385 if (type_visitor->vla_visitor_type_func)
386 type_visitor->vla_visitor_type_func(SIDE_TYPE_VISITOR_AFTER, side_ptr_get(type_desc->u.side_vla_visitor), vla_visitor, priv);
387 }
388
389 static
390 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode, const char *ptr)
391 {
392 switch (access_mode) {
393 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
394 return ptr;
395 case SIDE_TYPE_GATHER_ACCESS_POINTER:
396 /* Dereference pointer */
397 memcpy(&ptr, ptr, sizeof(const char *));
398 return ptr;
399 default:
400 abort();
401 }
402 }
403
404 static
405 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode, uint32_t len)
406 {
407 switch (access_mode) {
408 case SIDE_TYPE_GATHER_ACCESS_DIRECT:
409 return len;
410 case SIDE_TYPE_GATHER_ACCESS_POINTER:
411 return sizeof(void *);
412 default:
413 abort();
414 }
415 }
416
417 static
418 union int_value tracer_load_gather_integer_value(const struct side_type_gather_integer *side_integer,
419 const void *_ptr)
420 {
421 enum side_type_gather_access_mode access_mode = side_enum_get(side_integer->access_mode);
422 uint32_t integer_size_bytes = side_integer->type.integer_size;
423 const char *ptr = (const char *) _ptr;
424 union side_integer_value value;
425
426 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
427 memcpy(&value, ptr, integer_size_bytes);
428 return tracer_load_integer_value(&side_integer->type, &value,
429 side_integer->offset_bits, NULL);
430 }
431
432 static
433 void visit_gather_field(const struct side_type_visitor *type_visitor, const struct side_event_field *field, const void *ptr, void *priv)
434 {
435 if (type_visitor->field_func)
436 type_visitor->field_func(SIDE_TYPE_VISITOR_BEFORE, field, priv);
437 (void) visit_gather_type(type_visitor, &field->side_type, ptr, priv);
438 if (type_visitor->field_func)
439 type_visitor->field_func(SIDE_TYPE_VISITOR_AFTER, field, priv);
440 }
441
442 static
443 uint32_t type_visitor_gather_struct(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
444 {
445 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_struct.access_mode);
446 const struct side_type_struct *side_struct = side_ptr_get(type_gather->u.side_struct.type);
447 const char *ptr = (const char *) _ptr;
448 uint32_t i;
449
450 if (type_visitor->gather_struct_type_func)
451 type_visitor->gather_struct_type_func(SIDE_TYPE_VISITOR_BEFORE, side_struct, priv);
452 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_struct.offset);
453 for (i = 0; i < side_struct->nr_fields; i++)
454 visit_gather_field(type_visitor, &side_ptr_get(side_struct->fields)[i], ptr, priv);
455 if (type_visitor->gather_struct_type_func)
456 type_visitor->gather_struct_type_func(SIDE_TYPE_VISITOR_AFTER, side_struct, priv);
457 return tracer_gather_size(access_mode, type_gather->u.side_struct.size);
458 }
459
460 static
461 uint32_t type_visitor_gather_array(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
462 {
463 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_array.access_mode);
464 const struct side_type_array *side_array = &type_gather->u.side_array.type;
465 const char *ptr = (const char *) _ptr, *orig_ptr;
466 uint32_t i;
467
468 if (type_visitor->gather_array_type_func)
469 type_visitor->gather_array_type_func(SIDE_TYPE_VISITOR_BEFORE, side_array, priv);
470 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_array.offset);
471 orig_ptr = ptr;
472 for (i = 0; i < side_array->length; i++) {
473 const struct side_type *elem_type = side_ptr_get(side_array->elem_type);
474
475 switch (side_enum_get(elem_type->type)) {
476 case SIDE_TYPE_GATHER_VLA:
477 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
478 abort();
479 default:
480 break;
481 }
482 ptr += visit_gather_elem(type_visitor, elem_type, ptr, priv);
483 }
484 if (type_visitor->gather_array_type_func)
485 type_visitor->gather_array_type_func(SIDE_TYPE_VISITOR_AFTER, side_array, priv);
486 return tracer_gather_size(access_mode, ptr - orig_ptr);
487 }
488
489 static
490 uint32_t type_visitor_gather_vla(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, const void *_length_ptr, void *priv)
491 {
492 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_vla.access_mode);
493 const struct side_type_vla *side_vla = &type_gather->u.side_vla.type;
494 const struct side_type *length_type = side_ptr_get(type_gather->u.side_vla.type.length_type);
495 const char *ptr = (const char *) _ptr, *orig_ptr;
496 const char *length_ptr = (const char *) _length_ptr;
497 union int_value v = {};
498 uint32_t i, length;
499
500 /* Access length */
501 switch (side_enum_get(length_type->type)) {
502 case SIDE_TYPE_GATHER_INTEGER:
503 break;
504 default:
505 fprintf(stderr, "<gather VLA expects integer gather length type>\n");
506 abort();
507 }
508 v = tracer_load_gather_integer_value(&length_type->u.side_gather.u.side_integer,
509 length_ptr);
510 if (v.u[SIDE_INTEGER128_SPLIT_HIGH] || v.u[SIDE_INTEGER128_SPLIT_LOW] > UINT32_MAX) {
511 fprintf(stderr, "Unexpected vla length value\n");
512 abort();
513 }
514 length = (uint32_t) v.u[SIDE_INTEGER128_SPLIT_LOW];
515 if (type_visitor->gather_vla_type_func)
516 type_visitor->gather_vla_type_func(SIDE_TYPE_VISITOR_BEFORE, side_vla, length, priv);
517 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_vla.offset);
518 orig_ptr = ptr;
519 for (i = 0; i < length; i++) {
520 const struct side_type *elem_type = side_ptr_get(side_vla->elem_type);
521
522 switch (side_enum_get(elem_type->type)) {
523 case SIDE_TYPE_GATHER_VLA:
524 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
525 abort();
526 default:
527 break;
528 }
529 ptr += visit_gather_elem(type_visitor, elem_type, ptr, priv);
530 }
531 if (type_visitor->gather_vla_type_func)
532 type_visitor->gather_vla_type_func(SIDE_TYPE_VISITOR_AFTER, side_vla, length, priv);
533 return tracer_gather_size(access_mode, ptr - orig_ptr);
534 }
535
536 static
537 uint32_t type_visitor_gather_bool(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
538 {
539 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_bool.access_mode);
540 uint32_t bool_size_bytes = type_gather->u.side_bool.type.bool_size;
541 const char *ptr = (const char *) _ptr;
542 union side_bool_value value;
543
544 switch (bool_size_bytes) {
545 case 1:
546 case 2:
547 case 4:
548 case 8:
549 break;
550 default:
551 abort();
552 }
553 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_bool.offset);
554 memcpy(&value, ptr, bool_size_bytes);
555 if (type_visitor->gather_bool_type_func)
556 type_visitor->gather_bool_type_func(&type_gather->u.side_bool, &value, priv);
557 return tracer_gather_size(access_mode, bool_size_bytes);
558 }
559
560 static
561 uint32_t type_visitor_gather_byte(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
562 {
563 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_byte.access_mode);
564 const char *ptr = (const char *) _ptr;
565 uint8_t value;
566
567 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_byte.offset);
568 memcpy(&value, ptr, 1);
569 if (type_visitor->gather_byte_type_func)
570 type_visitor->gather_byte_type_func(&type_gather->u.side_byte, &value, priv);
571 return tracer_gather_size(access_mode, 1);
572 }
573
574 static
575 uint32_t type_visitor_gather_integer(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr,
576 enum side_type_label integer_type, void *priv)
577 {
578 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_integer.access_mode);
579 uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size;
580 const char *ptr = (const char *) _ptr;
581 union side_integer_value value;
582
583 switch (integer_size_bytes) {
584 case 1:
585 case 2:
586 case 4:
587 case 8:
588 case 16:
589 break;
590 default:
591 abort();
592 }
593 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset);
594 memcpy(&value, ptr, integer_size_bytes);
595 switch (integer_type) {
596 case SIDE_TYPE_GATHER_INTEGER:
597 if (type_visitor->gather_integer_type_func)
598 type_visitor->gather_integer_type_func(&type_gather->u.side_integer, &value, priv);
599 break;
600 case SIDE_TYPE_GATHER_POINTER:
601 if (type_visitor->gather_pointer_type_func)
602 type_visitor->gather_pointer_type_func(&type_gather->u.side_integer, &value, priv);
603 break;
604 default:
605 fprintf(stderr, "Unexpected integer type\n");
606 abort();
607 }
608 return tracer_gather_size(access_mode, integer_size_bytes);
609 }
610
611 static
612 uint32_t type_visitor_gather_float(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
613 {
614 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_float.access_mode);
615 uint32_t float_size_bytes = type_gather->u.side_float.type.float_size;
616 const char *ptr = (const char *) _ptr;
617 union side_float_value value;
618
619 switch (float_size_bytes) {
620 case 2:
621 case 4:
622 case 8:
623 case 16:
624 break;
625 default:
626 abort();
627 }
628 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_float.offset);
629 memcpy(&value, ptr, float_size_bytes);
630 if (type_visitor->gather_float_type_func)
631 type_visitor->gather_float_type_func(&type_gather->u.side_float, &value, priv);
632 return tracer_gather_size(access_mode, float_size_bytes);
633 }
634
635 static
636 uint32_t type_visitor_gather_string(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
637 {
638
639 enum side_type_gather_access_mode access_mode = side_enum_get(type_gather->u.side_string.access_mode);
640 enum side_type_label_byte_order byte_order = side_enum_get(type_gather->u.side_string.type.byte_order);
641 uint8_t unit_size = type_gather->u.side_string.type.unit_size;
642 const char *ptr = (const char *) _ptr;
643 size_t string_len = 0;
644
645 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_string.offset);
646 if (ptr)
647 string_len = type_visitor_strlen(ptr, unit_size);
648 if (type_visitor->gather_string_type_func)
649 type_visitor->gather_string_type_func(&type_gather->u.side_string, ptr, unit_size,
650 byte_order, string_len, priv);
651 return tracer_gather_size(access_mode, string_len);
652 }
653
654 static
655 uint32_t visit_gather_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv)
656 {
657 uint32_t len;
658
659 switch (side_enum_get(type_desc->type)) {
660 /* Gather basic types */
661 case SIDE_TYPE_GATHER_BOOL:
662 len = type_visitor_gather_bool(type_visitor, &type_desc->u.side_gather, ptr, priv);
663 break;
664 case SIDE_TYPE_GATHER_INTEGER:
665 len = type_visitor_gather_integer(type_visitor, &type_desc->u.side_gather, ptr, SIDE_TYPE_GATHER_INTEGER, priv);
666 break;
667 case SIDE_TYPE_GATHER_BYTE:
668 len = type_visitor_gather_byte(type_visitor, &type_desc->u.side_gather, ptr, priv);
669 break;
670 case SIDE_TYPE_GATHER_POINTER:
671 len = type_visitor_gather_integer(type_visitor, &type_desc->u.side_gather, ptr, SIDE_TYPE_GATHER_POINTER, priv);
672 break;
673 case SIDE_TYPE_GATHER_FLOAT:
674 len = type_visitor_gather_float(type_visitor, &type_desc->u.side_gather, ptr, priv);
675 break;
676 case SIDE_TYPE_GATHER_STRING:
677 len = type_visitor_gather_string(type_visitor, &type_desc->u.side_gather, ptr, priv);
678 break;
679
680 /* Gather enumeration types */
681 case SIDE_TYPE_GATHER_ENUM:
682 len = type_visitor_gather_enum(type_visitor, &type_desc->u.side_gather, ptr, priv);
683 break;
684
685 /* Gather compound types */
686 case SIDE_TYPE_GATHER_STRUCT:
687 len = type_visitor_gather_struct(type_visitor, &type_desc->u.side_gather, ptr, priv);
688 break;
689 case SIDE_TYPE_GATHER_ARRAY:
690 len = type_visitor_gather_array(type_visitor, &type_desc->u.side_gather, ptr, priv);
691 break;
692 case SIDE_TYPE_GATHER_VLA:
693 len = type_visitor_gather_vla(type_visitor, &type_desc->u.side_gather, ptr, ptr, priv);
694 break;
695 default:
696 fprintf(stderr, "<UNKNOWN GATHER TYPE>");
697 abort();
698 }
699 return len;
700 }
701
702 static
703 uint32_t visit_gather_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv)
704 {
705 uint32_t len;
706
707 if (type_visitor->elem_func)
708 type_visitor->elem_func(SIDE_TYPE_VISITOR_BEFORE, type_desc, priv);
709 len = visit_gather_type(type_visitor, type_desc, ptr, priv);
710 if (type_visitor->elem_func)
711 type_visitor->elem_func(SIDE_TYPE_VISITOR_AFTER, type_desc, priv);
712 return len;
713 }
714
715 static
716 uint32_t type_visitor_gather_enum(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
717 {
718 const struct side_type *enum_elem_type = side_ptr_get(type_gather->u.side_enum.elem_type);
719 const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer;
720 enum side_type_gather_access_mode access_mode = side_enum_get(side_integer->access_mode);
721 uint32_t integer_size_bytes = side_integer->type.integer_size;
722 const char *ptr = (const char *) _ptr;
723 union side_integer_value value;
724
725 switch (integer_size_bytes) {
726 case 1:
727 case 2:
728 case 4:
729 case 8:
730 case 16:
731 break;
732 default:
733 abort();
734 }
735 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
736 memcpy(&value, ptr, integer_size_bytes);
737 if (type_visitor->gather_enum_type_func)
738 type_visitor->gather_enum_type_func(&type_gather->u.side_enum, &value, priv);
739 return tracer_gather_size(access_mode, integer_size_bytes);
740 }
741
742 static
743 void visit_dynamic_field(const struct side_type_visitor *type_visitor, const struct side_arg_dynamic_field *field, void *priv)
744 {
745 if (type_visitor->dynamic_field_func)
746 type_visitor->dynamic_field_func(SIDE_TYPE_VISITOR_BEFORE, field, priv);
747 visit_dynamic_type(type_visitor, &field->elem, priv);
748 if (type_visitor->dynamic_field_func)
749 type_visitor->dynamic_field_func(SIDE_TYPE_VISITOR_AFTER, field, priv);
750 }
751
752 static
753 void type_visitor_dynamic_struct(const struct side_type_visitor *type_visitor, const struct side_arg_dynamic_struct *dynamic_struct, void *priv)
754 {
755 const struct side_arg_dynamic_field *fields = side_ptr_get(dynamic_struct->fields);
756 uint32_t i, len = dynamic_struct->len;
757
758 if (type_visitor->dynamic_struct_func)
759 type_visitor->dynamic_struct_func(SIDE_TYPE_VISITOR_BEFORE, dynamic_struct, priv);
760 for (i = 0; i < len; i++)
761 visit_dynamic_field(type_visitor, &fields[i], priv);
762 if (type_visitor->dynamic_struct_func)
763 type_visitor->dynamic_struct_func(SIDE_TYPE_VISITOR_AFTER, dynamic_struct, priv);
764 }
765
766 struct tracer_dynamic_struct_visitor_priv {
767 const struct side_type_visitor *type_visitor;
768 void *priv;
769 int i;
770 };
771
772 static
773 enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
774 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
775 const struct side_arg_dynamic_field *dynamic_field)
776 {
777 struct tracer_dynamic_struct_visitor_priv *tracer_priv =
778 (struct tracer_dynamic_struct_visitor_priv *) tracer_ctx->priv;
779
780 visit_dynamic_field(tracer_priv->type_visitor, dynamic_field, tracer_priv->priv);
781 return SIDE_VISITOR_STATUS_OK;
782 }
783
784 static
785 void type_visitor_dynamic_struct_visitor(const struct side_type_visitor *type_visitor, const struct side_arg *item, void *priv)
786 {
787 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
788 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
789 .type_visitor = type_visitor,
790 .priv = priv,
791 .i = 0,
792 };
793 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
794 .write_field = tracer_dynamic_struct_write_elem_cb,
795 .priv = &tracer_priv,
796 };
797 enum side_visitor_status status;
798 void *app_ctx;
799
800 if (type_visitor->dynamic_struct_visitor_func)
801 type_visitor->dynamic_struct_visitor_func(SIDE_TYPE_VISITOR_BEFORE, item, priv);
802 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
803 if (!dynamic_struct_visitor)
804 abort();
805 app_ctx = side_ptr_get(dynamic_struct_visitor->app_ctx);
806 status = side_ptr_get(dynamic_struct_visitor->visitor)(&tracer_ctx, app_ctx);
807 switch (status) {
808 case SIDE_VISITOR_STATUS_OK:
809 break;
810 case SIDE_VISITOR_STATUS_ERROR:
811 fprintf(stderr, "ERROR: Visitor error\n");
812 abort();
813 }
814 if (type_visitor->dynamic_struct_visitor_func)
815 type_visitor->dynamic_struct_visitor_func(SIDE_TYPE_VISITOR_AFTER, item, priv);
816 }
817
818 static
819 void type_visitor_dynamic_vla(const struct side_type_visitor *type_visitor, const struct side_arg_dynamic_vla *vla, void *priv)
820 {
821 const struct side_arg *sav = side_ptr_get(vla->sav);
822 uint32_t i, side_sav_len = vla->len;
823
824 if (type_visitor->dynamic_vla_func)
825 type_visitor->dynamic_vla_func(SIDE_TYPE_VISITOR_BEFORE, vla, priv);
826 for (i = 0; i < side_sav_len; i++)
827 visit_dynamic_elem(type_visitor, &sav[i], priv);
828 if (type_visitor->dynamic_vla_func)
829 type_visitor->dynamic_vla_func(SIDE_TYPE_VISITOR_AFTER, vla, priv);
830 }
831
832 struct tracer_dynamic_vla_visitor_priv {
833 const struct side_type_visitor *type_visitor;
834 void *priv;
835 int i;
836 };
837
838 static
839 enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
840 const struct side_tracer_visitor_ctx *tracer_ctx,
841 const struct side_arg *elem)
842 {
843 struct tracer_dynamic_vla_visitor_priv *tracer_priv =
844 (struct tracer_dynamic_vla_visitor_priv *) tracer_ctx->priv;
845
846 visit_dynamic_elem(tracer_priv->type_visitor, elem, tracer_priv->priv);
847 return SIDE_VISITOR_STATUS_OK;
848 }
849
850 static
851 void type_visitor_dynamic_vla_visitor(const struct side_type_visitor *type_visitor, const struct side_arg *item, void *priv)
852 {
853 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
854 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
855 .type_visitor = type_visitor,
856 .priv = priv,
857 .i = 0,
858 };
859 const struct side_tracer_visitor_ctx tracer_ctx = {
860 .write_elem = tracer_dynamic_vla_write_elem_cb,
861 .priv = &tracer_priv,
862 };
863 enum side_visitor_status status;
864 void *app_ctx;
865
866 if (type_visitor->dynamic_vla_visitor_func)
867 type_visitor->dynamic_vla_visitor_func(SIDE_TYPE_VISITOR_BEFORE, item, priv);
868 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
869 if (!dynamic_vla_visitor)
870 abort();
871 app_ctx = side_ptr_get(dynamic_vla_visitor->app_ctx);
872 status = side_ptr_get(dynamic_vla_visitor->visitor)(&tracer_ctx, app_ctx);
873 switch (status) {
874 case SIDE_VISITOR_STATUS_OK:
875 break;
876 case SIDE_VISITOR_STATUS_ERROR:
877 fprintf(stderr, "ERROR: Visitor error\n");
878 abort();
879 }
880 if (type_visitor->dynamic_vla_visitor_func)
881 type_visitor->dynamic_vla_visitor_func(SIDE_TYPE_VISITOR_AFTER, item, priv);
882 }
883
884 static
885 void visit_dynamic_type(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv)
886 {
887 switch (side_enum_get(dynamic_item->type)) {
888 /* Dynamic basic types */
889 case SIDE_TYPE_DYNAMIC_NULL:
890 if (type_visitor->dynamic_null_func)
891 type_visitor->dynamic_null_func(dynamic_item, priv);
892 break;
893 case SIDE_TYPE_DYNAMIC_BOOL:
894 if (type_visitor->dynamic_bool_func)
895 type_visitor->dynamic_bool_func(dynamic_item, priv);
896 break;
897 case SIDE_TYPE_DYNAMIC_INTEGER:
898 if (type_visitor->dynamic_integer_func)
899 type_visitor->dynamic_integer_func(dynamic_item, priv);
900 break;
901 case SIDE_TYPE_DYNAMIC_BYTE:
902 if (type_visitor->dynamic_byte_func)
903 type_visitor->dynamic_byte_func(dynamic_item, priv);
904 break;
905 case SIDE_TYPE_DYNAMIC_POINTER:
906 if (type_visitor->dynamic_pointer_func)
907 type_visitor->dynamic_pointer_func(dynamic_item, priv);
908 break;
909 case SIDE_TYPE_DYNAMIC_FLOAT:
910 if (type_visitor->dynamic_float_func)
911 type_visitor->dynamic_float_func(dynamic_item, priv);
912 break;
913 case SIDE_TYPE_DYNAMIC_STRING:
914 if (type_visitor->dynamic_string_func)
915 type_visitor->dynamic_string_func(dynamic_item, priv);
916 break;
917
918 /* Dynamic compound types */
919 case SIDE_TYPE_DYNAMIC_STRUCT:
920 type_visitor_dynamic_struct(type_visitor, side_ptr_get(dynamic_item->u.side_dynamic.side_dynamic_struct), priv);
921 break;
922 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
923 type_visitor_dynamic_struct_visitor(type_visitor, dynamic_item, priv);
924 break;
925 case SIDE_TYPE_DYNAMIC_VLA:
926 type_visitor_dynamic_vla(type_visitor, side_ptr_get(dynamic_item->u.side_dynamic.side_dynamic_vla), priv);
927 break;
928 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
929 type_visitor_dynamic_vla_visitor(type_visitor, dynamic_item, priv);
930 break;
931 default:
932 fprintf(stderr, "<UNKNOWN TYPE>\n");
933 abort();
934 }
935 }
936
937 static
938 void visit_dynamic_elem(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv)
939 {
940 if (type_visitor->elem_func)
941 type_visitor->dynamic_elem_func(SIDE_TYPE_VISITOR_BEFORE, dynamic_item, priv);
942 visit_dynamic_type(type_visitor, dynamic_item, priv);
943 if (type_visitor->elem_func)
944 type_visitor->dynamic_elem_func(SIDE_TYPE_VISITOR_AFTER, dynamic_item, priv);
945 }
946
947 void side_visit_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv)
948 {
949 enum side_type_label type;
950
951 switch (side_enum_get(type_desc->type)) {
952 case SIDE_TYPE_ENUM:
953 switch (side_enum_get(item->type)) {
954 case SIDE_TYPE_U8:
955 case SIDE_TYPE_U16:
956 case SIDE_TYPE_U32:
957 case SIDE_TYPE_U64:
958 case SIDE_TYPE_U128:
959 case SIDE_TYPE_S8:
960 case SIDE_TYPE_S16:
961 case SIDE_TYPE_S32:
962 case SIDE_TYPE_S64:
963 case SIDE_TYPE_S128:
964 break;
965 default:
966 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
967 abort();
968 break;
969 }
970 break;
971
972 case SIDE_TYPE_ENUM_BITMAP:
973 switch (side_enum_get(item->type)) {
974 case SIDE_TYPE_U8:
975 case SIDE_TYPE_BYTE:
976 case SIDE_TYPE_U16:
977 case SIDE_TYPE_U32:
978 case SIDE_TYPE_U64:
979 case SIDE_TYPE_U128:
980 case SIDE_TYPE_ARRAY:
981 case SIDE_TYPE_VLA:
982 break;
983 default:
984 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
985 abort();
986 break;
987 }
988 break;
989
990 case SIDE_TYPE_GATHER_ENUM:
991 switch (side_enum_get(item->type)) {
992 case SIDE_TYPE_GATHER_INTEGER:
993 break;
994 default:
995 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
996 abort();
997 break;
998 }
999 break;
1000
1001 case SIDE_TYPE_DYNAMIC:
1002 switch (side_enum_get(item->type)) {
1003 case SIDE_TYPE_DYNAMIC_NULL:
1004 case SIDE_TYPE_DYNAMIC_BOOL:
1005 case SIDE_TYPE_DYNAMIC_INTEGER:
1006 case SIDE_TYPE_DYNAMIC_BYTE:
1007 case SIDE_TYPE_DYNAMIC_POINTER:
1008 case SIDE_TYPE_DYNAMIC_FLOAT:
1009 case SIDE_TYPE_DYNAMIC_STRING:
1010 case SIDE_TYPE_DYNAMIC_STRUCT:
1011 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
1012 case SIDE_TYPE_DYNAMIC_VLA:
1013 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
1014 break;
1015 default:
1016 fprintf(stderr, "ERROR: Unexpected dynamic type\n");
1017 abort();
1018 break;
1019 }
1020 break;
1021
1022 default:
1023 if (side_enum_get(type_desc->type) != side_enum_get(item->type)) {
1024 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
1025 abort();
1026 }
1027 break;
1028 }
1029
1030 if (side_enum_get(type_desc->type) == SIDE_TYPE_ENUM || side_enum_get(type_desc->type) == SIDE_TYPE_ENUM_BITMAP || side_enum_get(type_desc->type) == SIDE_TYPE_GATHER_ENUM)
1031 type = side_enum_get(type_desc->type);
1032 else
1033 type = side_enum_get(item->type);
1034
1035 switch (type) {
1036 /* Stack-copy basic types */
1037 case SIDE_TYPE_NULL:
1038 if (type_visitor->null_type_func)
1039 type_visitor->null_type_func(type_desc, item, priv);
1040 break;
1041 case SIDE_TYPE_BOOL:
1042 if (type_visitor->bool_type_func)
1043 type_visitor->bool_type_func(type_desc, item, priv);
1044 break;
1045 case SIDE_TYPE_U8: /* Fallthrough */
1046 case SIDE_TYPE_U16: /* Fallthrough */
1047 case SIDE_TYPE_U32: /* Fallthrough */
1048 case SIDE_TYPE_U64: /* Fallthrough */
1049 case SIDE_TYPE_U128: /* Fallthrough */
1050 case SIDE_TYPE_S8: /* Fallthrough */
1051 case SIDE_TYPE_S16: /* Fallthrough */
1052 case SIDE_TYPE_S32: /* Fallthrough */
1053 case SIDE_TYPE_S64: /* Fallthrough */
1054 case SIDE_TYPE_S128:
1055 if (type_visitor->integer_type_func)
1056 type_visitor->integer_type_func(type_desc, item, priv);
1057 break;
1058 case SIDE_TYPE_BYTE:
1059 if (type_visitor->byte_type_func)
1060 type_visitor->byte_type_func(type_desc, item, priv);
1061 break;
1062 case SIDE_TYPE_POINTER:
1063 if (type_visitor->pointer_type_func)
1064 type_visitor->pointer_type_func(type_desc, item, priv);
1065 break;
1066 case SIDE_TYPE_FLOAT_BINARY16: /* Fallthrough */
1067 case SIDE_TYPE_FLOAT_BINARY32: /* Fallthrough */
1068 case SIDE_TYPE_FLOAT_BINARY64: /* Fallthrough */
1069 case SIDE_TYPE_FLOAT_BINARY128:
1070 if (type_visitor->float_type_func)
1071 type_visitor->float_type_func(type_desc, item, priv);
1072 break;
1073 case SIDE_TYPE_STRING_UTF8: /* Fallthrough */
1074 case SIDE_TYPE_STRING_UTF16: /* Fallthrough */
1075 case SIDE_TYPE_STRING_UTF32:
1076 if (type_visitor->string_type_func)
1077 type_visitor->string_type_func(type_desc, item, priv);
1078 break;
1079 case SIDE_TYPE_ENUM:
1080 if (type_visitor->enum_type_func)
1081 type_visitor->enum_type_func(type_desc, item, priv);
1082 break;
1083 case SIDE_TYPE_ENUM_BITMAP:
1084 if (type_visitor->enum_bitmap_type_func)
1085 type_visitor->enum_bitmap_type_func(type_desc, item, priv);
1086 break;
1087
1088 /* Stack-copy compound types */
1089 case SIDE_TYPE_STRUCT:
1090 type_visitor_struct(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_struct), priv);
1091 break;
1092 case SIDE_TYPE_VARIANT:
1093 type_visitor_variant(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_variant), priv);
1094 break;
1095 case SIDE_TYPE_ARRAY:
1096 type_visitor_array(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_array), priv);
1097 break;
1098 case SIDE_TYPE_VLA:
1099 type_visitor_vla(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_vla), priv);
1100 break;
1101 case SIDE_TYPE_VLA_VISITOR:
1102 type_visitor_vla_visitor(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_vla_visitor), priv);
1103 break;
1104
1105 /* Gather basic types */
1106 case SIDE_TYPE_GATHER_BOOL:
1107 (void) type_visitor_gather_bool(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_bool_gather_ptr), priv);
1108 break;
1109 case SIDE_TYPE_GATHER_INTEGER:
1110 (void) type_visitor_gather_integer(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr), SIDE_TYPE_GATHER_INTEGER, priv);
1111 break;
1112 case SIDE_TYPE_GATHER_BYTE:
1113 (void) type_visitor_gather_byte(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_byte_gather_ptr), priv);
1114 break;
1115 case SIDE_TYPE_GATHER_POINTER:
1116 (void) type_visitor_gather_integer(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr), SIDE_TYPE_GATHER_POINTER, priv);
1117 break;
1118 case SIDE_TYPE_GATHER_FLOAT:
1119 (void) type_visitor_gather_float(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_float_gather_ptr), priv);
1120 break;
1121 case SIDE_TYPE_GATHER_STRING:
1122 (void) type_visitor_gather_string(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_string_gather_ptr), priv);
1123 break;
1124
1125 /* Gather compound type */
1126 case SIDE_TYPE_GATHER_STRUCT:
1127 (void) type_visitor_gather_struct(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_struct_gather_ptr), priv);
1128 break;
1129 case SIDE_TYPE_GATHER_ARRAY:
1130 (void) type_visitor_gather_array(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_array_gather_ptr), priv);
1131 break;
1132 case SIDE_TYPE_GATHER_VLA:
1133 (void) type_visitor_gather_vla(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_array_gather_ptr),
1134 side_ptr_get(item->u.side_static.side_vla_gather.length_ptr), priv);
1135 break;
1136
1137 /* Gather enumeration types */
1138 case SIDE_TYPE_GATHER_ENUM:
1139 (void) type_visitor_gather_enum(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr), priv);
1140 break;
1141
1142 /* Dynamic basic types */
1143 case SIDE_TYPE_DYNAMIC_NULL: /* Fallthrough */
1144 case SIDE_TYPE_DYNAMIC_BOOL: /* Fallthrough */
1145 case SIDE_TYPE_DYNAMIC_INTEGER: /* Fallthrough */
1146 case SIDE_TYPE_DYNAMIC_BYTE: /* Fallthrough */
1147 case SIDE_TYPE_DYNAMIC_POINTER: /* Fallthrough */
1148 case SIDE_TYPE_DYNAMIC_FLOAT: /* Fallthrough */
1149 case SIDE_TYPE_DYNAMIC_STRING: /* Fallthrough */
1150
1151 /* Dynamic compound types */
1152 case SIDE_TYPE_DYNAMIC_STRUCT: /* Fallthrough */
1153 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR: /* Fallthrough */
1154 case SIDE_TYPE_DYNAMIC_VLA: /* Fallthrough */
1155 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
1156 visit_dynamic_type(type_visitor, item, priv);
1157 break;
1158
1159 default:
1160 fprintf(stderr, "<UNKNOWN TYPE>\n");
1161 abort();
1162 }
1163 }
1164
1165 void type_visitor_event(const struct side_type_visitor *type_visitor,
1166 const struct side_event_description *desc,
1167 const struct side_arg_vec *side_arg_vec,
1168 const struct side_arg_dynamic_struct *var_struct,
1169 void *caller_addr, void *priv)
1170 {
1171 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
1172 uint32_t i, side_sav_len = side_arg_vec->len;
1173
1174 if (desc->nr_fields != side_sav_len) {
1175 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1176 abort();
1177 }
1178 if (type_visitor->event_func)
1179 type_visitor->event_func(SIDE_TYPE_VISITOR_BEFORE, desc, side_arg_vec, var_struct, caller_addr, priv);
1180 if (side_sav_len) {
1181 if (type_visitor->static_fields_func)
1182 type_visitor->static_fields_func(SIDE_TYPE_VISITOR_BEFORE, side_arg_vec, priv);
1183 for (i = 0; i < side_sav_len; i++)
1184 side_visit_field(type_visitor, &side_ptr_get(desc->fields)[i], &sav[i], priv);
1185 if (type_visitor->static_fields_func)
1186 type_visitor->static_fields_func(SIDE_TYPE_VISITOR_AFTER, side_arg_vec, priv);
1187 }
1188 if (var_struct) {
1189 uint32_t var_struct_len = var_struct->len;
1190
1191 if (type_visitor->variadic_fields_func)
1192 type_visitor->variadic_fields_func(SIDE_TYPE_VISITOR_BEFORE, var_struct, priv);
1193 for (i = 0; i < var_struct_len; i++)
1194 visit_dynamic_field(type_visitor, &side_ptr_get(var_struct->fields)[i], priv);
1195 if (type_visitor->variadic_fields_func)
1196 type_visitor->variadic_fields_func(SIDE_TYPE_VISITOR_AFTER, var_struct, priv);
1197 }
1198 if (type_visitor->event_func)
1199 type_visitor->event_func(SIDE_TYPE_VISITOR_AFTER, desc, side_arg_vec, var_struct, caller_addr, priv);
1200 }
This page took 0.056446 seconds and 5 git commands to generate.