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 | ||
57553dfd MD |
64 | union side_arg_static { |
65 | /* Stack-copy basic types */ | |
66 | union side_bool_value bool_value; | |
67 | uint8_t byte_value; | |
68 | side_ptr_t(const void) string_value; /* const {uint8_t, uint16_t, uint32_t} * */ | |
69 | union side_integer_value integer_value; | |
70 | union side_float_value float_value; | |
71 | ||
72 | /* Stack-copy compound types */ | |
73 | side_ptr_t(const struct side_arg_vec) side_struct; | |
511ee756 | 74 | side_ptr_t(struct side_arg_variant) side_variant; |
57553dfd MD |
75 | side_ptr_t(const struct side_arg_vec) side_array; |
76 | side_ptr_t(const struct side_arg_vec) side_vla; | |
77 | void *side_vla_app_visitor_ctx; | |
78 | ||
79 | /* Gather basic types */ | |
80 | side_ptr_t(const void) side_bool_gather_ptr; | |
81 | side_ptr_t(const void) side_byte_gather_ptr; | |
82 | side_ptr_t(const void) side_integer_gather_ptr; | |
83 | side_ptr_t(const void) side_float_gather_ptr; | |
84 | side_ptr_t(const void) side_string_gather_ptr; | |
85 | ||
86 | /* Gather compound types */ | |
87 | side_ptr_t(const void) side_array_gather_ptr; | |
88 | side_ptr_t(const void) side_struct_gather_ptr; | |
89 | struct { | |
90 | side_ptr_t(const void) ptr; | |
91 | side_ptr_t(const void) length_ptr; | |
92 | } SIDE_PACKED side_vla_gather; | |
93 | side_padding(32); | |
94 | } SIDE_PACKED; | |
95 | side_check_size(union side_arg_static, 32); | |
96 | ||
97 | struct side_arg_dynamic_vla { | |
511ee756 | 98 | side_ptr_t(struct side_arg) sav; |
57553dfd MD |
99 | side_ptr_t(const struct side_attr) attr; |
100 | uint32_t len; | |
101 | uint32_t nr_attr; | |
102 | } SIDE_PACKED; | |
103 | side_check_size(struct side_arg_dynamic_vla, 40); | |
104 | ||
105 | struct side_arg_dynamic_struct { | |
511ee756 | 106 | side_ptr_t(struct side_arg_dynamic_field) fields; |
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_struct, 40); | |
112 | ||
113 | struct side_dynamic_struct_visitor { | |
114 | side_func_ptr_t(side_dynamic_struct_visitor_func) visitor; | |
115 | side_ptr_t(void) app_ctx; | |
116 | side_ptr_t(const struct side_attr) attr; | |
117 | uint32_t nr_attr; | |
118 | } SIDE_PACKED; | |
119 | side_check_size(struct side_dynamic_struct_visitor, 52); | |
120 | ||
121 | struct side_dynamic_vla_visitor { | |
122 | side_func_ptr_t(side_visitor_func) visitor; | |
123 | side_ptr_t(void) app_ctx; | |
124 | side_ptr_t(const struct side_attr) attr; | |
125 | uint32_t nr_attr; | |
126 | } SIDE_PACKED; | |
127 | side_check_size(struct side_dynamic_vla_visitor, 52); | |
128 | ||
129 | union side_arg_dynamic { | |
130 | /* Dynamic basic types */ | |
131 | struct side_type_null side_null; | |
132 | struct { | |
133 | struct side_type_bool type; | |
134 | union side_bool_value value; | |
135 | } SIDE_PACKED side_bool; | |
136 | struct { | |
137 | struct side_type_byte type; | |
138 | uint8_t value; | |
139 | } SIDE_PACKED side_byte; | |
140 | struct { | |
141 | struct side_type_string type; | |
142 | uint64_t value; /* const char * */ | |
143 | } SIDE_PACKED side_string; | |
144 | struct { | |
145 | struct side_type_integer type; | |
146 | union side_integer_value value; | |
147 | } SIDE_PACKED side_integer; | |
148 | struct { | |
149 | struct side_type_float type; | |
150 | union side_float_value value; | |
151 | } SIDE_PACKED side_float; | |
152 | ||
153 | /* Dynamic compound types */ | |
154 | side_ptr_t(const struct side_arg_dynamic_struct) side_dynamic_struct; | |
155 | side_ptr_t(const struct side_arg_dynamic_vla) side_dynamic_vla; | |
156 | ||
157 | struct side_dynamic_struct_visitor side_dynamic_struct_visitor; | |
158 | struct side_dynamic_vla_visitor side_dynamic_vla_visitor; | |
159 | ||
160 | side_padding(58); | |
161 | } SIDE_PACKED; | |
162 | side_check_size(union side_arg_dynamic, 58); | |
163 | ||
164 | struct side_arg { | |
165 | side_enum_t(enum side_type_label, uint16_t) type; | |
e28b5a3c | 166 | uint16_t flags; |
57553dfd MD |
167 | union { |
168 | union side_arg_static side_static; | |
169 | union side_arg_dynamic side_dynamic; | |
e28b5a3c | 170 | side_padding(60); |
57553dfd MD |
171 | } SIDE_PACKED u; |
172 | } SIDE_PACKED; | |
173 | side_check_size(struct side_arg, 64); | |
174 | ||
175 | struct side_arg_variant { | |
176 | struct side_arg selector; | |
177 | struct side_arg option; | |
178 | } SIDE_PACKED; | |
179 | side_check_size(struct side_arg_variant, 128); | |
180 | ||
181 | struct side_arg_vec { | |
511ee756 | 182 | side_ptr_t(struct side_arg) sav; |
57553dfd MD |
183 | uint32_t len; |
184 | } SIDE_PACKED; | |
185 | side_check_size(struct side_arg_vec, 20); | |
186 | ||
187 | struct side_arg_dynamic_field { | |
188 | side_ptr_t(const char) field_name; | |
511ee756 | 189 | struct side_arg elem; |
57553dfd MD |
190 | } SIDE_PACKED; |
191 | side_check_size(struct side_arg_dynamic_field, 16 + sizeof(const struct side_arg)); | |
192 | ||
b8dfb348 | 193 | #endif /* SIDE_ABI_TYPE_ARGUMENT_H */ |