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