Introduce argument vector visitor
[libside.git] / src / visit-arg-vec.c
CommitLineData
980c17b1
MD
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
10union int_value {
11 uint64_t u[NR_SIDE_INTEGER128_SPLIT];
12 int64_t s[NR_SIDE_INTEGER128_SPLIT];
13};
14
15static
16void visit_dynamic_type(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv);
17
18static
19void visit_dynamic_elem(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv);
20
21static
22uint32_t visit_gather_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv);
23
24static
25uint32_t visit_gather_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv);
26
27static
28void side_visit_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv);
29
30static
31void side_visit_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv);
32
33static
34uint32_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
36static
37uint32_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
39static
40uint32_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
42static
43uint32_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
46static
47union 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
176static
177void 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 */
189static
190size_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
223static
224void 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
233static
234void 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
243static
244void 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
262static
263void 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
305static
306void 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
323static
324void 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
337struct 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
344static
345enum 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
354static
355void 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(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, &type_desc->u.side_vla_visitor, vla_visitor, priv);
375 app_ctx = side_ptr_get(vla_visitor->app_ctx);
376 func = 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, &type_desc->u.side_vla_visitor, vla_visitor, priv);
387}
388
389static
390const 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
404static
405uint32_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
417static
418union 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 =
422 (enum side_type_gather_access_mode) side_integer->access_mode;
423 uint32_t integer_size_bytes = side_integer->type.integer_size;
424 const char *ptr = (const char *) _ptr;
425 union side_integer_value value;
426
427 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
428 memcpy(&value, ptr, integer_size_bytes);
429 return tracer_load_integer_value(&side_integer->type, &value,
430 side_integer->offset_bits, NULL);
431}
432
433static
434void visit_gather_field(const struct side_type_visitor *type_visitor, const struct side_event_field *field, const void *ptr, void *priv)
435{
436 if (type_visitor->field_func)
437 type_visitor->field_func(SIDE_TYPE_VISITOR_BEFORE, field, priv);
438 (void) visit_gather_type(type_visitor, &field->side_type, ptr, priv);
439 if (type_visitor->field_func)
440 type_visitor->field_func(SIDE_TYPE_VISITOR_AFTER, field, priv);
441}
442
443static
444uint32_t type_visitor_gather_struct(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
445{
446 enum side_type_gather_access_mode access_mode =
447 (enum side_type_gather_access_mode) type_gather->u.side_struct.access_mode;
448 const struct side_type_struct *side_struct = side_ptr_get(type_gather->u.side_struct.type);
449 const char *ptr = (const char *) _ptr;
450 uint32_t i;
451
452 if (type_visitor->gather_struct_type_func)
453 type_visitor->gather_struct_type_func(SIDE_TYPE_VISITOR_BEFORE, side_struct, priv);
454 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_struct.offset);
455 for (i = 0; i < side_struct->nr_fields; i++)
456 visit_gather_field(type_visitor, &side_ptr_get(side_struct->fields)[i], ptr, priv);
457 if (type_visitor->gather_struct_type_func)
458 type_visitor->gather_struct_type_func(SIDE_TYPE_VISITOR_AFTER, side_struct, priv);
459 return tracer_gather_size(access_mode, type_gather->u.side_struct.size);
460}
461
462static
463uint32_t type_visitor_gather_array(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
464{
465 enum side_type_gather_access_mode access_mode =
466 (enum side_type_gather_access_mode) type_gather->u.side_array.access_mode;
467 const struct side_type_array *side_array = &type_gather->u.side_array.type;
468 const char *ptr = (const char *) _ptr, *orig_ptr;
469 uint32_t i;
470
471 if (type_visitor->gather_array_type_func)
472 type_visitor->gather_array_type_func(SIDE_TYPE_VISITOR_BEFORE, side_array, priv);
473 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_array.offset);
474 orig_ptr = ptr;
475 for (i = 0; i < side_array->length; i++) {
476 const struct side_type *elem_type = side_ptr_get(side_array->elem_type);
477
478 switch (side_enum_get(elem_type->type)) {
479 case SIDE_TYPE_GATHER_VLA:
480 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
481 abort();
482 default:
483 break;
484 }
485 ptr += visit_gather_elem(type_visitor, elem_type, ptr, priv);
486 }
487 if (type_visitor->gather_array_type_func)
488 type_visitor->gather_array_type_func(SIDE_TYPE_VISITOR_AFTER, side_array, priv);
489 return tracer_gather_size(access_mode, ptr - orig_ptr);
490}
491
492static
493uint32_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)
494{
495 enum side_type_gather_access_mode access_mode =
496 (enum side_type_gather_access_mode) type_gather->u.side_vla.access_mode;
497 const struct side_type_vla *side_vla = &type_gather->u.side_vla.type;
498 const struct side_type *length_type = side_ptr_get(type_gather->u.side_vla.length_type);
499 const char *ptr = (const char *) _ptr, *orig_ptr;
500 const char *length_ptr = (const char *) _length_ptr;
501 union int_value v = {};
502 uint32_t i, length;
503
504 /* Access length */
505 switch (side_enum_get(length_type->type)) {
506 case SIDE_TYPE_GATHER_INTEGER:
507 break;
508 default:
509 fprintf(stderr, "<gather VLA expects integer gather length type>\n");
510 abort();
511 }
512 v = tracer_load_gather_integer_value(&length_type->u.side_gather.u.side_integer,
513 length_ptr);
514 if (v.u[SIDE_INTEGER128_SPLIT_HIGH] || v.u[SIDE_INTEGER128_SPLIT_LOW] > UINT32_MAX) {
515 fprintf(stderr, "Unexpected vla length value\n");
516 abort();
517 }
518 length = (uint32_t) v.u[SIDE_INTEGER128_SPLIT_LOW];
519 if (type_visitor->gather_vla_type_func)
520 type_visitor->gather_vla_type_func(SIDE_TYPE_VISITOR_BEFORE, side_vla, length, priv);
521 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_vla.offset);
522 orig_ptr = ptr;
523 for (i = 0; i < length; i++) {
524 const struct side_type *elem_type = side_ptr_get(side_vla->elem_type);
525
526 switch (side_enum_get(elem_type->type)) {
527 case SIDE_TYPE_GATHER_VLA:
528 fprintf(stderr, "<gather VLA only supported within gather structures>\n");
529 abort();
530 default:
531 break;
532 }
533 ptr += visit_gather_elem(type_visitor, elem_type, ptr, priv);
534 }
535 if (type_visitor->gather_vla_type_func)
536 type_visitor->gather_vla_type_func(SIDE_TYPE_VISITOR_AFTER, side_vla, length, priv);
537 return tracer_gather_size(access_mode, ptr - orig_ptr);
538}
539
540static
541uint32_t type_visitor_gather_bool(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
542{
543 enum side_type_gather_access_mode access_mode =
544 (enum side_type_gather_access_mode) type_gather->u.side_bool.access_mode;
545 uint32_t bool_size_bytes = type_gather->u.side_bool.type.bool_size;
546 const char *ptr = (const char *) _ptr;
547 union side_bool_value value;
548
549 switch (bool_size_bytes) {
550 case 1:
551 case 2:
552 case 4:
553 case 8:
554 break;
555 default:
556 abort();
557 }
558 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_bool.offset);
559 memcpy(&value, ptr, bool_size_bytes);
560 if (type_visitor->gather_bool_type_func)
561 type_visitor->gather_bool_type_func(&type_gather->u.side_bool, &value, priv);
562 return tracer_gather_size(access_mode, bool_size_bytes);
563}
564
565static
566uint32_t type_visitor_gather_byte(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
567{
568 enum side_type_gather_access_mode access_mode =
569 (enum side_type_gather_access_mode) type_gather->u.side_byte.access_mode;
570 const char *ptr = (const char *) _ptr;
571 uint8_t value;
572
573 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_byte.offset);
574 memcpy(&value, ptr, 1);
575 if (type_visitor->gather_byte_type_func)
576 type_visitor->gather_byte_type_func(&type_gather->u.side_byte, &value, priv);
577 return tracer_gather_size(access_mode, 1);
578}
579
580static
581uint32_t type_visitor_gather_integer(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr,
582 enum side_type_label integer_type, void *priv)
583{
584 enum side_type_gather_access_mode access_mode =
585 (enum side_type_gather_access_mode) type_gather->u.side_integer.access_mode;
586 uint32_t integer_size_bytes = type_gather->u.side_integer.type.integer_size;
587 const char *ptr = (const char *) _ptr;
588 union side_integer_value value;
589
590 switch (integer_size_bytes) {
591 case 1:
592 case 2:
593 case 4:
594 case 8:
595 case 16:
596 break;
597 default:
598 abort();
599 }
600 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_integer.offset);
601 memcpy(&value, ptr, integer_size_bytes);
602 switch (integer_type) {
603 case SIDE_TYPE_GATHER_INTEGER:
604 if (type_visitor->gather_integer_type_func)
605 type_visitor->gather_integer_type_func(&type_gather->u.side_integer, &value, priv);
606 break;
607 case SIDE_TYPE_GATHER_POINTER:
608 if (type_visitor->gather_pointer_type_func)
609 type_visitor->gather_pointer_type_func(&type_gather->u.side_integer, &value, priv);
610 break;
611 default:
612 fprintf(stderr, "Unexpected integer type\n");
613 abort();
614 }
615 return tracer_gather_size(access_mode, integer_size_bytes);
616}
617
618static
619uint32_t type_visitor_gather_float(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
620{
621 enum side_type_gather_access_mode access_mode =
622 (enum side_type_gather_access_mode) type_gather->u.side_float.access_mode;
623 uint32_t float_size_bytes = type_gather->u.side_float.type.float_size;
624 const char *ptr = (const char *) _ptr;
625 union side_float_value value;
626
627 switch (float_size_bytes) {
628 case 2:
629 case 4:
630 case 8:
631 case 16:
632 break;
633 default:
634 abort();
635 }
636 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_float.offset);
637 memcpy(&value, ptr, float_size_bytes);
638 if (type_visitor->gather_float_type_func)
639 type_visitor->gather_float_type_func(&type_gather->u.side_float, &value, priv);
640 return tracer_gather_size(access_mode, float_size_bytes);
641}
642
643static
644uint32_t type_visitor_gather_string(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
645{
646
647 enum side_type_gather_access_mode access_mode =
648 (enum side_type_gather_access_mode) type_gather->u.side_string.access_mode;
649 enum side_type_label_byte_order byte_order = side_enum_get(type_gather->u.side_string.type.byte_order);
650 uint8_t unit_size = type_gather->u.side_string.type.unit_size;
651 const char *ptr = (const char *) _ptr;
652 size_t string_len = 0;
653
654 ptr = tracer_gather_access(access_mode, ptr + type_gather->u.side_string.offset);
655 if (ptr)
656 string_len = type_visitor_strlen(ptr, unit_size);
657 if (type_visitor->gather_string_type_func)
658 type_visitor->gather_string_type_func(&type_gather->u.side_string, ptr, unit_size,
659 byte_order, string_len, priv);
660 return tracer_gather_size(access_mode, string_len);
661}
662
663static
664uint32_t visit_gather_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv)
665{
666 uint32_t len;
667
668 switch (side_enum_get(type_desc->type)) {
669 /* Gather basic types */
670 case SIDE_TYPE_GATHER_BOOL:
671 len = type_visitor_gather_bool(type_visitor, &type_desc->u.side_gather, ptr, priv);
672 break;
673 case SIDE_TYPE_GATHER_INTEGER:
674 len = type_visitor_gather_integer(type_visitor, &type_desc->u.side_gather, ptr, SIDE_TYPE_GATHER_INTEGER, priv);
675 break;
676 case SIDE_TYPE_GATHER_BYTE:
677 len = type_visitor_gather_byte(type_visitor, &type_desc->u.side_gather, ptr, priv);
678 break;
679 case SIDE_TYPE_GATHER_POINTER:
680 len = type_visitor_gather_integer(type_visitor, &type_desc->u.side_gather, ptr, SIDE_TYPE_GATHER_POINTER, priv);
681 break;
682 case SIDE_TYPE_GATHER_FLOAT:
683 len = type_visitor_gather_float(type_visitor, &type_desc->u.side_gather, ptr, priv);
684 break;
685 case SIDE_TYPE_GATHER_STRING:
686 len = type_visitor_gather_string(type_visitor, &type_desc->u.side_gather, ptr, priv);
687 break;
688
689 /* Gather enumeration types */
690 case SIDE_TYPE_GATHER_ENUM:
691 len = type_visitor_gather_enum(type_visitor, &type_desc->u.side_gather, ptr, priv);
692 break;
693
694 /* Gather compound types */
695 case SIDE_TYPE_GATHER_STRUCT:
696 len = type_visitor_gather_struct(type_visitor, &type_desc->u.side_gather, ptr, priv);
697 break;
698 case SIDE_TYPE_GATHER_ARRAY:
699 len = type_visitor_gather_array(type_visitor, &type_desc->u.side_gather, ptr, priv);
700 break;
701 case SIDE_TYPE_GATHER_VLA:
702 len = type_visitor_gather_vla(type_visitor, &type_desc->u.side_gather, ptr, ptr, priv);
703 break;
704 default:
705 fprintf(stderr, "<UNKNOWN GATHER TYPE>");
706 abort();
707 }
708 return len;
709}
710
711static
712uint32_t visit_gather_elem(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const void *ptr, void *priv)
713{
714 uint32_t len;
715
716 if (type_visitor->elem_func)
717 type_visitor->elem_func(SIDE_TYPE_VISITOR_BEFORE, type_desc, priv);
718 len = visit_gather_type(type_visitor, type_desc, ptr, priv);
719 if (type_visitor->elem_func)
720 type_visitor->elem_func(SIDE_TYPE_VISITOR_AFTER, type_desc, priv);
721 return len;
722}
723
724static
725uint32_t type_visitor_gather_enum(const struct side_type_visitor *type_visitor, const struct side_type_gather *type_gather, const void *_ptr, void *priv)
726{
727 const struct side_type *enum_elem_type = side_ptr_get(type_gather->u.side_enum.elem_type);
728 const struct side_type_gather_integer *side_integer = &enum_elem_type->u.side_gather.u.side_integer;
729 enum side_type_gather_access_mode access_mode =
730 (enum side_type_gather_access_mode) side_integer->access_mode;
731 uint32_t integer_size_bytes = side_integer->type.integer_size;
732 const char *ptr = (const char *) _ptr;
733 union side_integer_value value;
734
735 switch (integer_size_bytes) {
736 case 1:
737 case 2:
738 case 4:
739 case 8:
740 case 16:
741 break;
742 default:
743 abort();
744 }
745 ptr = tracer_gather_access(access_mode, ptr + side_integer->offset);
746 memcpy(&value, ptr, integer_size_bytes);
747 if (type_visitor->gather_enum_type_func)
748 type_visitor->gather_enum_type_func(&type_gather->u.side_enum, &value, priv);
749 return tracer_gather_size(access_mode, integer_size_bytes);
750}
751
752static
753void visit_dynamic_field(const struct side_type_visitor *type_visitor, const struct side_arg_dynamic_field *field, void *priv)
754{
755 if (type_visitor->dynamic_field_func)
756 type_visitor->dynamic_field_func(SIDE_TYPE_VISITOR_BEFORE, field, priv);
757 visit_dynamic_type(type_visitor, &field->elem, priv);
758 if (type_visitor->dynamic_field_func)
759 type_visitor->dynamic_field_func(SIDE_TYPE_VISITOR_AFTER, field, priv);
760}
761
762static
763void type_visitor_dynamic_struct(const struct side_type_visitor *type_visitor, const struct side_arg_dynamic_struct *dynamic_struct, void *priv)
764{
765 const struct side_arg_dynamic_field *fields = side_ptr_get(dynamic_struct->fields);
766 uint32_t i, len = dynamic_struct->len;
767
768 if (type_visitor->dynamic_struct_func)
769 type_visitor->dynamic_struct_func(SIDE_TYPE_VISITOR_BEFORE, dynamic_struct, priv);
770 for (i = 0; i < len; i++)
771 visit_dynamic_field(type_visitor, &fields[i], priv);
772 if (type_visitor->dynamic_struct_func)
773 type_visitor->dynamic_struct_func(SIDE_TYPE_VISITOR_AFTER, dynamic_struct, priv);
774}
775
776struct tracer_dynamic_struct_visitor_priv {
777 const struct side_type_visitor *type_visitor;
778 void *priv;
779 int i;
780};
781
782static
783enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
784 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
785 const struct side_arg_dynamic_field *dynamic_field)
786{
787 struct tracer_dynamic_struct_visitor_priv *tracer_priv =
788 (struct tracer_dynamic_struct_visitor_priv *) tracer_ctx->priv;
789
790 visit_dynamic_field(tracer_priv->type_visitor, dynamic_field, tracer_priv->priv);
791 return SIDE_VISITOR_STATUS_OK;
792}
793
794static
795void type_visitor_dynamic_struct_visitor(const struct side_type_visitor *type_visitor, const struct side_arg *item, void *priv)
796{
797 struct side_arg_dynamic_struct_visitor *dynamic_struct_visitor;
798 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
799 .type_visitor = type_visitor,
800 .priv = priv,
801 .i = 0,
802 };
803 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
804 .write_field = tracer_dynamic_struct_write_elem_cb,
805 .priv = &tracer_priv,
806 };
807 enum side_visitor_status status;
808 void *app_ctx;
809
810 if (type_visitor->dynamic_struct_visitor_func)
811 type_visitor->dynamic_struct_visitor_func(SIDE_TYPE_VISITOR_BEFORE, item, priv);
812 dynamic_struct_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_struct_visitor);
813 if (!dynamic_struct_visitor)
814 abort();
815 app_ctx = side_ptr_get(dynamic_struct_visitor->app_ctx);
816 status = side_ptr_get(dynamic_struct_visitor->visitor)(&tracer_ctx, app_ctx);
817 switch (status) {
818 case SIDE_VISITOR_STATUS_OK:
819 break;
820 case SIDE_VISITOR_STATUS_ERROR:
821 fprintf(stderr, "ERROR: Visitor error\n");
822 abort();
823 }
824 if (type_visitor->dynamic_struct_visitor_func)
825 type_visitor->dynamic_struct_visitor_func(SIDE_TYPE_VISITOR_AFTER, item, priv);
826}
827
828static
829void type_visitor_dynamic_vla(const struct side_type_visitor *type_visitor, const struct side_arg_dynamic_vla *vla, void *priv)
830{
831 const struct side_arg *sav = side_ptr_get(vla->sav);
832 uint32_t i, side_sav_len = vla->len;
833
834 if (type_visitor->dynamic_vla_func)
835 type_visitor->dynamic_vla_func(SIDE_TYPE_VISITOR_BEFORE, vla, priv);
836 for (i = 0; i < side_sav_len; i++)
837 visit_dynamic_elem(type_visitor, &sav[i], priv);
838 if (type_visitor->dynamic_vla_func)
839 type_visitor->dynamic_vla_func(SIDE_TYPE_VISITOR_AFTER, vla, priv);
840}
841
842struct tracer_dynamic_vla_visitor_priv {
843 const struct side_type_visitor *type_visitor;
844 void *priv;
845 int i;
846};
847
848static
849enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
850 const struct side_tracer_visitor_ctx *tracer_ctx,
851 const struct side_arg *elem)
852{
853 struct tracer_dynamic_vla_visitor_priv *tracer_priv =
854 (struct tracer_dynamic_vla_visitor_priv *) tracer_ctx->priv;
855
856 visit_dynamic_elem(tracer_priv->type_visitor, elem, tracer_priv->priv);
857 return SIDE_VISITOR_STATUS_OK;
858}
859
860static
861void type_visitor_dynamic_vla_visitor(const struct side_type_visitor *type_visitor, const struct side_arg *item, void *priv)
862{
863 struct side_arg_dynamic_vla_visitor *dynamic_vla_visitor;
864 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
865 .type_visitor = type_visitor,
866 .priv = priv,
867 .i = 0,
868 };
869 const struct side_tracer_visitor_ctx tracer_ctx = {
870 .write_elem = tracer_dynamic_vla_write_elem_cb,
871 .priv = &tracer_priv,
872 };
873 enum side_visitor_status status;
874 void *app_ctx;
875
876 if (type_visitor->dynamic_vla_visitor_func)
877 type_visitor->dynamic_vla_visitor_func(SIDE_TYPE_VISITOR_BEFORE, item, priv);
878 dynamic_vla_visitor = side_ptr_get(item->u.side_dynamic.side_dynamic_vla_visitor);
879 if (!dynamic_vla_visitor)
880 abort();
881 app_ctx = side_ptr_get(dynamic_vla_visitor->app_ctx);
882 status = side_ptr_get(dynamic_vla_visitor->visitor)(&tracer_ctx, app_ctx);
883 switch (status) {
884 case SIDE_VISITOR_STATUS_OK:
885 break;
886 case SIDE_VISITOR_STATUS_ERROR:
887 fprintf(stderr, "ERROR: Visitor error\n");
888 abort();
889 }
890 if (type_visitor->dynamic_vla_visitor_func)
891 type_visitor->dynamic_vla_visitor_func(SIDE_TYPE_VISITOR_AFTER, item, priv);
892}
893
894static
895void visit_dynamic_type(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv)
896{
897 switch (side_enum_get(dynamic_item->type)) {
898 /* Dynamic basic types */
899 case SIDE_TYPE_DYNAMIC_NULL:
900 if (type_visitor->dynamic_null_func)
901 type_visitor->dynamic_null_func(dynamic_item, priv);
902 break;
903 case SIDE_TYPE_DYNAMIC_BOOL:
904 if (type_visitor->dynamic_bool_func)
905 type_visitor->dynamic_bool_func(dynamic_item, priv);
906 break;
907 case SIDE_TYPE_DYNAMIC_INTEGER:
908 if (type_visitor->dynamic_integer_func)
909 type_visitor->dynamic_integer_func(dynamic_item, priv);
910 break;
911 case SIDE_TYPE_DYNAMIC_BYTE:
912 if (type_visitor->dynamic_byte_func)
913 type_visitor->dynamic_byte_func(dynamic_item, priv);
914 break;
915 case SIDE_TYPE_DYNAMIC_POINTER:
916 if (type_visitor->dynamic_pointer_func)
917 type_visitor->dynamic_pointer_func(dynamic_item, priv);
918 break;
919 case SIDE_TYPE_DYNAMIC_FLOAT:
920 if (type_visitor->dynamic_float_func)
921 type_visitor->dynamic_float_func(dynamic_item, priv);
922 break;
923 case SIDE_TYPE_DYNAMIC_STRING:
924 if (type_visitor->dynamic_string_func)
925 type_visitor->dynamic_string_func(dynamic_item, priv);
926 break;
927
928 /* Dynamic compound types */
929 case SIDE_TYPE_DYNAMIC_STRUCT:
930 type_visitor_dynamic_struct(type_visitor, side_ptr_get(dynamic_item->u.side_dynamic.side_dynamic_struct), priv);
931 break;
932 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
933 type_visitor_dynamic_struct_visitor(type_visitor, dynamic_item, priv);
934 break;
935 case SIDE_TYPE_DYNAMIC_VLA:
936 type_visitor_dynamic_vla(type_visitor, side_ptr_get(dynamic_item->u.side_dynamic.side_dynamic_vla), priv);
937 break;
938 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
939 type_visitor_dynamic_vla_visitor(type_visitor, dynamic_item, priv);
940 break;
941 default:
942 fprintf(stderr, "<UNKNOWN TYPE>\n");
943 abort();
944 }
945}
946
947static
948void visit_dynamic_elem(const struct side_type_visitor *type_visitor, const struct side_arg *dynamic_item, void *priv)
949{
950 if (type_visitor->elem_func)
951 type_visitor->dynamic_elem_func(SIDE_TYPE_VISITOR_BEFORE, dynamic_item, priv);
952 visit_dynamic_type(type_visitor, dynamic_item, priv);
953 if (type_visitor->elem_func)
954 type_visitor->dynamic_elem_func(SIDE_TYPE_VISITOR_AFTER, dynamic_item, priv);
955}
956
957void side_visit_type(const struct side_type_visitor *type_visitor, const struct side_type *type_desc, const struct side_arg *item, void *priv)
958{
959 enum side_type_label type;
960
961 switch (side_enum_get(type_desc->type)) {
962 case SIDE_TYPE_ENUM:
963 switch (side_enum_get(item->type)) {
964 case SIDE_TYPE_U8:
965 case SIDE_TYPE_U16:
966 case SIDE_TYPE_U32:
967 case SIDE_TYPE_U64:
968 case SIDE_TYPE_U128:
969 case SIDE_TYPE_S8:
970 case SIDE_TYPE_S16:
971 case SIDE_TYPE_S32:
972 case SIDE_TYPE_S64:
973 case SIDE_TYPE_S128:
974 break;
975 default:
976 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
977 abort();
978 break;
979 }
980 break;
981
982 case SIDE_TYPE_ENUM_BITMAP:
983 switch (side_enum_get(item->type)) {
984 case SIDE_TYPE_U8:
985 case SIDE_TYPE_BYTE:
986 case SIDE_TYPE_U16:
987 case SIDE_TYPE_U32:
988 case SIDE_TYPE_U64:
989 case SIDE_TYPE_U128:
990 case SIDE_TYPE_ARRAY:
991 case SIDE_TYPE_VLA:
992 break;
993 default:
994 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
995 abort();
996 break;
997 }
998 break;
999
1000 case SIDE_TYPE_GATHER_ENUM:
1001 switch (side_enum_get(item->type)) {
1002 case SIDE_TYPE_GATHER_INTEGER:
1003 break;
1004 default:
1005 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
1006 abort();
1007 break;
1008 }
1009 break;
1010
1011 case SIDE_TYPE_DYNAMIC:
1012 switch (side_enum_get(item->type)) {
1013 case SIDE_TYPE_DYNAMIC_NULL:
1014 case SIDE_TYPE_DYNAMIC_BOOL:
1015 case SIDE_TYPE_DYNAMIC_INTEGER:
1016 case SIDE_TYPE_DYNAMIC_BYTE:
1017 case SIDE_TYPE_DYNAMIC_POINTER:
1018 case SIDE_TYPE_DYNAMIC_FLOAT:
1019 case SIDE_TYPE_DYNAMIC_STRING:
1020 case SIDE_TYPE_DYNAMIC_STRUCT:
1021 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR:
1022 case SIDE_TYPE_DYNAMIC_VLA:
1023 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
1024 break;
1025 default:
1026 fprintf(stderr, "ERROR: Unexpected dynamic type\n");
1027 abort();
1028 break;
1029 }
1030 break;
1031
1032 default:
1033 if (side_enum_get(type_desc->type) != side_enum_get(item->type)) {
1034 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
1035 abort();
1036 }
1037 break;
1038 }
1039
1040 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)
1041 type = side_enum_get(type_desc->type);
1042 else
1043 type = side_enum_get(item->type);
1044
1045 switch (type) {
1046 /* Stack-copy basic types */
1047 case SIDE_TYPE_NULL:
1048 if (type_visitor->null_type_func)
1049 type_visitor->null_type_func(type_desc, item, priv);
1050 break;
1051 case SIDE_TYPE_BOOL:
1052 if (type_visitor->bool_type_func)
1053 type_visitor->bool_type_func(type_desc, item, priv);
1054 break;
1055 case SIDE_TYPE_U8: /* Fallthrough */
1056 case SIDE_TYPE_U16: /* Fallthrough */
1057 case SIDE_TYPE_U32: /* Fallthrough */
1058 case SIDE_TYPE_U64: /* Fallthrough */
1059 case SIDE_TYPE_U128: /* Fallthrough */
1060 case SIDE_TYPE_S8: /* Fallthrough */
1061 case SIDE_TYPE_S16: /* Fallthrough */
1062 case SIDE_TYPE_S32: /* Fallthrough */
1063 case SIDE_TYPE_S64: /* Fallthrough */
1064 case SIDE_TYPE_S128:
1065 if (type_visitor->integer_type_func)
1066 type_visitor->integer_type_func(type_desc, item, priv);
1067 break;
1068 case SIDE_TYPE_BYTE:
1069 if (type_visitor->byte_type_func)
1070 type_visitor->byte_type_func(type_desc, item, priv);
1071 break;
1072 case SIDE_TYPE_POINTER:
1073 if (type_visitor->pointer_type_func)
1074 type_visitor->pointer_type_func(type_desc, item, priv);
1075 break;
1076 case SIDE_TYPE_FLOAT_BINARY16: /* Fallthrough */
1077 case SIDE_TYPE_FLOAT_BINARY32: /* Fallthrough */
1078 case SIDE_TYPE_FLOAT_BINARY64: /* Fallthrough */
1079 case SIDE_TYPE_FLOAT_BINARY128:
1080 if (type_visitor->float_type_func)
1081 type_visitor->float_type_func(type_desc, item, priv);
1082 break;
1083 case SIDE_TYPE_STRING_UTF8: /* Fallthrough */
1084 case SIDE_TYPE_STRING_UTF16: /* Fallthrough */
1085 case SIDE_TYPE_STRING_UTF32:
1086 if (type_visitor->string_type_func)
1087 type_visitor->string_type_func(type_desc, item, priv);
1088 break;
1089 case SIDE_TYPE_ENUM:
1090 if (type_visitor->enum_type_func)
1091 type_visitor->enum_type_func(type_desc, item, priv);
1092 break;
1093 case SIDE_TYPE_ENUM_BITMAP:
1094 if (type_visitor->enum_bitmap_type_func)
1095 type_visitor->enum_bitmap_type_func(type_desc, item, priv);
1096 break;
1097
1098 /* Stack-copy compound types */
1099 case SIDE_TYPE_STRUCT:
1100 type_visitor_struct(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_struct), priv);
1101 break;
1102 case SIDE_TYPE_VARIANT:
1103 type_visitor_variant(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_variant), priv);
1104 break;
1105 case SIDE_TYPE_ARRAY:
1106 type_visitor_array(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_array), priv);
1107 break;
1108 case SIDE_TYPE_VLA:
1109 type_visitor_vla(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_vla), priv);
1110 break;
1111 case SIDE_TYPE_VLA_VISITOR:
1112 type_visitor_vla_visitor(type_visitor, type_desc, side_ptr_get(item->u.side_static.side_vla_visitor), priv);
1113 break;
1114
1115 /* Gather basic types */
1116 case SIDE_TYPE_GATHER_BOOL:
1117 (void) type_visitor_gather_bool(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_bool_gather_ptr), priv);
1118 break;
1119 case SIDE_TYPE_GATHER_INTEGER:
1120 (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);
1121 break;
1122 case SIDE_TYPE_GATHER_BYTE:
1123 (void) type_visitor_gather_byte(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_byte_gather_ptr), priv);
1124 break;
1125 case SIDE_TYPE_GATHER_POINTER:
1126 (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);
1127 break;
1128 case SIDE_TYPE_GATHER_FLOAT:
1129 (void) type_visitor_gather_float(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_float_gather_ptr), priv);
1130 break;
1131 case SIDE_TYPE_GATHER_STRING:
1132 (void) type_visitor_gather_string(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_string_gather_ptr), priv);
1133 break;
1134
1135 /* Gather compound type */
1136 case SIDE_TYPE_GATHER_STRUCT:
1137 (void) type_visitor_gather_struct(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_struct_gather_ptr), priv);
1138 break;
1139 case SIDE_TYPE_GATHER_ARRAY:
1140 (void) type_visitor_gather_array(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_array_gather_ptr), priv);
1141 break;
1142 case SIDE_TYPE_GATHER_VLA:
1143 (void) type_visitor_gather_vla(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_array_gather_ptr),
1144 side_ptr_get(item->u.side_static.side_vla_gather.length_ptr), priv);
1145 break;
1146
1147 /* Gather enumeration types */
1148 case SIDE_TYPE_GATHER_ENUM:
1149 (void) type_visitor_gather_enum(type_visitor, &type_desc->u.side_gather, side_ptr_get(item->u.side_static.side_integer_gather_ptr), priv);
1150 break;
1151
1152 /* Dynamic basic types */
1153 case SIDE_TYPE_DYNAMIC_NULL: /* Fallthrough */
1154 case SIDE_TYPE_DYNAMIC_BOOL: /* Fallthrough */
1155 case SIDE_TYPE_DYNAMIC_INTEGER: /* Fallthrough */
1156 case SIDE_TYPE_DYNAMIC_BYTE: /* Fallthrough */
1157 case SIDE_TYPE_DYNAMIC_POINTER: /* Fallthrough */
1158 case SIDE_TYPE_DYNAMIC_FLOAT: /* Fallthrough */
1159 case SIDE_TYPE_DYNAMIC_STRING: /* Fallthrough */
1160
1161 /* Dynamic compound types */
1162 case SIDE_TYPE_DYNAMIC_STRUCT: /* Fallthrough */
1163 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR: /* Fallthrough */
1164 case SIDE_TYPE_DYNAMIC_VLA: /* Fallthrough */
1165 case SIDE_TYPE_DYNAMIC_VLA_VISITOR:
1166 visit_dynamic_type(type_visitor, item, priv);
1167 break;
1168
1169 default:
1170 fprintf(stderr, "<UNKNOWN TYPE>\n");
1171 abort();
1172 }
1173}
1174
1175void type_visitor_event(const struct side_type_visitor *type_visitor,
1176 const struct side_event_description *desc,
1177 const struct side_arg_vec *side_arg_vec,
1178 const struct side_arg_dynamic_struct *var_struct,
1179 void *caller_addr, void *priv)
1180{
1181 const struct side_arg *sav = side_ptr_get(side_arg_vec->sav);
1182 uint32_t i, side_sav_len = side_arg_vec->len;
1183
1184 if (desc->nr_fields != side_sav_len) {
1185 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1186 abort();
1187 }
1188 if (type_visitor->event_func)
1189 type_visitor->event_func(SIDE_TYPE_VISITOR_BEFORE, desc, side_arg_vec, var_struct, caller_addr, priv);
1190 if (side_sav_len) {
1191 if (type_visitor->static_fields_func)
1192 type_visitor->static_fields_func(SIDE_TYPE_VISITOR_BEFORE, side_arg_vec, priv);
1193 for (i = 0; i < side_sav_len; i++)
1194 side_visit_field(type_visitor, &side_ptr_get(desc->fields)[i], &sav[i], priv);
1195 if (type_visitor->static_fields_func)
1196 type_visitor->static_fields_func(SIDE_TYPE_VISITOR_AFTER, side_arg_vec, priv);
1197 }
1198 if (var_struct) {
1199 uint32_t var_struct_len = var_struct->len;
1200
1201 if (type_visitor->variadic_fields_func)
1202 type_visitor->variadic_fields_func(SIDE_TYPE_VISITOR_BEFORE, var_struct, priv);
1203 for (i = 0; i < var_struct_len; i++)
1204 visit_dynamic_field(type_visitor, &side_ptr_get(var_struct->fields)[i], priv);
1205 if (type_visitor->variadic_fields_func)
1206 type_visitor->variadic_fields_func(SIDE_TYPE_VISITOR_AFTER, var_struct, priv);
1207 }
1208 if (type_visitor->event_func)
1209 type_visitor->event_func(SIDE_TYPE_VISITOR_AFTER, desc, side_arg_vec, var_struct, caller_addr, priv);
1210}
This page took 0.191468 seconds and 4 git commands to generate.