1 // SPDX-License-Identifier: MIT
3 * Copyright 2022-2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 #include "visit-arg-vec.h"
11 uint64_t u
[NR_SIDE_INTEGER128_SPLIT
];
12 int64_t s
[NR_SIDE_INTEGER128_SPLIT
];
16 void visit_dynamic_type(const struct side_type_visitor
*type_visitor
, const struct side_arg
*dynamic_item
, void *priv
);
19 void visit_dynamic_elem(const struct side_type_visitor
*type_visitor
, const struct side_arg
*dynamic_item
, void *priv
);
22 uint32_t visit_gather_type(const struct side_type_visitor
*type_visitor
, const struct side_type
*type_desc
, const void *ptr
, void *priv
);
25 uint32_t visit_gather_elem(const struct side_type_visitor
*type_visitor
, const struct side_type
*type_desc
, const void *ptr
, void *priv
);
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
);
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
);
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
);
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
);
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
);
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
);
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
)
51 union int_value v
= {};
55 if (!type_integer
->len_bits
)
56 len_bits
= type_integer
->integer_size
* CHAR_BIT
;
58 len_bits
= type_integer
->len_bits
;
59 if (len_bits
+ offset_bits
> type_integer
->integer_size
* CHAR_BIT
)
61 reverse_bo
= side_enum_get(type_integer
->byte_order
) != SIDE_TYPE_BYTE_ORDER_HOST
;
62 switch (type_integer
->integer_size
) {
64 if (type_integer
->signedness
)
65 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = value
->side_s8
;
67 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = value
->side_u8
;
70 if (type_integer
->signedness
) {
73 side_s16
= value
->side_s16
;
75 side_s16
= side_bswap_16(side_s16
);
76 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s16
;
80 side_u16
= value
->side_u16
;
82 side_u16
= side_bswap_16(side_u16
);
83 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u16
;
87 if (type_integer
->signedness
) {
90 side_s32
= value
->side_s32
;
92 side_s32
= side_bswap_32(side_s32
);
93 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s32
;
97 side_u32
= value
->side_u32
;
99 side_u32
= side_bswap_32(side_u32
);
100 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u32
;
104 if (type_integer
->signedness
) {
107 side_s64
= value
->side_s64
;
109 side_s64
= side_bswap_64(side_s64
);
110 v
.s
[SIDE_INTEGER128_SPLIT_LOW
] = side_s64
;
114 side_u64
= value
->side_u64
;
116 side_u64
= side_bswap_64(side_u64
);
117 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] = side_u64
;
121 if (type_integer
->signedness
) {
122 int64_t side_s64
[NR_SIDE_INTEGER128_SPLIT
];
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
];
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
];
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
];
136 uint64_t side_u64
[NR_SIDE_INTEGER128_SPLIT
];
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
];
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
];
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
];
154 if (type_integer
->integer_size
<= 8) {
155 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] >>= offset_bits
;
157 v
.u
[SIDE_INTEGER128_SPLIT_LOW
] &= (1ULL << len_bits
) - 1;
158 if (type_integer
->signedness
) {
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;
167 //TODO: Implement 128-bit integer with len_bits != 128 or nonzero offset_bits
168 if (len_bits
< 128 || offset_bits
!= 0)
172 *_len_bits
= len_bits
;
177 void side_check_value_u64(union int_value v
)
179 if (v
.u
[SIDE_INTEGER128_SPLIT_HIGH
]) {
180 fprintf(stderr
, "Unexpected integer value\n");
186 * return the size of the input string including the null terminator, in
190 size_t type_visitor_strlen(const void *p
, uint8_t unit_size
)
192 size_t inbytesleft
= 0;
199 return strlen(str
) + 1;
203 const uint16_t *p16
= p
;
207 return inbytesleft
+ 2; /* Include 2-byte null terminator. */
211 const uint32_t *p32
= p
;
215 return inbytesleft
+ 4; /* Include 4-byte null terminator. */
218 fprintf(stderr
, "Unknown string unit size %" PRIu8
"\n", unit_size
);
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
)
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
);
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
)
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
);
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
)
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
;
250 if (side_struct
->nr_fields
!= side_sav_len
) {
251 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
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
);
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
)
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
;
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");
274 switch (side_enum_get(selector_type
->type
)) {
287 fprintf(stderr
, "ERROR: Expecting integer variant selector type\n");
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
];
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
);
301 fprintf(stderr
, "ERROR: Variant selector value unknown %" PRId64
"\n", v
.s
[SIDE_INTEGER128_SPLIT_LOW
]);
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
)
308 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
309 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
311 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
312 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
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
);
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
)
326 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
327 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
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
);
337 struct tracer_visitor_priv
{
338 const struct side_type_visitor
*type_visitor
;
340 const struct side_type
*elem_type
;
345 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
346 const struct side_arg
*elem
)
348 struct tracer_visitor_priv
*tracer_priv
= (struct tracer_visitor_priv
*) tracer_ctx
->priv
;
350 side_visit_elem(tracer_priv
->type_visitor
, tracer_priv
->elem_type
, elem
, tracer_priv
->priv
);
351 return SIDE_VISITOR_STATUS_OK
;
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
)
357 struct tracer_visitor_priv tracer_priv
= {
358 .type_visitor
= type_visitor
,
360 .elem_type
= side_ptr_get(side_ptr_get(type_desc
->u
.side_vla_visitor
)->elem_type
),
363 const struct side_tracer_visitor_ctx tracer_ctx
= {
364 .write_elem
= tracer_write_elem_cb
,
365 .priv
= &tracer_priv
,
367 enum side_visitor_status status
;
368 side_visitor_func func
;
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
);
379 case SIDE_VISITOR_STATUS_OK
:
381 case SIDE_VISITOR_STATUS_ERROR
:
382 fprintf(stderr
, "ERROR: Visitor error\n");
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
);
390 const char *tracer_gather_access(enum side_type_gather_access_mode access_mode
, const char *ptr
)
392 switch (access_mode
) {
393 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
395 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
396 /* Dereference pointer */
397 memcpy(&ptr
, ptr
, sizeof(const char *));
405 uint32_t tracer_gather_size(enum side_type_gather_access_mode access_mode
, uint32_t len
)
407 switch (access_mode
) {
408 case SIDE_TYPE_GATHER_ACCESS_DIRECT
:
410 case SIDE_TYPE_GATHER_ACCESS_POINTER
:
411 return sizeof(void *);
418 union int_value
tracer_load_gather_integer_value(const struct side_type_gather_integer
*side_integer
,
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
;
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
);
433 void visit_gather_field(const struct side_type_visitor
*type_visitor
, const struct side_event_field
*field
, const void *ptr
, void *priv
)
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
);
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
)
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
;
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
);
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
)
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
;
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
);
472 for (i
= 0; i
< side_array
->length
; i
++) {
473 const struct side_type
*elem_type
= side_ptr_get(side_array
->elem_type
);
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");
482 ptr
+= visit_gather_elem(type_visitor
, elem_type
, ptr
, priv
);
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
);
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
)
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
= {};
501 switch (side_enum_get(length_type
->type
)) {
502 case SIDE_TYPE_GATHER_INTEGER
:
505 fprintf(stderr
, "<gather VLA expects integer gather length type>\n");
508 v
= tracer_load_gather_integer_value(&length_type
->u
.side_gather
.u
.side_integer
,
510 if (v
.u
[SIDE_INTEGER128_SPLIT_HIGH
] || v
.u
[SIDE_INTEGER128_SPLIT_LOW
] > UINT32_MAX
) {
511 fprintf(stderr
, "Unexpected vla length value\n");
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
);
519 for (i
= 0; i
< length
; i
++) {
520 const struct side_type
*elem_type
= side_ptr_get(side_vla
->elem_type
);
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");
529 ptr
+= visit_gather_elem(type_visitor
, elem_type
, ptr
, priv
);
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
);
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
)
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
;
544 switch (bool_size_bytes
) {
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
);
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
)
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
;
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);
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
)
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
;
583 switch (integer_size_bytes
) {
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
);
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
);
605 fprintf(stderr
, "Unexpected integer type\n");
608 return tracer_gather_size(access_mode
, integer_size_bytes
);
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
)
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
;
619 switch (float_size_bytes
) {
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
);
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
)
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;
645 ptr
= tracer_gather_access(access_mode
, ptr
+ type_gather
->u
.side_string
.offset
);
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
);
655 uint32_t visit_gather_type(const struct side_type_visitor
*type_visitor
, const struct side_type
*type_desc
, const void *ptr
, void *priv
)
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
);
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
);
667 case SIDE_TYPE_GATHER_BYTE
:
668 len
= type_visitor_gather_byte(type_visitor
, &type_desc
->u
.side_gather
, ptr
, priv
);
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
);
673 case SIDE_TYPE_GATHER_FLOAT
:
674 len
= type_visitor_gather_float(type_visitor
, &type_desc
->u
.side_gather
, ptr
, priv
);
676 case SIDE_TYPE_GATHER_STRING
:
677 len
= type_visitor_gather_string(type_visitor
, &type_desc
->u
.side_gather
, ptr
, priv
);
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
);
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
);
689 case SIDE_TYPE_GATHER_ARRAY
:
690 len
= type_visitor_gather_array(type_visitor
, &type_desc
->u
.side_gather
, ptr
, priv
);
692 case SIDE_TYPE_GATHER_VLA
:
693 len
= type_visitor_gather_vla(type_visitor
, &type_desc
->u
.side_gather
, ptr
, ptr
, priv
);
696 fprintf(stderr
, "<UNKNOWN GATHER TYPE>");
703 uint32_t visit_gather_elem(const struct side_type_visitor
*type_visitor
, const struct side_type
*type_desc
, const void *ptr
, void *priv
)
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
);
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
)
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
;
725 switch (integer_size_bytes
) {
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
);
743 void visit_dynamic_field(const struct side_type_visitor
*type_visitor
, const struct side_arg_dynamic_field
*field
, void *priv
)
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
);
753 void type_visitor_dynamic_struct(const struct side_type_visitor
*type_visitor
, const struct side_arg_dynamic_struct
*dynamic_struct
, void *priv
)
755 const struct side_arg_dynamic_field
*fields
= side_ptr_get(dynamic_struct
->fields
);
756 uint32_t i
, len
= dynamic_struct
->len
;
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
);
766 struct tracer_dynamic_struct_visitor_priv
{
767 const struct side_type_visitor
*type_visitor
;
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
)
777 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
=
778 (struct tracer_dynamic_struct_visitor_priv
*) tracer_ctx
->priv
;
780 visit_dynamic_field(tracer_priv
->type_visitor
, dynamic_field
, tracer_priv
->priv
);
781 return SIDE_VISITOR_STATUS_OK
;
785 void type_visitor_dynamic_struct_visitor(const struct side_type_visitor
*type_visitor
, const struct side_arg
*item
, void *priv
)
787 struct side_arg_dynamic_struct_visitor
*dynamic_struct_visitor
;
788 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
789 .type_visitor
= type_visitor
,
793 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
794 .write_field
= tracer_dynamic_struct_write_elem_cb
,
795 .priv
= &tracer_priv
,
797 enum side_visitor_status status
;
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
)
805 app_ctx
= side_ptr_get(dynamic_struct_visitor
->app_ctx
);
806 status
= side_ptr_get(dynamic_struct_visitor
->visitor
)(&tracer_ctx
, app_ctx
);
808 case SIDE_VISITOR_STATUS_OK
:
810 case SIDE_VISITOR_STATUS_ERROR
:
811 fprintf(stderr
, "ERROR: Visitor error\n");
814 if (type_visitor
->dynamic_struct_visitor_func
)
815 type_visitor
->dynamic_struct_visitor_func(SIDE_TYPE_VISITOR_AFTER
, item
, priv
);
819 void type_visitor_dynamic_vla(const struct side_type_visitor
*type_visitor
, const struct side_arg_dynamic_vla
*vla
, void *priv
)
821 const struct side_arg
*sav
= side_ptr_get(vla
->sav
);
822 uint32_t i
, side_sav_len
= vla
->len
;
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
);
832 struct tracer_dynamic_vla_visitor_priv
{
833 const struct side_type_visitor
*type_visitor
;
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
)
843 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
=
844 (struct tracer_dynamic_vla_visitor_priv
*) tracer_ctx
->priv
;
846 visit_dynamic_elem(tracer_priv
->type_visitor
, elem
, tracer_priv
->priv
);
847 return SIDE_VISITOR_STATUS_OK
;
851 void type_visitor_dynamic_vla_visitor(const struct side_type_visitor
*type_visitor
, const struct side_arg
*item
, void *priv
)
853 struct side_arg_dynamic_vla_visitor
*dynamic_vla_visitor
;
854 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
855 .type_visitor
= type_visitor
,
859 const struct side_tracer_visitor_ctx tracer_ctx
= {
860 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
861 .priv
= &tracer_priv
,
863 enum side_visitor_status status
;
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
)
871 app_ctx
= side_ptr_get(dynamic_vla_visitor
->app_ctx
);
872 status
= side_ptr_get(dynamic_vla_visitor
->visitor
)(&tracer_ctx
, app_ctx
);
874 case SIDE_VISITOR_STATUS_OK
:
876 case SIDE_VISITOR_STATUS_ERROR
:
877 fprintf(stderr
, "ERROR: Visitor error\n");
880 if (type_visitor
->dynamic_vla_visitor_func
)
881 type_visitor
->dynamic_vla_visitor_func(SIDE_TYPE_VISITOR_AFTER
, item
, priv
);
885 void visit_dynamic_type(const struct side_type_visitor
*type_visitor
, const struct side_arg
*dynamic_item
, void *priv
)
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
);
893 case SIDE_TYPE_DYNAMIC_BOOL
:
894 if (type_visitor
->dynamic_bool_func
)
895 type_visitor
->dynamic_bool_func(dynamic_item
, priv
);
897 case SIDE_TYPE_DYNAMIC_INTEGER
:
898 if (type_visitor
->dynamic_integer_func
)
899 type_visitor
->dynamic_integer_func(dynamic_item
, priv
);
901 case SIDE_TYPE_DYNAMIC_BYTE
:
902 if (type_visitor
->dynamic_byte_func
)
903 type_visitor
->dynamic_byte_func(dynamic_item
, priv
);
905 case SIDE_TYPE_DYNAMIC_POINTER
:
906 if (type_visitor
->dynamic_pointer_func
)
907 type_visitor
->dynamic_pointer_func(dynamic_item
, priv
);
909 case SIDE_TYPE_DYNAMIC_FLOAT
:
910 if (type_visitor
->dynamic_float_func
)
911 type_visitor
->dynamic_float_func(dynamic_item
, priv
);
913 case SIDE_TYPE_DYNAMIC_STRING
:
914 if (type_visitor
->dynamic_string_func
)
915 type_visitor
->dynamic_string_func(dynamic_item
, priv
);
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
);
922 case SIDE_TYPE_DYNAMIC_STRUCT_VISITOR
:
923 type_visitor_dynamic_struct_visitor(type_visitor
, dynamic_item
, priv
);
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
);
928 case SIDE_TYPE_DYNAMIC_VLA_VISITOR
:
929 type_visitor_dynamic_vla_visitor(type_visitor
, dynamic_item
, priv
);
932 fprintf(stderr
, "<UNKNOWN TYPE>\n");
938 void visit_dynamic_elem(const struct side_type_visitor
*type_visitor
, const struct side_arg
*dynamic_item
, void *priv
)
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
);
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
)
949 enum side_type_label type
;
951 switch (side_enum_get(type_desc
->type
)) {
953 switch (side_enum_get(item
->type
)) {
966 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
972 case SIDE_TYPE_ENUM_BITMAP
:
973 switch (side_enum_get(item
->type
)) {
980 case SIDE_TYPE_ARRAY
:
984 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
990 case SIDE_TYPE_GATHER_ENUM
:
991 switch (side_enum_get(item
->type
)) {
992 case SIDE_TYPE_GATHER_INTEGER
:
995 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
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
:
1016 fprintf(stderr
, "ERROR: Unexpected dynamic type\n");
1023 if (side_enum_get(type_desc
->type
) != side_enum_get(item
->type
)) {
1024 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
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
);
1033 type
= side_enum_get(item
->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
);
1041 case SIDE_TYPE_BOOL
:
1042 if (type_visitor
->bool_type_func
)
1043 type_visitor
->bool_type_func(type_desc
, item
, priv
);
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
);
1058 case SIDE_TYPE_BYTE
:
1059 if (type_visitor
->byte_type_func
)
1060 type_visitor
->byte_type_func(type_desc
, item
, priv
);
1062 case SIDE_TYPE_POINTER
:
1063 if (type_visitor
->pointer_type_func
)
1064 type_visitor
->pointer_type_func(type_desc
, item
, priv
);
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
);
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
);
1079 case SIDE_TYPE_ENUM
:
1080 if (type_visitor
->enum_type_func
)
1081 type_visitor
->enum_type_func(type_desc
, item
, priv
);
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
);
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
);
1092 case SIDE_TYPE_VARIANT
:
1093 type_visitor_variant(type_visitor
, type_desc
, side_ptr_get(item
->u
.side_static
.side_variant
), priv
);
1095 case SIDE_TYPE_ARRAY
:
1096 type_visitor_array(type_visitor
, type_desc
, side_ptr_get(item
->u
.side_static
.side_array
), priv
);
1099 type_visitor_vla(type_visitor
, type_desc
, side_ptr_get(item
->u
.side_static
.side_vla
), priv
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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 */
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
);
1160 fprintf(stderr
, "<UNKNOWN TYPE>\n");
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
)
1171 const struct side_arg
*sav
= side_ptr_get(side_arg_vec
->sav
);
1172 uint32_t i
, side_sav_len
= side_arg_vec
->len
;
1174 if (desc
->nr_fields
!= side_sav_len
) {
1175 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1178 if (type_visitor
->event_func
)
1179 type_visitor
->event_func(SIDE_TYPE_VISITOR_BEFORE
, desc
, side_arg_vec
, var_struct
, caller_addr
, priv
);
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
);
1189 uint32_t var_struct_len
= var_struct
->len
;
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
);
1198 if (type_visitor
->event_func
)
1199 type_visitor
->event_func(SIDE_TYPE_VISITOR_AFTER
, desc
, side_arg_vec
, var_struct
, caller_addr
, priv
);