Commit | Line | Data |
---|---|---|
57553dfd MD |
1 | // SPDX-License-Identifier: MIT |
2 | /* | |
3 | * Copyright 2022-2023 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
4 | */ | |
5 | ||
b8dfb348 MD |
6 | #ifndef SIDE_ABI_TYPE_ARGUMENT_H |
7 | #define SIDE_ABI_TYPE_ARGUMENT_H | |
57553dfd MD |
8 | |
9 | #include <stdint.h> | |
10 | #include <side/macros.h> | |
11 | #include <side/endian.h> | |
12 | ||
b8dfb348 MD |
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> | |
57553dfd | 17 | |
35e4f870 MD |
18 | /* |
19 | * SIDE ABI for arguments passed to instrumentation call site. | |
20 | * | |
21 | * The extensibility scheme for the SIDE ABI for call site arguments is | |
22 | * as follows: | |
23 | * | |
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. | |
32 | * | |
33 | * Handling of unknown argument types by the tracers: | |
34 | * | |
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. | |
40 | */ | |
41 | ||
57553dfd MD |
42 | #if (SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN) |
43 | # define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE | |
44 | #else | |
45 | # define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_BE | |
46 | #endif | |
47 | ||
48 | #if (SIDE_FLOAT_WORD_ORDER == SIDE_LITTLE_ENDIAN) | |
49 | # define SIDE_TYPE_FLOAT_WORD_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE | |
50 | #else | |
51 | # define SIDE_TYPE_FLOAT_WORD_ORDER_HOST SIDE_TYPE_BYTE_ORDER_BE | |
52 | #endif | |
53 | ||
e28b5a3c MD |
54 | enum side_arg_flag_bit { |
55 | SIDE_ARG_FLAG_INCOMPLETE_BIT = 0, | |
56 | ||
57 | _NR_SIDE_ARG_FLAG_BIT, | |
58 | }; | |
59 | ||
60 | enum side_arg_flag { | |
61 | SIDE_ARG_FLAG_INCOMPLETE = (1U << SIDE_ARG_FLAG_INCOMPLETE_BIT), | |
62 | }; | |
63 | ||
c6af61dc MD |
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; | |
68 | } SIDE_PACKED; | |
69 | side_check_size(struct side_arg_vla_visitor, 32); | |
70 | ||
57553dfd MD |
71 | union side_arg_static { |
72 | /* Stack-copy basic types */ | |
73 | union side_bool_value bool_value; | |
74 | uint8_t byte_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; | |
78 | ||
79 | /* Stack-copy compound types */ | |
80 | side_ptr_t(const struct side_arg_vec) side_struct; | |
e14987e0 | 81 | side_ptr_t(const struct side_arg_variant) side_variant; |
57553dfd MD |
82 | side_ptr_t(const struct side_arg_vec) side_array; |
83 | side_ptr_t(const struct side_arg_vec) side_vla; | |
c6af61dc MD |
84 | /* Pointer to non-const structure. Content modified by libside. */ |
85 | side_ptr_t(struct side_arg_vla_visitor) side_vla_visitor; | |
57553dfd MD |
86 | |
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; | |
93 | ||
94 | /* Gather compound types */ | |
95 | side_ptr_t(const void) side_array_gather_ptr; | |
96 | side_ptr_t(const void) side_struct_gather_ptr; | |
97 | struct { | |
98 | side_ptr_t(const void) ptr; | |
99 | side_ptr_t(const void) length_ptr; | |
100 | } SIDE_PACKED side_vla_gather; | |
101 | side_padding(32); | |
102 | } SIDE_PACKED; | |
103 | side_check_size(union side_arg_static, 32); | |
104 | ||
105 | struct side_arg_dynamic_vla { | |
e14987e0 | 106 | side_ptr_t(const struct side_arg) sav; |
57553dfd MD |
107 | side_ptr_t(const struct side_attr) attr; |
108 | uint32_t len; | |
109 | uint32_t nr_attr; | |
110 | } SIDE_PACKED; | |
111 | side_check_size(struct side_arg_dynamic_vla, 40); | |
112 | ||
113 | struct side_arg_dynamic_struct { | |
e14987e0 | 114 | side_ptr_t(const struct side_arg_dynamic_field) fields; |
57553dfd MD |
115 | side_ptr_t(const struct side_attr) attr; |
116 | uint32_t len; | |
117 | uint32_t nr_attr; | |
118 | } SIDE_PACKED; | |
119 | side_check_size(struct side_arg_dynamic_struct, 40); | |
120 | ||
c6af61dc | 121 | struct side_arg_dynamic_struct_visitor { |
57553dfd MD |
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; | |
c6af61dc MD |
125 | /* libside argument cache, initialize to NULL. */ |
126 | side_ptr_t(struct side_arg) cached_arg; | |
57553dfd MD |
127 | uint32_t nr_attr; |
128 | } SIDE_PACKED; | |
c6af61dc | 129 | side_check_size(struct side_arg_dynamic_struct_visitor, 68); |
57553dfd | 130 | |
c6af61dc | 131 | struct side_arg_dynamic_vla_visitor { |
57553dfd MD |
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; | |
c6af61dc MD |
135 | /* libside argument cache, initialize to NULL. */ |
136 | side_ptr_t(struct side_arg) cached_arg; | |
57553dfd MD |
137 | uint32_t nr_attr; |
138 | } SIDE_PACKED; | |
c6af61dc | 139 | side_check_size(struct side_arg_dynamic_vla_visitor, 68); |
57553dfd MD |
140 | |
141 | union side_arg_dynamic { | |
142 | /* Dynamic basic types */ | |
143 | struct side_type_null side_null; | |
144 | struct { | |
145 | struct side_type_bool type; | |
146 | union side_bool_value value; | |
147 | } SIDE_PACKED side_bool; | |
148 | struct { | |
149 | struct side_type_byte type; | |
150 | uint8_t value; | |
151 | } SIDE_PACKED side_byte; | |
152 | struct { | |
153 | struct side_type_string type; | |
154 | uint64_t value; /* const char * */ | |
155 | } SIDE_PACKED side_string; | |
156 | struct { | |
157 | struct side_type_integer type; | |
158 | union side_integer_value value; | |
159 | } SIDE_PACKED side_integer; | |
160 | struct { | |
161 | struct side_type_float type; | |
162 | union side_float_value value; | |
163 | } SIDE_PACKED side_float; | |
164 | ||
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; | |
168 | ||
c6af61dc MD |
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; | |
57553dfd MD |
173 | |
174 | side_padding(58); | |
175 | } SIDE_PACKED; | |
176 | side_check_size(union side_arg_dynamic, 58); | |
177 | ||
178 | struct side_arg { | |
179 | side_enum_t(enum side_type_label, uint16_t) type; | |
e28b5a3c | 180 | uint16_t flags; |
57553dfd MD |
181 | union { |
182 | union side_arg_static side_static; | |
183 | union side_arg_dynamic side_dynamic; | |
e28b5a3c | 184 | side_padding(60); |
57553dfd MD |
185 | } SIDE_PACKED u; |
186 | } SIDE_PACKED; | |
187 | side_check_size(struct side_arg, 64); | |
188 | ||
189 | struct side_arg_variant { | |
190 | struct side_arg selector; | |
191 | struct side_arg option; | |
192 | } SIDE_PACKED; | |
193 | side_check_size(struct side_arg_variant, 128); | |
194 | ||
195 | struct side_arg_vec { | |
e14987e0 | 196 | side_ptr_t(const struct side_arg) sav; |
57553dfd MD |
197 | uint32_t len; |
198 | } SIDE_PACKED; | |
199 | side_check_size(struct side_arg_vec, 20); | |
200 | ||
201 | struct side_arg_dynamic_field { | |
202 | side_ptr_t(const char) field_name; | |
e14987e0 | 203 | const struct side_arg elem; |
57553dfd MD |
204 | } SIDE_PACKED; |
205 | side_check_size(struct side_arg_dynamic_field, 16 + sizeof(const struct side_arg)); | |
206 | ||
b8dfb348 | 207 | #endif /* SIDE_ABI_TYPE_ARGUMENT_H */ |