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