1 // SPDX-License-Identifier: MIT
3 * Copyright 2022-2023 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 #ifndef SIDE_ABI_TYPE_ARGUMENT_H
7 #define SIDE_ABI_TYPE_ARGUMENT_H
10 #include <side/macros.h>
11 #include <side/endian.h>
13 #include <side/abi/type-value.h>
14 #include <side/abi/attribute.h>
15 #include <side/abi/type-description.h>
16 #include <side/abi/visitor.h>
19 * SIDE ABI for arguments passed to instrumentation call site.
21 * The extensibility scheme for the SIDE ABI for call site arguments is
24 * * Existing argument types are never changed nor extended. Argument
25 * types can be added to the ABI by reserving a label within
26 * enum side_type_label.
27 * * Each union part of the ABI has an explicit size defined by a
28 * side_padding() member. Each structure and union have a static
29 * assert validating its size.
30 * * Changing the semantic of the existing argument type fields is a
31 * breaking ABI change.
33 * Handling of unknown argument types by the tracers:
35 * * A tracer may choose to support only a subset of the types supported
36 * by libside. When encountering an unknown or unsupported type, the
37 * tracer has the option to either disallow the entire event or skip
38 * over the unknown type, both at event registration and when
39 * receiving the side_call arguments.
42 #if (SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN)
43 # define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE
45 # define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_BE
48 #if (SIDE_FLOAT_WORD_ORDER == SIDE_LITTLE_ENDIAN)
49 # define SIDE_TYPE_FLOAT_WORD_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE
51 # define SIDE_TYPE_FLOAT_WORD_ORDER_HOST SIDE_TYPE_BYTE_ORDER_BE
54 enum side_arg_flag_bit
{
55 SIDE_ARG_FLAG_INCOMPLETE_BIT
= 0,
57 _NR_SIDE_ARG_FLAG_BIT
,
61 SIDE_ARG_FLAG_INCOMPLETE
= (1U << SIDE_ARG_FLAG_INCOMPLETE_BIT
),
64 struct side_arg_vla_visitor
{
65 side_ptr_t(void) app_ctx
;
66 /* libside argument cache, initialize to NULL. */
67 side_ptr_t(struct side_arg
) cached_arg
;
69 side_check_size(struct side_arg_vla_visitor
, 32);
71 union side_arg_static
{
72 /* Stack-copy basic types */
73 union side_bool_value bool_value
;
75 side_ptr_t(const void) string_value
; /* const {uint8_t, uint16_t, uint32_t} * */
76 union side_integer_value integer_value
;
77 union side_float_value float_value
;
79 /* Stack-copy compound types */
80 side_ptr_t(const struct side_arg_vec
) side_struct
;
81 side_ptr_t(const struct side_arg_variant
) side_variant
;
82 side_ptr_t(const struct side_arg_vec
) side_array
;
83 side_ptr_t(const struct side_arg_vec
) side_vla
;
84 /* Pointer to non-const structure. Content modified by libside. */
85 side_ptr_t(struct side_arg_vla_visitor
) side_vla_visitor
;
87 /* Gather basic types */
88 side_ptr_t(const void) side_bool_gather_ptr
;
89 side_ptr_t(const void) side_byte_gather_ptr
;
90 side_ptr_t(const void) side_integer_gather_ptr
;
91 side_ptr_t(const void) side_float_gather_ptr
;
92 side_ptr_t(const void) side_string_gather_ptr
;
94 /* Gather compound types */
95 side_ptr_t(const void) side_array_gather_ptr
;
96 side_ptr_t(const void) side_struct_gather_ptr
;
98 side_ptr_t(const void) ptr
;
99 side_ptr_t(const void) length_ptr
;
100 } SIDE_PACKED side_vla_gather
;
103 side_check_size(union side_arg_static
, 32);
105 struct side_arg_dynamic_vla
{
106 side_ptr_t(const struct side_arg
) sav
;
107 side_ptr_t(const struct side_attr
) attr
;
111 side_check_size(struct side_arg_dynamic_vla
, 40);
113 struct side_arg_dynamic_struct
{
114 side_ptr_t(const struct side_arg_dynamic_field
) fields
;
115 side_ptr_t(const struct side_attr
) attr
;
119 side_check_size(struct side_arg_dynamic_struct
, 40);
121 struct side_arg_dynamic_struct_visitor
{
122 side_func_ptr_t(side_dynamic_struct_visitor_func
) visitor
;
123 side_ptr_t(void) app_ctx
;
124 side_ptr_t(const struct side_attr
) attr
;
125 /* libside argument cache, initialize to NULL. */
126 side_ptr_t(struct side_arg
) cached_arg
;
129 side_check_size(struct side_arg_dynamic_struct_visitor
, 68);
131 struct side_arg_dynamic_vla_visitor
{
132 side_func_ptr_t(side_visitor_func
) visitor
;
133 side_ptr_t(void) app_ctx
;
134 side_ptr_t(const struct side_attr
) attr
;
135 /* libside argument cache, initialize to NULL. */
136 side_ptr_t(struct side_arg
) cached_arg
;
139 side_check_size(struct side_arg_dynamic_vla_visitor
, 68);
141 union side_arg_dynamic
{
142 /* Dynamic basic types */
143 struct side_type_null side_null
;
145 struct side_type_bool type
;
146 union side_bool_value value
;
147 } SIDE_PACKED side_bool
;
149 struct side_type_byte type
;
151 } SIDE_PACKED side_byte
;
153 struct side_type_string type
;
154 uint64_t value
; /* const char * */
155 } SIDE_PACKED side_string
;
157 struct side_type_integer type
;
158 union side_integer_value value
;
159 } SIDE_PACKED side_integer
;
161 struct side_type_float type
;
162 union side_float_value value
;
163 } SIDE_PACKED side_float
;
165 /* Dynamic compound types */
166 side_ptr_t(const struct side_arg_dynamic_struct
) side_dynamic_struct
;
167 side_ptr_t(const struct side_arg_dynamic_vla
) side_dynamic_vla
;
169 /* Pointer to non-const structure. Content modified by libside. */
170 side_ptr_t(struct side_arg_dynamic_struct_visitor
) side_dynamic_struct_visitor
;
171 /* Pointer to non-const structure. Content modified by libside. */
172 side_ptr_t(struct side_arg_dynamic_vla_visitor
) side_dynamic_vla_visitor
;
176 side_check_size(union side_arg_dynamic
, 58);
179 side_enum_t(enum side_type_label
, uint16_t) type
;
182 union side_arg_static side_static
;
183 union side_arg_dynamic side_dynamic
;
187 side_check_size(struct side_arg
, 64);
189 struct side_arg_variant
{
190 struct side_arg selector
;
191 struct side_arg option
;
193 side_check_size(struct side_arg_variant
, 128);
195 struct side_arg_vec
{
196 side_ptr_t(const struct side_arg
) sav
;
199 side_check_size(struct side_arg_vec
, 20);
201 struct side_arg_dynamic_field
{
202 side_ptr_t(const char) field_name
;
203 const struct side_arg elem
;
205 side_check_size(struct side_arg_dynamic_field
, 16 + sizeof(const struct side_arg
));
207 #endif /* SIDE_ABI_TYPE_ARGUMENT_H */