2 * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
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.
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
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.
21 #include "ust-field-utils.h"
24 * The ustctl_field is made of a combination of C basic types
25 * ustctl_basic_type and _ustctl_basic_type.
27 * ustctl_basic_type contains an enumeration describing the abstract type.
28 * _ustctl_basic_type does _NOT_ contain an enumeration describing the
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.
37 * Compare two ustctl_integer_type fields.
38 * Returns 1 if both are identical.
40 static bool match_ustctl_field_integer(const struct ustctl_integer_type
*first
,
41 const struct ustctl_integer_type
*second
)
43 if (first
->size
!= second
->size
) {
46 if (first
->alignment
!= second
->alignment
) {
49 if (first
->signedness
!= second
->signedness
) {
52 if (first
->encoding
!= second
->encoding
) {
55 if (first
->base
!= second
->base
) {
58 if (first
->reverse_byte_order
!= second
->reverse_byte_order
) {
69 * Compare two _ustctl_basic_type fields known to be of type integer.
70 * Returns 1 if both are identical.
72 static bool match_ustctl_field_integer_from_raw_basic_type(
73 const union _ustctl_basic_type
*first
,
74 const union _ustctl_basic_type
*second
)
76 return match_ustctl_field_integer(&first
->integer
, &second
->integer
);
80 * Compare two _ustctl_basic_type fields known to be of type enum.
81 * Returns 1 if both are identical.
83 static bool match_ustctl_field_enum_from_raw_basic_type(
84 const union _ustctl_basic_type
*first
,
85 const union _ustctl_basic_type
*second
)
88 * Compare enumeration ID. Enumeration ID is provided to the application by
89 * the session daemon before event registration.
91 if (first
->enumeration
.id
!= second
->enumeration
.id
) {
96 * Sanity check of the name and container type. Those were already checked
97 * during enum registration.
99 if (strncmp(first
->enumeration
.name
, second
->enumeration
.name
,
100 LTTNG_UST_SYM_NAME_LEN
)) {
103 if (!match_ustctl_field_integer(&first
->enumeration
.container_type
,
104 &second
->enumeration
.container_type
)) {
115 * Compare two _ustctl_basic_type fields known to be of type string.
116 * Returns 1 if both are identical.
118 static bool match_ustctl_field_string_from_raw_basic_type(
119 const union _ustctl_basic_type
*first
,
120 const union _ustctl_basic_type
*second
)
122 return first
->string
.encoding
== second
->string
.encoding
;
126 * Compare two _ustctl_basic_type fields known to be of type float.
127 * Returns 1 if both are identical.
129 static bool match_ustctl_field_float_from_raw_basic_type(
130 const union _ustctl_basic_type
*first
,
131 const union _ustctl_basic_type
*second
)
133 if (first
->_float
.exp_dig
!= second
->_float
.exp_dig
) {
137 if (first
->_float
.mant_dig
!= second
->_float
.mant_dig
) {
141 if (first
->_float
.reverse_byte_order
!=
142 second
->_float
.reverse_byte_order
) {
146 if (first
->_float
.alignment
!= second
->_float
.alignment
) {
157 * Compare two _ustctl_basic_type fields given their respective abstract types.
158 * Returns 1 if both are identical.
160 static 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
)
166 if (first_atype
!= second_atype
) {
170 switch (first_atype
) {
171 case ustctl_atype_integer
:
172 if (!match_ustctl_field_integer_from_raw_basic_type(first
, second
)) {
176 case ustctl_atype_enum
:
177 if (!match_ustctl_field_enum_from_raw_basic_type(first
, second
)) {
181 case ustctl_atype_string
:
182 if (!match_ustctl_field_string_from_raw_basic_type(first
, second
)) {
186 case ustctl_atype_float
:
187 if (!match_ustctl_field_float_from_raw_basic_type(first
, second
)) {
202 * Compatibility layer between the ustctl_basic_type struct and
203 * _ustctl_basic_type union.
205 static bool match_ustctl_field_basic_type(const struct ustctl_basic_type
*first
,
206 const struct ustctl_basic_type
*second
)
208 return match_ustctl_field_raw_basic_type(first
->atype
, &first
->u
.basic
,
209 second
->atype
, &second
->u
.basic
);
212 int match_ustctl_field(const struct ustctl_field
*first
,
213 const struct ustctl_field
*second
)
215 /* Check the name of the field is identical. */
216 if (strncmp(first
->name
, second
->name
, LTTNG_UST_SYM_NAME_LEN
)) {
220 /* Check the field type is identical. */
221 if (first
->type
.atype
!= second
->type
.atype
) {
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
)) {
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
)) {
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
)) {
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
)) {
257 /* Match length of the array. */
258 if (first
->type
.u
.array
.length
!= second
->type
.u
.array
.length
) {
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
) {
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
)) {
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
) {