Fix: userspace probe accessors are not const-correct
[lttng-tools.git] / src / bin / lttng-sessiond / ust-field-utils.c
CommitLineData
98b73e88
FD
1/*
2 * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#include <stdbool.h>
19#include <string.h>
20
21#include "ust-field-utils.h"
22
23/*
24 * The ustctl_field is made of a combination of C basic types
25 * ustctl_basic_type and _ustctl_basic_type.
26 *
27 * ustctl_basic_type contains an enumeration describing the abstract type.
28 * _ustctl_basic_type does _NOT_ contain an enumeration describing the
29 * abstract type.
30 *
31 * A layer is needed to use the same code for both structures.
32 * When dealing with _ustctl_basic_type, we need to use the abstract type of
33 * the ustctl_type struct.
34 */
35
36/*
37 * Compare two ustctl_integer_type fields.
38 * Returns 1 if both are identical.
39 */
40static bool match_ustctl_field_integer(const struct ustctl_integer_type *first,
41 const struct ustctl_integer_type *second)
42{
43 if (first->size != second->size) {
44 goto no_match;
45 }
46 if (first->alignment != second->alignment) {
47 goto no_match;
48 }
49 if (first->signedness != second->signedness) {
50 goto no_match;
51 }
52 if (first->encoding != second->encoding) {
53 goto no_match;
54 }
55 if (first->base != second->base) {
56 goto no_match;
57 }
58 if (first->reverse_byte_order != second->reverse_byte_order) {
59 goto no_match;
60 }
61
62 return true;
63
64no_match:
65 return false;
66}
67
68/*
69 * Compare two _ustctl_basic_type fields known to be of type integer.
70 * Returns 1 if both are identical.
71 */
72static bool match_ustctl_field_integer_from_raw_basic_type(
73 const union _ustctl_basic_type *first,
74 const union _ustctl_basic_type *second)
75{
76 return match_ustctl_field_integer(&first->integer, &second->integer);
77}
78
79/*
80 * Compare two _ustctl_basic_type fields known to be of type enum.
81 * Returns 1 if both are identical.
82 */
83static bool match_ustctl_field_enum_from_raw_basic_type(
84 const union _ustctl_basic_type *first,
85 const union _ustctl_basic_type *second)
86{
87 /*
88 * Compare enumeration ID. Enumeration ID is provided to the application by
89 * the session daemon before event registration.
90 */
91 if (first->enumeration.id != second->enumeration.id) {
92 goto no_match;
93 }
94
95 /*
96 * Sanity check of the name and container type. Those were already checked
97 * during enum registration.
98 */
99 if (strncmp(first->enumeration.name, second->enumeration.name,
100 LTTNG_UST_SYM_NAME_LEN)) {
101 goto no_match;
102 }
103 if (!match_ustctl_field_integer(&first->enumeration.container_type,
104 &second->enumeration.container_type)) {
105 goto no_match;
106 }
107
108 return true;
109
110no_match:
111 return false;
112}
113
114/*
115 * Compare two _ustctl_basic_type fields known to be of type string.
116 * Returns 1 if both are identical.
117 */
118static bool match_ustctl_field_string_from_raw_basic_type(
119 const union _ustctl_basic_type *first,
120 const union _ustctl_basic_type *second)
121{
122 return first->string.encoding == second->string.encoding;
123}
124
125/*
126 * Compare two _ustctl_basic_type fields known to be of type float.
127 * Returns 1 if both are identical.
128 */
129static bool match_ustctl_field_float_from_raw_basic_type(
130 const union _ustctl_basic_type *first,
131 const union _ustctl_basic_type *second)
132{
133 if (first->_float.exp_dig != second->_float.exp_dig) {
134 goto no_match;
135 }
136
137 if (first->_float.mant_dig != second->_float.mant_dig) {
138 goto no_match;
139 }
140
141 if (first->_float.reverse_byte_order !=
142 second->_float.reverse_byte_order) {
143 goto no_match;
144 }
145
146 if (first->_float.alignment != second->_float.alignment) {
147 goto no_match;
148 }
149
150 return true;
151
152no_match:
153 return false;
154}
155
156/*
157 * Compare two _ustctl_basic_type fields given their respective abstract types.
158 * Returns 1 if both are identical.
159 */
160static bool match_ustctl_field_raw_basic_type(
161 enum ustctl_abstract_types first_atype,
162 const union _ustctl_basic_type *first,
163 enum ustctl_abstract_types second_atype,
164 const union _ustctl_basic_type *second)
165{
166 if (first_atype != second_atype) {
167 goto no_match;
168 }
169
170 switch (first_atype) {
171 case ustctl_atype_integer:
172 if (!match_ustctl_field_integer_from_raw_basic_type(first, second)) {
173 goto no_match;
174 }
175 break;
176 case ustctl_atype_enum:
177 if (!match_ustctl_field_enum_from_raw_basic_type(first, second)) {
178 goto no_match;
179 }
180 break;
181 case ustctl_atype_string:
182 if (!match_ustctl_field_string_from_raw_basic_type(first, second)) {
183 goto no_match;
184 }
185 break;
186 case ustctl_atype_float:
187 if (!match_ustctl_field_float_from_raw_basic_type(first, second)) {
188 goto no_match;
189 }
190 break;
191 default:
192 goto no_match;
193 }
194
195 return true;
196
197no_match:
198 return false;
199}
200
201/*
202 * Compatibility layer between the ustctl_basic_type struct and
203 * _ustctl_basic_type union.
204 */
205static bool match_ustctl_field_basic_type(const struct ustctl_basic_type *first,
206 const struct ustctl_basic_type *second)
207{
208 return match_ustctl_field_raw_basic_type(first->atype, &first->u.basic,
209 second->atype, &second->u.basic);
210}
211
212int match_ustctl_field(const struct ustctl_field *first,
213 const struct ustctl_field *second)
214{
215 /* Check the name of the field is identical. */
216 if (strncmp(first->name, second->name, LTTNG_UST_SYM_NAME_LEN)) {
217 goto no_match;
218 }
219
220 /* Check the field type is identical. */
221 if (first->type.atype != second->type.atype) {
222 goto no_match;
223 }
224
225 /* Check the field layout. */
226 switch (first->type.atype) {
227 case ustctl_atype_integer:
228 case ustctl_atype_enum:
229 case ustctl_atype_string:
230 case ustctl_atype_float:
231 if (!match_ustctl_field_raw_basic_type(first->type.atype,
232 &first->type.u.basic, second->type.atype,
233 &second->type.u.basic)) {
234 goto no_match;
235 }
236 break;
237 case ustctl_atype_sequence:
238 /* Match element type of the sequence. */
239 if (!match_ustctl_field_basic_type(&first->type.u.sequence.elem_type,
240 &second->type.u.sequence.elem_type)) {
241 goto no_match;
242 }
243
244 /* Match length type of the sequence. */
245 if (!match_ustctl_field_basic_type(&first->type.u.sequence.length_type,
246 &second->type.u.sequence.length_type)) {
247 goto no_match;
248 }
249 break;
250 case ustctl_atype_array:
251 /* Match element type of the array. */
252 if (!match_ustctl_field_basic_type(&first->type.u.array.elem_type,
253 &second->type.u.array.elem_type)) {
254 goto no_match;
255 }
256
257 /* Match length of the array. */
258 if (first->type.u.array.length != second->type.u.array.length) {
259 goto no_match;
260 }
261 break;
262 case ustctl_atype_variant:
263 /* Compare number of choice of the variants. */
264 if (first->type.u.variant.nr_choices !=
265 second->type.u.variant.nr_choices) {
266 goto no_match;
267 }
268
269 /* Compare tag name of the variants. */
270 if (strncmp(first->type.u.variant.tag_name,
271 second->type.u.variant.tag_name,
272 LTTNG_UST_SYM_NAME_LEN)) {
273 goto no_match;
274 }
275 break;
276 case ustctl_atype_struct:
277 /* Compare number of fields of the structs. */
278 if (first->type.u._struct.nr_fields != second->type.u._struct.nr_fields) {
279 goto no_match;
280 }
281 break;
282 default:
283 goto no_match;
284 }
285
286 return true;
287
288no_match:
289 return false;
290}
This page took 0.036258 seconds and 5 git commands to generate.