fd1979c0157657cd0ef4b90a3acb8e8f051bd469
[libside.git] / include / side / abi / type-argument.h
1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2022-2023 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6 #ifndef SIDE_ABI_TYPE_ARGUMENT_H
7 #define SIDE_ABI_TYPE_ARGUMENT_H
8
9 #include <stdint.h>
10 #include <side/macros.h>
11 #include <side/endian.h>
12
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>
17
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
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 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
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;
74 side_ptr_t(const struct side_arg_variant) side_variant;
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 {
98 side_ptr_t(const struct side_arg) sav;
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 {
106 side_ptr_t(const struct side_arg_dynamic_field) fields;
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;
166 uint16_t flags;
167 union {
168 union side_arg_static side_static;
169 union side_arg_dynamic side_dynamic;
170 side_padding(60);
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 {
182 side_ptr_t(const struct side_arg) sav;
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;
189 const struct side_arg elem;
190 } SIDE_PACKED;
191 side_check_size(struct side_arg_dynamic_field, 16 + sizeof(const struct side_arg));
192
193 #endif /* SIDE_ABI_TYPE_ARGUMENT_H */
This page took 0.033226 seconds and 3 git commands to generate.