flt.lttng-utils.debug-info: Don't copy trace class UUID to output trace class
[babeltrace.git] / plugins / lttng-utils / debug-info / trace-ir-metadata-copy.c
CommitLineData
58f6d595
FD
1/*
2 * Babeltrace - Trace IR metadata object copy
3 *
4 * Copyright (c) 2015 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_LOG_TAG "PLUGIN-LTTNG-UTILS-DEBUG-INFO-TRACE-IR-METADATA-COPY"
28#include "logging.h"
29
30#include <inttypes.h>
31#include <stdint.h>
32
33#include <babeltrace/assert-internal.h>
34
35#include "trace-ir-metadata-copy.h"
36#include "trace-ir-metadata-field-class-copy.h"
37#include "utils.h"
38
39BT_HIDDEN
40int copy_trace_class_content(const bt_trace_class *in_trace_class,
41 bt_trace_class *out_trace_class)
42{
43 int ret = 0;
44 uint64_t i, env_field_count;
45 const char *in_trace_class_name;
58f6d595
FD
46
47 BT_LOGD("Copying content of trace class: in-tc-addr=%p, out-tc-addr=%p",
48 in_trace_class, out_trace_class);
49
50 /* Use the same stream class ids as in the origin trace class. */
51 bt_trace_class_set_assigns_automatic_stream_class_id(out_trace_class,
52 BT_FALSE);
53
54 in_trace_class_name = bt_trace_class_get_name(in_trace_class);
55 if (in_trace_class_name) {
56 bt_trace_class_set_name(out_trace_class, in_trace_class_name);
57 }
58
1dd85641
FD
59 /*
60 * Do not copy the trace class UUID as it may be modified and should no
61 * longer have the same UUID.
62 */
58f6d595
FD
63
64 /*
65 * Go over all the entries in the environment section of the trace class
66 * and copy the content to the new trace class.
67 */
68 env_field_count = bt_trace_class_get_environment_entry_count(in_trace_class);
69 for (i = 0; i < env_field_count; i++) {
70 const char *value_name;
71 const bt_value *value = NULL;
72 bt_trace_class_status trace_class_status;
73
74 bt_trace_class_borrow_environment_entry_by_index_const(
75 in_trace_class, i, &value_name, &value);
76
77 BT_LOGD("Copying trace class environnement entry: "
78 "index=%" PRId64 ", value-addr=%p, value-name=%s",
79 i, value, value_name);
80
81 BT_ASSERT(value_name);
82 BT_ASSERT(value);
83
84 if (bt_value_is_integer(value)) {
85 trace_class_status =
86 bt_trace_class_set_environment_entry_integer(
87 out_trace_class, value_name,
88 bt_value_integer_get(value));
89 } else if (bt_value_is_string(value)) {
90 trace_class_status =
91 bt_trace_class_set_environment_entry_string(
92 out_trace_class, value_name,
93 bt_value_string_get(value));
94 } else {
95 abort();
96 }
97
98 if (trace_class_status != BT_TRACE_CLASS_STATUS_OK) {
99 ret = -1;
100 goto error;
101 }
102 }
103
104 BT_LOGD("Copied content of trace class: in-tc-addr=%p, out-tc-addr=%p",
105 in_trace_class, out_trace_class);
106error:
107 return ret;
108}
109
110static
111int copy_clock_class_content(const bt_clock_class *in_clock_class,
112 bt_clock_class *out_clock_class)
113{
114 bt_clock_class_status status;
115 const char *clock_class_name, *clock_class_description;
116 int64_t seconds;
117 uint64_t cycles;
118 bt_uuid in_uuid;
119 int ret = 0;
120
121 BT_LOGD("Copying content of clock class: in-cc-addr=%p, out-cc-addr=%p",
122 in_clock_class, out_clock_class);
123
124 clock_class_name = bt_clock_class_get_name(in_clock_class);
125
126 if (clock_class_name) {
127 status = bt_clock_class_set_name(out_clock_class, clock_class_name);
128 if (status != BT_CLOCK_CLASS_STATUS_OK) {
129 BT_LOGE("Error setting clock class' name cc-addr=%p, name=%p",
130 out_clock_class, clock_class_name);
131 out_clock_class = NULL;
132 ret = -1;
133 goto error;
134 }
135 }
136
137 clock_class_description = bt_clock_class_get_description(in_clock_class);
138
139 if (clock_class_description) {
140 status = bt_clock_class_set_description(out_clock_class,
141 clock_class_description);
142 if (status != BT_CLOCK_CLASS_STATUS_OK) {
143 BT_LOGE("Error setting clock class' description cc-addr=%p, "
144 "name=%p", out_clock_class, clock_class_description);
145 out_clock_class = NULL;
146 ret = -1;
147 goto error;
148 }
149 }
150
151 in_uuid = bt_clock_class_get_uuid(in_clock_class);
152 if (in_uuid) {
153 bt_clock_class_set_uuid(out_clock_class, in_uuid);
154 }
155
156 bt_clock_class_set_frequency(out_clock_class,
157 bt_clock_class_get_frequency(in_clock_class));
158 bt_clock_class_set_precision(out_clock_class,
159 bt_clock_class_get_precision(in_clock_class));
160 bt_clock_class_get_offset(in_clock_class, &seconds, &cycles);
161 bt_clock_class_set_offset(out_clock_class, seconds, cycles);
162 bt_clock_class_set_origin_is_unix_epoch(out_clock_class,
163 bt_clock_class_origin_is_unix_epoch(in_clock_class));
164
165 BT_LOGD("Copied content of clock class: in-cc-addr=%p, out-cc-addr=%p",
166 in_clock_class, out_clock_class);
167
168error:
169 return ret;
170}
171
172static
173bt_clock_class *borrow_mapped_clock_class(
174 struct trace_ir_metadata_maps *md_maps,
175 const bt_clock_class *in_clock_class)
176{
177 BT_ASSERT(md_maps);
178 BT_ASSERT(in_clock_class);
179
180 return g_hash_table_lookup(md_maps->clock_class_map,
181 (gpointer) in_clock_class);
182}
183
184static
185bt_clock_class *create_new_mapped_clock_class(
186 bt_self_component *self_comp,
187 struct trace_ir_metadata_maps *md_maps,
188 const bt_clock_class *in_clock_class)
189{
190 bt_clock_class *out_clock_class;
191 int ret;
192
193 BT_LOGD("Creating new mapped clock class: in-cc-addr=%p",
194 in_clock_class);
195
196 BT_ASSERT(md_maps);
197 BT_ASSERT(in_clock_class);
198
199 BT_ASSERT(!borrow_mapped_clock_class(md_maps, in_clock_class));
200
201 out_clock_class = bt_clock_class_create(self_comp);
202 if (!out_clock_class) {
203 BT_LOGE_STR("Cannot create clock class");
204 goto end;
205 }
206 /* If not, create a new one and add it to the mapping. */
207 ret = copy_clock_class_content(in_clock_class, out_clock_class);
208 if (ret) {
209 BT_LOGE_STR("Cannot copy clock class");
210 goto end;
211 }
212
213 g_hash_table_insert(md_maps->clock_class_map,
214 (gpointer) in_clock_class, out_clock_class);
215
216 BT_LOGD("Created new mapped clock class: in-cc-addr=%p, out-cc-addr=%p",
217 in_clock_class, out_clock_class);
218end:
219 return out_clock_class;
220}
221
222BT_HIDDEN
223int copy_stream_class_content(struct trace_ir_maps *ir_maps,
224 const bt_stream_class *in_stream_class,
225 bt_stream_class *out_stream_class)
226{
227 struct trace_ir_metadata_maps *md_maps;
228 const bt_clock_class *in_clock_class;
229 bt_clock_class *out_clock_class;
230 const bt_field_class *in_packet_context_fc, *in_common_context_fc;
231 bt_field_class *out_packet_context_fc, *out_common_context_fc;
232 bt_stream_class_status status;
233 const char *in_name;
234 int ret = 0;
235
236 BT_LOGD("Copying content of stream class: in-sc-addr=%p, out-sc-addr=%p",
237 in_stream_class, out_stream_class);
238
239 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps, in_stream_class);
240 in_clock_class = bt_stream_class_borrow_default_clock_class_const(
241 in_stream_class);
242
243 if (in_clock_class) {
244 /* Copy the clock class. */
245 out_clock_class =
246 borrow_mapped_clock_class(md_maps, in_clock_class);
247 if (!out_clock_class) {
248 out_clock_class = create_new_mapped_clock_class(
249 ir_maps->self_comp, md_maps,
250 in_clock_class);
251 }
252 bt_stream_class_set_default_clock_class(out_stream_class,
253 out_clock_class);
254
255 }
256
257 in_name = bt_stream_class_get_name(in_stream_class);
258 if (in_name) {
259 status = bt_stream_class_set_name(out_stream_class, in_name);
260 if (status != BT_STREAM_CLASS_STATUS_OK) {
261 BT_LOGE("Error set stream class name: out-sc-addr=%p, "
262 "name=%s", out_stream_class, in_name);
263 ret = -1;
264 goto error;
265 }
266 }
267
268 bt_stream_class_set_assigns_automatic_stream_id(out_stream_class,
269 BT_FALSE);
270 bt_stream_class_set_assigns_automatic_event_class_id(out_stream_class,
271 BT_FALSE);
272
273 /*
274 * Add the input packet context field class to the context to
275 * resolution in the further steps.
276 */
277 in_packet_context_fc =
278 bt_stream_class_borrow_packet_context_field_class_const(
279 in_stream_class);
280 md_maps->fc_resolving_ctx->packet_context =
281 in_packet_context_fc;
282
283 if (in_packet_context_fc) {
284 /* Copy packet context. */
285 out_packet_context_fc = create_field_class_copy(
286 md_maps, in_packet_context_fc);
287
288 ret = copy_field_class_content(md_maps,
289 in_packet_context_fc, out_packet_context_fc);
290 if (ret) {
291 ret = -1;
292 goto error;
293 }
294
295 status = bt_stream_class_set_packet_context_field_class(
296 out_stream_class, out_packet_context_fc);
297 if (status != BT_STREAM_CLASS_STATUS_OK) {
298 BT_LOGE("Error setting stream class' packet context "
299 "field class: sc-addr=%p, packet-fc-addr=%p",
300 out_stream_class, out_packet_context_fc);
301 ret = -1;
302 goto error;
303 }
304 }
305
306 /*
307 * Add the input common context field class to the context to
308 * resolution in the further steps.
309 */
310 in_common_context_fc =
311 bt_stream_class_borrow_event_common_context_field_class_const(
312 in_stream_class);
313 md_maps->fc_resolving_ctx->event_common_context =
314 in_common_context_fc;
315
316 if (in_common_context_fc) {
317 /* Copy common context. */
318 /* TODO: I find it a bit awkward to have this special function
319 * here to add the debug-info field class. I would like to
320 * abstract that.*/
321 out_common_context_fc = create_field_class_copy(
322 md_maps, in_common_context_fc);
323
324 ret = copy_event_common_context_field_class_content(
325 md_maps, ir_maps->debug_info_field_class_name,
326 in_common_context_fc, out_common_context_fc);
327 if (ret) {
328 goto error;
329 }
330
331 status = bt_stream_class_set_event_common_context_field_class(
332 out_stream_class, out_common_context_fc);
333 if (status != BT_STREAM_CLASS_STATUS_OK) {
334 BT_LOGE("Error setting stream class' packet context "
335 "field class: sc-addr=%p, packet-fc-addr=%p",
336 out_stream_class, out_common_context_fc);
337 ret = -1;
338 goto error;
339 }
340 }
341
342 /* Set packet snapshot boolean fields. */
343 BT_LOGD("Copied content of stream class: in-sc-addr=%p, out-sc-addr=%p",
344 in_stream_class, out_stream_class);
345error:
346 return ret;
347}
348
349BT_HIDDEN
350int copy_event_class_content(struct trace_ir_maps *ir_maps,
351 const bt_event_class *in_event_class,
352 bt_event_class *out_event_class)
353{
354 struct trace_ir_metadata_maps *md_maps;
355 const char *in_event_class_name, *in_emf_uri;
356 bt_property_availability prop_avail;
357 bt_event_class_log_level log_level;
358 bt_event_class_status status;
359 bt_field_class *out_specific_context_fc, *out_payload_fc;
360 const bt_field_class *in_event_specific_context, *in_event_payload;
361 int ret = 0;
362
363 BT_LOGD("Copying content of event class: in-ec-addr=%p, out-ec-addr=%p",
364 in_event_class, out_event_class);
365
366 /* Copy event class name. */
367 in_event_class_name = bt_event_class_get_name(in_event_class);
368 if (in_event_class_name) {
369 status = bt_event_class_set_name(out_event_class, in_event_class_name);
370 if (status != BT_EVENT_CLASS_STATUS_OK) {
371 BT_LOGE("Error setting event class' name: ec-addr=%p, "
372 "name=%s", out_event_class, in_event_class_name);
373 ret = -1;
374 goto error;
375 }
376 }
377
378 /* Copy event class loglevel. */
379 prop_avail = bt_event_class_get_log_level(in_event_class, &log_level);
380 if (prop_avail == BT_PROPERTY_AVAILABILITY_AVAILABLE) {
381 bt_event_class_set_log_level(out_event_class,
382 log_level);
383 }
384
385 /* Copy event class emf uri. */
386 in_emf_uri = bt_event_class_get_emf_uri(in_event_class);
387 if (in_emf_uri) {
388 status = bt_event_class_set_emf_uri(out_event_class, in_emf_uri);
389 if (status != BT_EVENT_CLASS_STATUS_OK) {
390 BT_LOGE("Error setting event class' emf uri: ec-addr=%p, "
391 "emf uri=%s", out_event_class, in_emf_uri);
392 ret = -1;
393 goto error;
394 }
395 }
396
397 md_maps = borrow_metadata_maps_from_input_event_class(ir_maps, in_event_class);
398 /*
399 * Add the input event class' specific ctx to te
400 * context.
401 */
402 in_event_specific_context =
403 bt_event_class_borrow_specific_context_field_class_const(
404 in_event_class);
405
406 md_maps->fc_resolving_ctx->event_specific_context =
407 in_event_specific_context;
408
409 if (in_event_specific_context) {
410 /* Copy the specific context of this event class. */
411 out_specific_context_fc = create_field_class_copy(md_maps,
412 in_event_specific_context);
413
414 copy_field_class_content(md_maps,
415 in_event_specific_context, out_specific_context_fc);
416 if (ret) {
417 goto error;
418 }
419 /*
420 * Add the output specific context to the output event
421 * class.
422 */
423 status = bt_event_class_set_specific_context_field_class(
424 out_event_class, out_specific_context_fc);
425 if (status != BT_EVENT_CLASS_STATUS_OK) {
426 BT_LOGE("Error setting event class' specific context "
427 "field class: ec-addr=%p, ctx-fc-addr=%p",
428 out_event_class, out_specific_context_fc);
429 ret = -1;
430 goto error;
431 }
432 }
433
434 /*
435 * Add the input event class' payload field class to
436 * the context.
437 */
438 in_event_payload = bt_event_class_borrow_payload_field_class_const(
439 in_event_class);
440
441 md_maps->fc_resolving_ctx->event_payload = in_event_payload;
442
443 if (in_event_payload) {
444 /* Copy the payload of this event class. */
445 out_payload_fc = create_field_class_copy(md_maps,
446 in_event_payload);
447 copy_field_class_content(md_maps,
448 in_event_payload, out_payload_fc);
449 if (ret) {
450 goto error;
451 }
452
453 /* Add the output payload to the output event class. */
454 status = bt_event_class_set_payload_field_class(
455 out_event_class, out_payload_fc);
456 if (status != BT_EVENT_CLASS_STATUS_OK) {
457 BT_LOGE("Error setting event class' payload "
458 "field class: ec-addr=%p, payload-fc-addr=%p",
459 out_event_class, out_payload_fc);
460 ret = -1;
461 goto error;
462 }
463 }
464
465 BT_LOGD("Copied content of event class: in-ec-addr=%p, out-ec-addr=%p",
466 in_event_class, out_event_class);
467error:
468 return ret;
469}
470
471BT_HIDDEN
472int copy_event_common_context_field_class_content(
473 struct trace_ir_metadata_maps *md_maps,
474 const char *debug_info_fc_name,
475 const bt_field_class *in_field_class,
476 bt_field_class *out_field_class)
477{
478 bt_field_class_status status;
479 bt_field_class *debug_field_class = NULL, *bin_field_class = NULL,
480 *func_field_class = NULL, *src_field_class = NULL;
481 int ret = 0;
482
483 BT_LOGD("Copying content of event common context field class: "
484 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
485
486 /* Copy the content of the input common context. */
487 ret = copy_field_class_content(md_maps, in_field_class, out_field_class);
488 if (ret) {
489 goto error;
490 }
491
492 /*
493 * If this event common context has the necessary fields to compute the
494 * debug information append the debug-info field class to the event
495 * common context.
496 */
497 if (is_event_common_ctx_dbg_info_compatible(in_field_class, debug_info_fc_name)) {
498 /*
499 * The struct field and 3 sub-fields are not stored in the
500 * field class map because they don't have input equivalent.
501 * We need to put our reference each of these field classes
502 * once they are added to their respective containing field
503 * classes.
504 */
505 debug_field_class = bt_field_class_structure_create(
506 md_maps->output_trace_class);
507 if (!debug_field_class) {
508 BT_LOGE_STR("Failed to create debug_info structure.");
509 ret = -1;
510 goto error;
511 }
512
513 bin_field_class = bt_field_class_string_create(
514 md_maps->output_trace_class);
515 if (!bin_field_class) {
516 BT_LOGE_STR("Failed to create string for field=bin.");
517 ret = -1;
518 goto error;
519 }
520
521 func_field_class = bt_field_class_string_create(
522 md_maps->output_trace_class);
523 if (!func_field_class) {
524 BT_LOGE_STR("Failed to create string for field=func.");
525 ret = -1;
526 goto error;
527 }
528
529 src_field_class = bt_field_class_string_create(
530 md_maps->output_trace_class);
531 if (!src_field_class) {
532 BT_LOGE_STR("Failed to create string for field=src.");
533 ret = -1;
534 goto error;
535 }
536
537 status = bt_field_class_structure_append_member(
538 debug_field_class, "bin", bin_field_class);
539 if (status != BT_FIELD_CLASS_STATUS_OK) {
540 BT_LOGE_STR("Failed to add a field to debug_info "
541 "struct: field=bin.");
542 ret = -1;
543 goto error;
544 }
545 BT_FIELD_CLASS_PUT_REF_AND_RESET(bin_field_class);
546
547 status = bt_field_class_structure_append_member(
548 debug_field_class, "func", func_field_class);
549 if (status != BT_FIELD_CLASS_STATUS_OK) {
550 BT_LOGE_STR("Failed to add a field to debug_info "
551 "struct: field=func.");
552 ret = -1;
553 goto error;
554 }
555 BT_FIELD_CLASS_PUT_REF_AND_RESET(func_field_class);
556
557 status = bt_field_class_structure_append_member(
558 debug_field_class, "src", src_field_class);
559 if (status != BT_FIELD_CLASS_STATUS_OK) {
560 BT_LOGE_STR("Failed to add a field to debug_info "
561 "struct: field=src.");
562 ret = -1;
563 goto error;
564 }
565 BT_FIELD_CLASS_PUT_REF_AND_RESET(src_field_class);
566
567 /*Add the filled debug-info field class to the common context. */
568 status = bt_field_class_structure_append_member(out_field_class,
569 debug_info_fc_name,
570 debug_field_class);
571 if (status != BT_FIELD_CLASS_STATUS_OK) {
572 BT_LOGE_STR("Failed to add debug_info field to "
573 "event common context.");
574 ret = -1;
575 goto error;
576 }
577 BT_FIELD_CLASS_PUT_REF_AND_RESET(debug_field_class);
578 }
579 BT_LOGD("Copied content of event common context field class: "
580 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
581 goto end;
582
583error:
584 if (debug_field_class) {
585 bt_field_class_put_ref(debug_field_class);
586 }
587 if (bin_field_class) {
588 bt_field_class_put_ref(bin_field_class);
589 }
590 if (func_field_class) {
591 bt_field_class_put_ref(func_field_class);
592 }
593 if (src_field_class) {
594 bt_field_class_put_ref(src_field_class);
595 }
596end:
597 return ret;
598}
599
600BT_HIDDEN
601bt_field_class *create_field_class_copy(struct trace_ir_metadata_maps *md_maps,
602 const bt_field_class *in_field_class)
603{
604 return create_field_class_copy_internal(md_maps, in_field_class);
605}
606
607BT_HIDDEN
608int copy_field_class_content(struct trace_ir_metadata_maps *md_maps,
609 const bt_field_class *in_field_class,
610 bt_field_class *out_field_class)
611{
612 return copy_field_class_content_internal(md_maps, in_field_class,
613 out_field_class);
614}
This page took 0.045464 seconds and 4 git commands to generate.