60903dd661ff8c54a14ba285109a54271f6c987b
[babeltrace.git] / src / plugins / lttng-utils / debug-info / trace-ir-metadata-field-class-copy.c
1 /*
2 * Babeltrace - Trace IR field copy
3 *
4 * Copyright (c) 2015-2019 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2018 Philippe Proulx <pproulx@efficios.com>
6 * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27 #define BT_COMP_LOG_SELF_COMP (md_maps->self_comp)
28 #define BT_LOG_OUTPUT_LEVEL (md_maps->log_level)
29 #define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-META-FC-COPY"
30 #include "logging/comp-logging.h"
31
32 #include "common/assert.h"
33 #include "common/common.h"
34 #include "compat/compiler.h"
35 #include <babeltrace2/babeltrace.h>
36
37 #include "trace-ir-metadata-copy.h"
38 #include "trace-ir-metadata-field-class-copy.h"
39
40 /*
41 * This fonction walks througth the nested structures field class to resolve a
42 * field path object. A field path is made of indexes inside possibly nested
43 * structures ultimately leading to a field class.
44 */
45 static
46 const bt_field_class *walk_field_path(struct trace_ir_metadata_maps *md_maps,
47 const bt_field_path *fp, const bt_field_class *fc)
48 {
49 uint64_t i, fp_item_count;
50 const bt_field_class *curr_fc;
51
52 BT_ASSERT(bt_field_class_get_type(fc) == BT_FIELD_CLASS_TYPE_STRUCTURE);
53 BT_COMP_LOGD("Walking field path on field class: fp-addr=%p, fc-addr=%p",
54 fp, fc);
55
56 fp_item_count = bt_field_path_get_item_count(fp);
57 curr_fc = fc;
58 for (i = 0; i < fp_item_count; i++) {
59 bt_field_class_type fc_type = bt_field_class_get_type(curr_fc);
60 const bt_field_path_item *fp_item =
61 bt_field_path_borrow_item_by_index_const(fp, i);
62
63 switch (fc_type) {
64 case BT_FIELD_CLASS_TYPE_STRUCTURE:
65 {
66 const bt_field_class_structure_member *member;
67
68 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
69 BT_FIELD_PATH_ITEM_TYPE_INDEX);
70 member = bt_field_class_structure_borrow_member_by_index_const(
71 curr_fc,
72 bt_field_path_item_index_get_index(fp_item));
73 curr_fc = bt_field_class_structure_member_borrow_field_class_const(
74 member);
75 break;
76 }
77 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
78 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
79 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
80 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
81 {
82 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
83 BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
84 curr_fc = bt_field_class_option_borrow_field_class_const(
85 curr_fc);
86 break;
87 }
88 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
89 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
90 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
91 {
92 const bt_field_class_variant_option *option;
93
94 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
95 BT_FIELD_PATH_ITEM_TYPE_INDEX);
96 option = bt_field_class_variant_borrow_option_by_index_const(
97 curr_fc,
98 bt_field_path_item_index_get_index(fp_item));
99 curr_fc = bt_field_class_variant_option_borrow_field_class_const(
100 option);
101 break;
102 }
103 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
104 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
105 {
106 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
107 BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
108 curr_fc = bt_field_class_array_borrow_element_field_class_const(
109 curr_fc);
110 break;
111 }
112 default:
113 abort();
114 }
115 }
116
117 return curr_fc;
118 }
119
120 static
121 const bt_field_class *resolve_field_path_to_field_class(const bt_field_path *fp,
122 struct trace_ir_metadata_maps *md_maps)
123 {
124 struct field_class_resolving_context *fc_resolving_ctx;
125 const bt_field_class *fc;
126 bt_field_path_scope fp_scope;
127
128 BT_COMP_LOGD("Resolving field path: fp-addr=%p", fp);
129
130 fc_resolving_ctx = md_maps->fc_resolving_ctx;
131 fp_scope = bt_field_path_get_root_scope(fp);
132
133 switch (fp_scope) {
134 case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
135 fc = walk_field_path(md_maps, fp,
136 fc_resolving_ctx->packet_context);
137 break;
138 case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
139 fc = walk_field_path(md_maps, fp,
140 fc_resolving_ctx->event_common_context);
141 break;
142 case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
143 fc = walk_field_path(md_maps, fp,
144 fc_resolving_ctx->event_specific_context);
145 break;
146 case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
147 fc = walk_field_path(md_maps, fp,
148 fc_resolving_ctx->event_payload);
149 break;
150 default:
151 abort();
152 }
153
154 return fc;
155 }
156
157 static inline
158 void field_class_integer_set_props(const bt_field_class *input_fc,
159 bt_field_class *output_fc)
160 {
161 bt_field_class_integer_set_preferred_display_base(output_fc,
162 bt_field_class_integer_get_preferred_display_base(input_fc));
163 bt_field_class_integer_set_field_value_range(output_fc,
164 bt_field_class_integer_get_field_value_range(input_fc));
165 }
166
167 static inline
168 int field_class_bool_copy(struct trace_ir_metadata_maps *md_maps,
169 const bt_field_class *in_field_class,
170 bt_field_class *out_field_class)
171 {
172 BT_COMP_LOGD("Copying content of boolean field class: "
173 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
174 /*
175 * There is no content to copy. Keep this function call anyway for
176 * logging purposes.
177 */
178 BT_COMP_LOGD("Copied content of boolean field class: "
179 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
180 return 0;
181 }
182
183 static inline
184 int field_class_bit_array_copy(
185 struct trace_ir_metadata_maps *md_maps,
186 const bt_field_class *in_field_class,
187 bt_field_class *out_field_class)
188 {
189 BT_COMP_LOGD("Copying content of bit array field class: "
190 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
191 /*
192 * There is no content to copy. Keep this function call anyway for
193 * logging purposes.
194 */
195 BT_COMP_LOGD("Copied content of bit array field class: "
196 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
197 return 0;
198 }
199
200 static inline
201 int field_class_unsigned_integer_copy(
202 struct trace_ir_metadata_maps *md_maps,
203 const bt_field_class *in_field_class,
204 bt_field_class *out_field_class)
205 {
206 BT_COMP_LOGD("Copying content of unsigned integer field class: "
207 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
208
209 field_class_integer_set_props(in_field_class, out_field_class);
210
211 BT_COMP_LOGD("Copied content of unsigned integer field class: "
212 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
213 return 0;
214 }
215
216 static inline
217 int field_class_signed_integer_copy(
218 struct trace_ir_metadata_maps *md_maps,
219 const bt_field_class *in_field_class,
220 bt_field_class *out_field_class)
221 {
222 BT_COMP_LOGD("Copying content of signed integer field class: "
223 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
224
225 field_class_integer_set_props(in_field_class, out_field_class);
226
227 BT_COMP_LOGD("Copied content of signed integer field class: "
228 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
229 return 0;
230 }
231
232 BT_HIDDEN
233 int field_class_unsigned_enumeration_copy(
234 struct trace_ir_metadata_maps *md_maps,
235 const bt_field_class *in_field_class,
236 bt_field_class *out_field_class)
237 {
238 uint64_t i, enum_mapping_count;
239 int ret = 0;
240
241 BT_COMP_LOGD("Copying content of unsigned enumeration field class: "
242 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
243
244 /* Copy properties of the inner integer. */
245 field_class_integer_set_props(in_field_class, out_field_class);
246
247 /* Copy all enumeration entries. */
248 enum_mapping_count = bt_field_class_enumeration_get_mapping_count(
249 in_field_class);
250 for (i = 0; i < enum_mapping_count; i++) {
251 const char *label;
252 const bt_integer_range_set_unsigned *range_set;
253 const bt_field_class_enumeration_unsigned_mapping *u_mapping;
254 const bt_field_class_enumeration_mapping *mapping;
255
256 u_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
257 in_field_class, i);
258 mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(
259 u_mapping);
260 label = bt_field_class_enumeration_mapping_get_label(mapping);
261 range_set = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
262 u_mapping);
263 ret = bt_field_class_enumeration_unsigned_add_mapping(
264 out_field_class, label, range_set);
265 if (ret) {
266 goto error;
267 }
268 }
269
270 BT_COMP_LOGD("Copied content of unsigned enumeration field class: "
271 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
272
273 error:
274 return ret;
275 }
276
277 static inline
278 int field_class_signed_enumeration_copy(
279 struct trace_ir_metadata_maps *md_maps,
280 const bt_field_class *in_field_class,
281 bt_field_class *out_field_class)
282 {
283 uint64_t i, enum_mapping_count;
284 int ret = 0;
285
286 BT_COMP_LOGD("Copying content of signed enumeration field class: "
287 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
288
289 /* Copy properties of the inner integer. */
290 field_class_integer_set_props(in_field_class, out_field_class);
291
292 /* Copy all enumeration entries. */
293 enum_mapping_count =
294 bt_field_class_enumeration_get_mapping_count(in_field_class);
295 for (i = 0; i < enum_mapping_count; i++) {
296 const char *label;
297 const bt_integer_range_set_signed *range_set;
298 const bt_field_class_enumeration_signed_mapping *s_mapping;
299 const bt_field_class_enumeration_mapping *mapping;
300
301 s_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
302 in_field_class, i);
303 mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(
304 s_mapping);
305 label = bt_field_class_enumeration_mapping_get_label(mapping);
306 range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
307 s_mapping);
308 ret = bt_field_class_enumeration_signed_add_mapping(
309 out_field_class, label, range_set);
310 if (ret) {
311 goto error;
312 }
313 }
314
315 BT_COMP_LOGD("Copied content of signed enumeration field class: "
316 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
317
318 error:
319 return ret;
320 }
321
322 static inline
323 int field_class_single_precision_real_copy(
324 struct trace_ir_metadata_maps *md_maps,
325 const bt_field_class *in_field_class,
326 bt_field_class *out_field_class)
327 {
328 BT_COMP_LOGD("Copying content of single-precision real field class: "
329 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
330
331 BT_COMP_LOGD("Copied content single-precision real field class:"
332 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
333
334 return 0;
335 }
336
337 static inline
338 int field_class_double_precision_real_copy(
339 struct trace_ir_metadata_maps *md_maps,
340 const bt_field_class *in_field_class,
341 bt_field_class *out_field_class)
342 {
343 BT_COMP_LOGD("Copying content of double-precision real field class: "
344 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
345
346 BT_COMP_LOGD("Copied content double-precision real field class:"
347 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
348
349 return 0;
350 }
351
352 static inline
353 int field_class_structure_copy(
354 struct trace_ir_metadata_maps *md_maps,
355 const bt_field_class *in_field_class,
356 bt_field_class *out_field_class)
357 {
358 uint64_t i, struct_member_count;
359 int ret = 0;
360
361 BT_COMP_LOGD("Copying content of structure field class: "
362 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
363 /* Get the number of member in that struct. */
364 struct_member_count =
365 bt_field_class_structure_get_member_count(in_field_class);
366
367 /* Iterate over all the members of the struct. */
368 for (i = 0; i < struct_member_count; i++) {
369 const bt_field_class_structure_member *in_member;
370 bt_field_class_structure_member *out_member;
371 const char *member_name;
372 const bt_field_class *in_member_fc;
373 bt_field_class *out_member_field_class;
374
375 in_member = bt_field_class_structure_borrow_member_by_index_const(
376 in_field_class, i);
377 in_member_fc = bt_field_class_structure_member_borrow_field_class_const(
378 in_member);
379 member_name = bt_field_class_structure_member_get_name(in_member);
380 BT_COMP_LOGD("Copying structure field class's field: "
381 "index=%" PRId64 ", member-fc-addr=%p, field-name=\"%s\"",
382 i, in_member_fc, member_name);
383
384 out_member_field_class = create_field_class_copy(md_maps,
385 in_member_fc);
386 if (!out_member_field_class) {
387 BT_COMP_LOGE("Cannot copy structure field class's field: "
388 "index=%" PRId64 ", field-fc-addr=%p, field-name=\"%s\"",
389 i, in_member_fc, member_name);
390 ret = -1;
391 goto error;
392 }
393 ret = copy_field_class_content(md_maps, in_member_fc,
394 out_member_field_class);
395 if (ret) {
396 goto error;
397 }
398
399 if (bt_field_class_structure_append_member(out_field_class,
400 member_name, out_member_field_class) !=
401 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
402 BT_COMP_LOGE("Cannot append structure field class's field: "
403 "index=%" PRId64 ", "
404 "field-fc-addr=%p, field-name=\"%s\"",
405 i, in_member_fc, member_name);
406 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_member_field_class);
407 ret = -1;
408 goto error;
409 }
410
411 out_member = bt_field_class_structure_borrow_member_by_index(
412 out_field_class, i);
413 BT_ASSERT(out_member);
414
415 /*
416 * Safe to use the same value object because it's frozen
417 * at this point.
418 */
419 bt_field_class_structure_member_set_user_attributes(
420 out_member,
421 bt_field_class_structure_member_borrow_user_attributes_const(
422 in_member));
423 }
424
425 BT_COMP_LOGD("Copied structure field class: original-fc-addr=%p, copy-fc-addr=%p",
426 in_field_class, out_field_class);
427
428 error:
429 return ret;
430 }
431
432 static inline
433 int field_class_variant_copy(
434 struct trace_ir_metadata_maps *md_maps,
435 const bt_field_class *in_field_class,
436 bt_field_class *out_field_class)
437 {
438 bt_field_class *out_tag_field_class = NULL;
439 uint64_t i, variant_option_count;
440 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
441 int ret = 0;
442
443 BT_COMP_LOGD("Copying content of variant field class: "
444 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
445 variant_option_count =
446 bt_field_class_variant_get_option_count(in_field_class);
447 for (i = 0; i < variant_option_count; i++) {
448 const bt_field_class *in_option_fc;
449 const char *option_name;
450 bt_field_class *out_option_field_class;
451 const bt_field_class_variant_option *in_option;
452 bt_field_class_variant_option *out_option;
453
454 in_option = bt_field_class_variant_borrow_option_by_index_const(
455 in_field_class, i);
456 in_option_fc = bt_field_class_variant_option_borrow_field_class_const(
457 in_option);
458 option_name = bt_field_class_variant_option_get_name(in_option);
459 out_option_field_class = create_field_class_copy_internal(
460 md_maps, in_option_fc);
461 if (!out_option_field_class) {
462 BT_COMP_LOGE_STR("Cannot copy field class.");
463 ret = -1;
464 goto error;
465 }
466 ret = copy_field_class_content_internal(md_maps, in_option_fc,
467 out_option_field_class);
468 if (ret) {
469 BT_COMP_LOGE_STR("Error copying content of option variant "
470 "field class'");
471 goto error;
472 }
473
474 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR) {
475 const bt_field_class_variant_with_selector_integer_unsigned_option *spec_opt =
476 bt_field_class_variant_with_selector_integer_unsigned_borrow_option_by_index_const(
477 in_field_class, i);
478 const bt_integer_range_set_unsigned *ranges =
479 bt_field_class_variant_with_selector_integer_unsigned_option_borrow_ranges_const(
480 spec_opt);
481
482 if (bt_field_class_variant_with_selector_integer_unsigned_append_option(
483 out_field_class, option_name,
484 out_option_field_class, ranges) !=
485 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
486 BT_COMP_LOGE_STR("Cannot append option to variant field class with unsigned integer selector'");
487 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
488 ret = -1;
489 goto error;
490 }
491 } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR) {
492 const bt_field_class_variant_with_selector_integer_signed_option *spec_opt =
493 bt_field_class_variant_with_selector_integer_signed_borrow_option_by_index_const(
494 in_field_class, i);
495 const bt_integer_range_set_signed *ranges =
496 bt_field_class_variant_with_selector_integer_signed_option_borrow_ranges_const(
497 spec_opt);
498
499 if (bt_field_class_variant_with_selector_integer_signed_append_option(
500 out_field_class, option_name,
501 out_option_field_class, ranges) !=
502 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
503 BT_COMP_LOGE_STR("Cannot append option to variant field class with signed integer selector'");
504 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
505 ret = -1;
506 goto error;
507 }
508 } else {
509 BT_ASSERT(fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR);
510
511 if (bt_field_class_variant_without_selector_append_option(
512 out_field_class, option_name,
513 out_option_field_class) !=
514 BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_OK) {
515 BT_COMP_LOGE_STR("Cannot append option to variant field class'");
516 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
517 ret = -1;
518 goto error;
519 }
520 }
521
522 out_option = bt_field_class_variant_borrow_option_by_index(
523 out_field_class, i);
524 BT_ASSERT(out_option);
525
526 /*
527 * Safe to use the same value object because it's frozen
528 * at this point.
529 */
530 bt_field_class_variant_option_set_user_attributes(
531 out_option,
532 bt_field_class_variant_option_borrow_user_attributes_const(
533 in_option));
534 }
535
536 BT_COMP_LOGD("Copied content of variant field class: in-fc-addr=%p, "
537 "out-fc-addr=%p", in_field_class, out_field_class);
538
539 error:
540 return ret;
541 }
542
543 static inline
544 int field_class_static_array_copy(
545 struct trace_ir_metadata_maps *md_maps,
546 const bt_field_class *in_field_class,
547 bt_field_class *out_field_class)
548 {
549 BT_COMP_LOGD("Copying content of static array field class: in-fc-addr=%p, "
550 "out-fc-addr=%p", in_field_class, out_field_class);
551 /*
552 * There is no content to copy. Keep this function call anyway for
553 * logging purposes.
554 */
555 BT_COMP_LOGD("Copied content of static array field class: in-fc-addr=%p, "
556 "out-fc-addr=%p", in_field_class, out_field_class);
557
558 return 0;
559 }
560
561 static inline
562 int field_class_dynamic_array_copy(
563 struct trace_ir_metadata_maps *md_maps,
564 const bt_field_class *in_field_class,
565 bt_field_class *out_field_class)
566 {
567 BT_COMP_LOGD("Copying content of dynamic array field class: "
568 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
569 /*
570 * There is no content to copy. Keep this function call anyway for
571 * logging purposes.
572 */
573 BT_COMP_LOGD("Copied content of dynamic array field class: "
574 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
575
576 return 0;
577 }
578
579 static inline
580 int field_class_option_copy(
581 struct trace_ir_metadata_maps *md_maps,
582 const bt_field_class *in_field_class,
583 bt_field_class *out_field_class)
584 {
585 BT_COMP_LOGD("Copying content of option field class: "
586 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
587
588 if (bt_field_class_get_type(out_field_class) ==
589 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
590 bt_field_class_option_with_selector_bool_set_selector_is_reversed(
591 out_field_class,
592 bt_field_class_option_with_selector_bool_selector_is_reversed(
593 in_field_class));
594 }
595
596 BT_COMP_LOGD("Copied content of option field class: "
597 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
598
599 return 0;
600 }
601
602 static inline
603 int field_class_string_copy(struct trace_ir_metadata_maps *md_maps,
604 const bt_field_class *in_field_class,
605 bt_field_class *out_field_class)
606 {
607 BT_COMP_LOGD("Copying content of string field class: in-fc-addr=%p, "
608 "out-fc-addr=%p", in_field_class, out_field_class);
609 /*
610 * There is no content to copy. Keep this function call anyway for
611 * logging purposes.
612 */
613 BT_COMP_LOGD("Copied content of string field class: in-fc-addr=%p, "
614 "out-fc-addr=%p", in_field_class, out_field_class);
615
616 return 0;
617 }
618
619 static
620 bt_field_class *copy_field_class_array_element(struct trace_ir_metadata_maps *md_maps,
621 const bt_field_class *in_elem_fc)
622 {
623 int ret;
624 bt_field_class *out_elem_fc =
625 create_field_class_copy_internal(md_maps, in_elem_fc);
626 if (!out_elem_fc) {
627 BT_COMP_LOGE("Error creating output elem field class "
628 "from input elem field class for static array: "
629 "in-fc-addr=%p", in_elem_fc);
630 goto error;
631 }
632
633 ret = copy_field_class_content_internal(md_maps, in_elem_fc, out_elem_fc);
634 if (ret) {
635 BT_COMP_LOGE("Error creating output elem field class "
636 "from input elem field class for static array: "
637 "in-fc-addr=%p", in_elem_fc);
638 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_elem_fc);
639 goto error;
640 }
641
642 error:
643 return out_elem_fc;
644 }
645
646 BT_HIDDEN
647 bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *md_maps,
648 const bt_field_class *in_field_class)
649 {
650 bt_field_class *out_field_class = NULL;
651 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
652
653 BT_COMP_LOGD("Creating bare field class based on field class: in-fc-addr=%p",
654 in_field_class);
655
656 switch (fc_type) {
657 case BT_FIELD_CLASS_TYPE_BOOL:
658 out_field_class = bt_field_class_bool_create(
659 md_maps->output_trace_class);
660 break;
661 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
662 out_field_class = bt_field_class_bit_array_create(
663 md_maps->output_trace_class,
664 bt_field_class_bit_array_get_length(
665 in_field_class));
666 break;
667 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
668 out_field_class = bt_field_class_integer_unsigned_create(
669 md_maps->output_trace_class);
670 break;
671 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
672 out_field_class = bt_field_class_integer_signed_create(
673 md_maps->output_trace_class);
674 break;
675 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
676 out_field_class = bt_field_class_enumeration_unsigned_create(
677 md_maps->output_trace_class);
678 break;
679 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
680 out_field_class = bt_field_class_enumeration_signed_create(
681 md_maps->output_trace_class);
682 break;
683 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
684 out_field_class = bt_field_class_real_single_precision_create(
685 md_maps->output_trace_class);
686 break;
687 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
688 out_field_class = bt_field_class_real_double_precision_create(
689 md_maps->output_trace_class);
690 break;
691 case BT_FIELD_CLASS_TYPE_STRING:
692 out_field_class = bt_field_class_string_create(
693 md_maps->output_trace_class);
694 break;
695 case BT_FIELD_CLASS_TYPE_STRUCTURE:
696 out_field_class = bt_field_class_structure_create(
697 md_maps->output_trace_class);
698 break;
699 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
700 {
701 const bt_field_class *in_elem_fc =
702 bt_field_class_array_borrow_element_field_class_const(
703 in_field_class);
704 uint64_t array_len = bt_field_class_array_static_get_length(
705 in_field_class);
706
707 bt_field_class *out_elem_fc = copy_field_class_array_element(
708 md_maps, in_elem_fc);
709 if (!out_elem_fc) {
710 out_field_class = NULL;
711 goto error;
712 }
713
714 out_field_class = bt_field_class_array_static_create(
715 md_maps->output_trace_class,
716 out_elem_fc, array_len);
717 break;
718 }
719 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
720 {
721 const bt_field_class *in_elem_fc =
722 bt_field_class_array_borrow_element_field_class_const(
723 in_field_class);
724 const bt_field_path *length_fp =
725 bt_field_class_array_dynamic_borrow_length_field_path_const(
726 in_field_class);
727 bt_field_class *out_length_fc = NULL;
728
729 bt_field_class *out_elem_fc = copy_field_class_array_element(
730 md_maps, in_elem_fc);
731 if (!out_elem_fc) {
732 out_field_class = NULL;
733 goto error;
734 }
735
736 if (length_fp) {
737 const bt_field_class *in_length_fc =
738 resolve_field_path_to_field_class(length_fp,
739 md_maps);
740
741 BT_ASSERT(in_length_fc);
742 out_length_fc = g_hash_table_lookup(md_maps->field_class_map,
743 in_length_fc);
744 BT_ASSERT(out_length_fc);
745 }
746
747 out_field_class = bt_field_class_array_dynamic_create(
748 md_maps->output_trace_class,
749 out_elem_fc, out_length_fc);
750 break;
751 }
752 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
753 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
754 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
755 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
756 {
757 const bt_field_class *in_content_fc =
758 bt_field_class_option_borrow_field_class_const(
759 in_field_class);
760 bt_field_class *out_selector_fc = NULL;
761 bt_field_class *out_content_fc;
762 int ret;
763
764 out_content_fc = create_field_class_copy_internal(
765 md_maps, in_content_fc);
766 if (!out_content_fc) {
767 BT_COMP_LOGE_STR("Cannot copy option's content field class.");
768 goto error;
769 }
770
771 ret = copy_field_class_content_internal(md_maps,
772 in_content_fc, out_content_fc);
773 if (ret) {
774 BT_COMP_LOGE_STR("Error copying content of option's "
775 "content field class");
776 goto error;
777 }
778
779 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
780 out_field_class =
781 bt_field_class_option_without_selector_create(
782 md_maps->output_trace_class,
783 out_content_fc);
784 } else {
785 const bt_field_path *in_selector_fp =
786 bt_field_class_option_with_selector_borrow_selector_field_path_const(
787 in_field_class);
788 const bt_field_class *in_selector_fc;
789
790 BT_ASSERT(in_selector_fp);
791 in_selector_fc = resolve_field_path_to_field_class(
792 in_selector_fp, md_maps);
793 BT_ASSERT(in_selector_fc);
794 out_selector_fc = g_hash_table_lookup(
795 md_maps->field_class_map, in_selector_fc);
796 BT_ASSERT(out_selector_fc);
797
798 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
799 out_field_class =
800 bt_field_class_option_with_selector_bool_create(
801 md_maps->output_trace_class,
802 out_content_fc, out_selector_fc);
803 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR) {
804 const bt_integer_range_set_unsigned *ranges =
805 bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(
806 in_field_class);
807
808 BT_ASSERT(ranges);
809 out_field_class =
810 bt_field_class_option_with_selector_integer_unsigned_create(
811 md_maps->output_trace_class,
812 out_content_fc, out_selector_fc,
813 ranges);
814 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR) {
815 const bt_integer_range_set_signed *ranges =
816 bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(
817 in_field_class);
818
819 BT_ASSERT(ranges);
820 out_field_class =
821 bt_field_class_option_with_selector_integer_signed_create(
822 md_maps->output_trace_class,
823 out_content_fc, out_selector_fc,
824 ranges);
825 }
826 }
827
828 BT_ASSERT(out_field_class);
829 break;
830 }
831 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
832 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
833 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
834 {
835 bt_field_class *out_sel_fc = NULL;
836
837 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR ||
838 fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR) {
839 const bt_field_class *in_sel_fc;
840 const bt_field_path *sel_fp =
841 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
842 in_field_class);
843
844 BT_ASSERT(sel_fp);
845 in_sel_fc = resolve_field_path_to_field_class(sel_fp,
846 md_maps);
847 BT_ASSERT(in_sel_fc);
848 out_sel_fc = g_hash_table_lookup(
849 md_maps->field_class_map, in_sel_fc);
850 BT_ASSERT(out_sel_fc);
851 }
852
853 out_field_class = bt_field_class_variant_create(
854 md_maps->output_trace_class, out_sel_fc);
855 break;
856 }
857 default:
858 abort();
859 }
860
861 /*
862 * Add mapping from in_field_class to out_field_class. This simplifies
863 * the resolution of field paths in variant and dynamic array field
864 * classes.
865 */
866 g_hash_table_insert(md_maps->field_class_map,
867 (gpointer) in_field_class, out_field_class);
868
869 error:
870 if(out_field_class){
871 BT_COMP_LOGD("Created bare field class based on field class: in-fc-addr=%p, "
872 "out-fc-addr=%p", in_field_class, out_field_class);
873 } else {
874 BT_COMP_LOGE("Error creating output field class from input field "
875 "class: in-fc-addr=%p", in_field_class);
876 }
877
878 return out_field_class;
879 }
880
881 BT_HIDDEN
882 int copy_field_class_content_internal(
883 struct trace_ir_metadata_maps *md_maps,
884 const bt_field_class *in_field_class,
885 bt_field_class *out_field_class)
886 {
887 int ret = 0;
888
889 /*
890 * Safe to use the same value object because it's frozen at this
891 * point.
892 */
893 bt_field_class_set_user_attributes(out_field_class,
894 bt_field_class_borrow_user_attributes_const(in_field_class));
895
896 switch(bt_field_class_get_type(in_field_class)) {
897 case BT_FIELD_CLASS_TYPE_BOOL:
898 ret = field_class_bool_copy(md_maps,
899 in_field_class, out_field_class);
900 break;
901 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
902 ret = field_class_bit_array_copy(md_maps,
903 in_field_class, out_field_class);
904 break;
905 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
906 ret = field_class_unsigned_integer_copy(md_maps,
907 in_field_class, out_field_class);
908 break;
909 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
910 ret = field_class_signed_integer_copy(md_maps,
911 in_field_class, out_field_class);
912 break;
913 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
914 ret = field_class_unsigned_enumeration_copy(md_maps,
915 in_field_class, out_field_class);
916 break;
917 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
918 ret = field_class_signed_enumeration_copy(md_maps,
919 in_field_class, out_field_class);
920 break;
921 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
922 ret = field_class_single_precision_real_copy(md_maps,
923 in_field_class, out_field_class);
924 break;
925 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
926 ret = field_class_double_precision_real_copy(md_maps,
927 in_field_class, out_field_class);
928 break;
929 case BT_FIELD_CLASS_TYPE_STRING:
930 ret = field_class_string_copy(md_maps,
931 in_field_class, out_field_class);
932 break;
933 case BT_FIELD_CLASS_TYPE_STRUCTURE:
934 ret = field_class_structure_copy(md_maps,
935 in_field_class, out_field_class);
936 break;
937 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
938 ret = field_class_static_array_copy(md_maps,
939 in_field_class, out_field_class);
940 break;
941 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
942 ret = field_class_dynamic_array_copy(md_maps,
943 in_field_class, out_field_class);
944 break;
945 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
946 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
947 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
948 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
949 ret = field_class_option_copy(md_maps,
950 in_field_class, out_field_class);
951 break;
952 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
953 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
954 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
955 ret = field_class_variant_copy(md_maps,
956 in_field_class, out_field_class);
957 break;
958 default:
959 abort();
960 }
961
962 return ret;
963 }
This page took 0.049278 seconds and 3 git commands to generate.