MI: implement all objects related to trigger machine interface
[lttng-tools.git] / src / common / kernel-probe.c
1 /*
2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include "lttng/lttng-error.h"
9 #include <assert.h>
10 #include <common/error.h>
11 #include <common/hashtable/hashtable.h>
12 #include <common/hashtable/utils.h>
13 #include <common/macros.h>
14 #include <common/mi-lttng.h>
15 #include <common/payload-view.h>
16 #include <common/payload.h>
17 #include <fcntl.h>
18 #include <lttng/constant.h>
19 #include <lttng/kernel-probe-internal.h>
20 #include <lttng/kernel-probe.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <sys/unistd.h>
24
25 static
26 int lttng_kernel_probe_location_address_serialize(
27 const struct lttng_kernel_probe_location *location,
28 struct lttng_payload *payload);
29
30 static
31 int lttng_kernel_probe_location_symbol_serialize(
32 const struct lttng_kernel_probe_location *location,
33 struct lttng_payload *payload);
34
35 static
36 bool lttng_kernel_probe_location_address_is_equal(
37 const struct lttng_kernel_probe_location *a,
38 const struct lttng_kernel_probe_location *b);
39
40 static
41 bool lttng_kernel_probe_location_symbol_is_equal(
42 const struct lttng_kernel_probe_location *a,
43 const struct lttng_kernel_probe_location *b);
44
45 static
46 unsigned long lttng_kernel_probe_location_address_hash(
47 const struct lttng_kernel_probe_location *location);
48
49 static
50 unsigned long lttng_kernel_probe_location_symbol_hash(
51 const struct lttng_kernel_probe_location *location);
52
53 static
54 enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
55 const struct lttng_kernel_probe_location *location,
56 struct mi_writer *writer);
57
58 static
59 enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
60 const struct lttng_kernel_probe_location *location,
61 struct mi_writer *writer);
62
63 enum lttng_kernel_probe_location_type lttng_kernel_probe_location_get_type(
64 const struct lttng_kernel_probe_location *location)
65 {
66 return location ? location->type :
67 LTTNG_KERNEL_PROBE_LOCATION_TYPE_UNKNOWN;
68 }
69
70 static
71 void lttng_kernel_probe_location_address_destroy(
72 struct lttng_kernel_probe_location *location)
73 {
74 assert(location);
75 free(location);
76 }
77
78 static
79 void lttng_kernel_probe_location_symbol_destroy(
80 struct lttng_kernel_probe_location *location)
81 {
82 struct lttng_kernel_probe_location_symbol *location_symbol = NULL;
83
84 assert(location);
85
86 location_symbol = container_of(location,
87 struct lttng_kernel_probe_location_symbol,
88 parent);
89
90 assert(location_symbol);
91
92 free(location_symbol->symbol_name);
93 free(location);
94 }
95
96 void lttng_kernel_probe_location_destroy(
97 struct lttng_kernel_probe_location *location)
98 {
99 if (!location) {
100 return;
101 }
102
103 switch (location->type) {
104 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
105 lttng_kernel_probe_location_address_destroy(location);
106 break;
107 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
108 lttng_kernel_probe_location_symbol_destroy(location);
109 break;
110 default:
111 abort();
112 }
113 }
114
115 struct lttng_kernel_probe_location *
116 lttng_kernel_probe_location_address_create(uint64_t address)
117 {
118 struct lttng_kernel_probe_location *ret = NULL;
119 struct lttng_kernel_probe_location_address *location;
120
121 location = zmalloc(sizeof(*location));
122 if (!location) {
123 PERROR("Error allocating userspace probe location.");
124 goto end;
125 }
126
127 location->address = address;
128
129 ret = &location->parent;
130 ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS;
131 ret->equal = lttng_kernel_probe_location_address_is_equal;
132 ret->serialize = lttng_kernel_probe_location_address_serialize;
133 ret->hash = lttng_kernel_probe_location_address_hash;
134 ret->mi_serialize = lttng_kernel_probe_location_address_mi_serialize;
135
136 end:
137 return ret;
138 }
139
140 struct lttng_kernel_probe_location *
141 lttng_kernel_probe_location_symbol_create(const char *symbol_name,
142 uint64_t offset)
143 {
144 char *symbol_name_copy = NULL;
145 struct lttng_kernel_probe_location *ret = NULL;
146 struct lttng_kernel_probe_location_symbol *location;
147
148 if (!symbol_name || strlen(symbol_name) >= LTTNG_SYMBOL_NAME_LEN) {
149 goto error;
150 }
151
152 symbol_name_copy = strdup(symbol_name);
153 if (!symbol_name_copy) {
154 PERROR("Failed to copy symbol name '%s'", symbol_name);
155 goto error;
156 }
157
158 location = zmalloc(sizeof(*location));
159 if (!location) {
160 PERROR("Failed to allocate kernel symbol probe location");
161 goto error;
162 }
163
164 location->symbol_name = symbol_name_copy;
165 location->offset = offset;
166
167 ret = &location->parent;
168 ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET;
169 ret->equal = lttng_kernel_probe_location_symbol_is_equal;
170 ret->serialize = lttng_kernel_probe_location_symbol_serialize;
171 ret->hash = lttng_kernel_probe_location_symbol_hash;
172 ret->mi_serialize = lttng_kernel_probe_location_symbol_mi_serialize;
173 goto end;
174
175 error:
176 free(symbol_name_copy);
177 end:
178 return ret;
179 }
180
181 enum lttng_kernel_probe_location_status
182 lttng_kernel_probe_location_address_get_address(
183 const struct lttng_kernel_probe_location *location,
184 uint64_t *offset)
185 {
186 enum lttng_kernel_probe_location_status ret =
187 LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK;
188 struct lttng_kernel_probe_location_address *address_location;
189
190 assert(offset);
191
192 if (!location || lttng_kernel_probe_location_get_type(location) !=
193 LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS) {
194 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
195 ret = LTTNG_KERNEL_PROBE_LOCATION_STATUS_INVALID;
196 goto end;
197 }
198
199 address_location = container_of(location,
200 struct lttng_kernel_probe_location_address, parent);
201 *offset = address_location->address;
202 end:
203 return ret;
204 }
205
206 const char *lttng_kernel_probe_location_symbol_get_name(
207 const struct lttng_kernel_probe_location *location)
208 {
209 const char *ret = NULL;
210 struct lttng_kernel_probe_location_symbol *symbol_location;
211
212 if (!location || lttng_kernel_probe_location_get_type(location) !=
213 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET) {
214 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
215 goto end;
216 }
217
218 symbol_location = container_of(location,
219 struct lttng_kernel_probe_location_symbol, parent);
220 ret = symbol_location->symbol_name;
221 end:
222 return ret;
223 }
224
225 enum lttng_kernel_probe_location_status
226 lttng_kernel_probe_location_symbol_get_offset(
227 const struct lttng_kernel_probe_location *location,
228 uint64_t *offset)
229 {
230 enum lttng_kernel_probe_location_status ret =
231 LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK;
232 struct lttng_kernel_probe_location_symbol *symbol_location;
233
234 assert(offset);
235
236 if (!location || lttng_kernel_probe_location_get_type(location) !=
237 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET) {
238 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
239 ret = LTTNG_KERNEL_PROBE_LOCATION_STATUS_INVALID;
240 goto end;
241 }
242
243 symbol_location = container_of(location,
244 struct lttng_kernel_probe_location_symbol, parent);
245 *offset = symbol_location->offset;
246 end:
247 return ret;
248 }
249
250 static
251 int lttng_kernel_probe_location_symbol_serialize(
252 const struct lttng_kernel_probe_location *location,
253 struct lttng_payload *payload)
254 {
255 int ret;
256 size_t symbol_name_len;
257 size_t original_payload_size;
258 struct lttng_kernel_probe_location_symbol *location_symbol;
259 struct lttng_kernel_probe_location_symbol_comm location_symbol_comm;
260
261 if (!location || !payload) {
262 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
263 ret = -LTTNG_ERR_INVALID;
264 goto end;
265 }
266
267 assert(lttng_kernel_probe_location_get_type(location) ==
268 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
269
270 original_payload_size = payload->buffer.size;
271 location_symbol = container_of(location,
272 struct lttng_kernel_probe_location_symbol, parent);
273
274 if (!location_symbol->symbol_name) {
275 ret = -LTTNG_ERR_INVALID;
276 goto end;
277 }
278
279 symbol_name_len = strlen(location_symbol->symbol_name);
280 if (symbol_name_len == 0) {
281 ret = -LTTNG_ERR_INVALID;
282 goto end;
283 }
284
285 location_symbol_comm.symbol_len = symbol_name_len + 1;
286 location_symbol_comm.offset = location_symbol->offset;
287
288 ret = lttng_dynamic_buffer_append(&payload->buffer,
289 &location_symbol_comm, sizeof(location_symbol_comm));
290 if (ret) {
291 ret = -LTTNG_ERR_INVALID;
292 goto end;
293 }
294
295 ret = lttng_dynamic_buffer_append(&payload->buffer,
296 location_symbol->symbol_name,
297 location_symbol_comm.symbol_len);
298 if (ret) {
299 ret = -LTTNG_ERR_INVALID;
300 goto end;
301 }
302
303 ret = (int) (payload->buffer.size - original_payload_size);
304 end:
305 return ret;
306 }
307
308 static
309 int lttng_kernel_probe_location_address_serialize(
310 const struct lttng_kernel_probe_location *location,
311 struct lttng_payload *payload)
312 {
313 int ret;
314 size_t original_payload_size;
315 struct lttng_kernel_probe_location_address *location_address;
316 struct lttng_kernel_probe_location_address_comm location_address_comm;
317
318 assert(location);
319 assert(lttng_kernel_probe_location_get_type(location) ==
320 LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
321
322 original_payload_size = payload->buffer.size;
323 location_address = container_of(location,
324 struct lttng_kernel_probe_location_address,
325 parent);
326
327 location_address_comm.address = location_address->address;
328
329 ret = lttng_dynamic_buffer_append(&payload->buffer,
330 &location_address_comm,
331 sizeof(location_address_comm));
332 if (ret) {
333 ret = -LTTNG_ERR_INVALID;
334 goto end;
335 }
336
337 ret = (int) (payload->buffer.size - original_payload_size);
338 end:
339 return ret;
340 }
341
342 LTTNG_HIDDEN
343 int lttng_kernel_probe_location_serialize(
344 const struct lttng_kernel_probe_location *location,
345 struct lttng_payload *payload)
346 {
347 int ret;
348 size_t original_payload_size;
349 struct lttng_kernel_probe_location_comm location_generic_comm = {};
350
351 if (!location || !payload) {
352 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
353 ret = -LTTNG_ERR_INVALID;
354 goto end;
355 }
356
357 original_payload_size = payload->buffer.size;
358 location_generic_comm.type = (int8_t) location->type;
359 ret = lttng_dynamic_buffer_append(&payload->buffer,
360 &location_generic_comm,
361 sizeof(location_generic_comm));
362 if (ret) {
363 goto end;
364 }
365
366 ret = location->serialize(location, payload);
367 if (ret < 0) {
368 goto end;
369 }
370
371 ret = (int) (payload->buffer.size - original_payload_size);
372 end:
373 return ret;
374 }
375
376 static
377 int lttng_kernel_probe_location_symbol_create_from_payload(
378 struct lttng_payload_view *view,
379 struct lttng_kernel_probe_location **location)
380 {
381 struct lttng_kernel_probe_location_symbol_comm *location_symbol_comm;
382 const char *symbol_name_src;
383 ssize_t ret = 0;
384 size_t expected_size;
385
386 assert(location);
387
388 if (view->buffer.size < sizeof(*location_symbol_comm)) {
389 ret = -LTTNG_ERR_INVALID;
390 goto end;
391 }
392
393 location_symbol_comm =
394 (typeof(location_symbol_comm)) view->buffer.data;
395
396 expected_size = sizeof(*location_symbol_comm) +
397 location_symbol_comm->symbol_len;
398
399 if (view->buffer.size < expected_size) {
400 ret = -LTTNG_ERR_INVALID;
401 goto end;
402 }
403
404 symbol_name_src = view->buffer.data + sizeof(*location_symbol_comm);
405
406 if (!lttng_buffer_view_contains_string(&view->buffer, symbol_name_src,
407 location_symbol_comm->symbol_len)) {
408 ret = -LTTNG_ERR_INVALID;
409 goto end;
410 }
411
412 *location = lttng_kernel_probe_location_symbol_create(
413 symbol_name_src, location_symbol_comm->offset);
414 if (!(*location)) {
415 ret = -LTTNG_ERR_INVALID;
416 goto end;
417 }
418
419 ret = (ssize_t) expected_size;
420 end:
421 return ret;
422 }
423
424 static
425 ssize_t lttng_kernel_probe_location_address_create_from_payload(
426 struct lttng_payload_view *view,
427 struct lttng_kernel_probe_location **location)
428 {
429 struct lttng_kernel_probe_location_address_comm *location_address_comm;
430 ssize_t ret = 0;
431 size_t expected_size;
432
433 assert(location);
434
435 expected_size = sizeof(*location_address_comm);
436
437 if (view->buffer.size < expected_size) {
438 ret = -LTTNG_ERR_INVALID;
439 goto end;
440 }
441
442 location_address_comm =
443 (typeof(location_address_comm)) view->buffer.data;
444
445 *location = lttng_kernel_probe_location_address_create(location_address_comm->address);
446 if (!(*location)) {
447 ret = -LTTNG_ERR_INVALID;
448 goto end;
449 }
450
451 ret = (size_t) expected_size;
452 end:
453 return ret;
454 }
455
456 LTTNG_HIDDEN
457 ssize_t lttng_kernel_probe_location_create_from_payload(
458 struct lttng_payload_view *view,
459 struct lttng_kernel_probe_location **location)
460 {
461 enum lttng_kernel_probe_location_type type;
462 ssize_t consumed = 0;
463 ssize_t ret;
464 const struct lttng_kernel_probe_location_comm *probe_location_comm;
465 const struct lttng_payload_view probe_location_comm_view =
466 lttng_payload_view_from_view(
467 view, 0, sizeof(*probe_location_comm));
468
469 assert(view);
470 assert(location);
471
472 if (!lttng_payload_view_is_valid(&probe_location_comm_view)) {
473 ret = -LTTNG_ERR_INVALID;
474 goto end;
475 }
476
477 probe_location_comm = (typeof(probe_location_comm)) probe_location_comm_view.buffer.data;
478 type = (enum lttng_kernel_probe_location_type) probe_location_comm->type;
479 consumed += sizeof(*probe_location_comm);
480
481 switch (type) {
482 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
483 {
484 struct lttng_payload_view location_view =
485 lttng_payload_view_from_view(
486 view, consumed, -1);
487
488 ret = lttng_kernel_probe_location_symbol_create_from_payload(
489 &location_view, location);
490 break;
491 }
492 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
493 {
494 struct lttng_payload_view location_view =
495 lttng_payload_view_from_view(view, consumed, -1);
496
497 ret = lttng_kernel_probe_location_address_create_from_payload(
498 &location_view, location);
499 break;
500 }
501 default:
502 ret = -LTTNG_ERR_INVALID;
503 break;
504 }
505
506 if (ret < 0) {
507 ret = -LTTNG_ERR_INVALID;
508 goto end;
509 }
510
511 ret += consumed;
512
513 end:
514 return ret;
515 }
516
517 static
518 unsigned long lttng_kernel_probe_location_address_hash(
519 const struct lttng_kernel_probe_location *location)
520 {
521 unsigned long hash = hash_key_ulong(
522 (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS,
523 lttng_ht_seed);
524 struct lttng_kernel_probe_location_address *address_location =
525 container_of(location, typeof(*address_location),
526 parent);
527
528 hash ^= hash_key_u64(&address_location->address, lttng_ht_seed);
529
530 return hash;
531 }
532
533 static
534 bool lttng_kernel_probe_location_address_is_equal(
535 const struct lttng_kernel_probe_location *_a,
536 const struct lttng_kernel_probe_location *_b)
537 {
538 bool is_equal = false;
539 struct lttng_kernel_probe_location_address *a, *b;
540
541 a = container_of(_a, struct lttng_kernel_probe_location_address,
542 parent);
543 b = container_of(_b, struct lttng_kernel_probe_location_address,
544 parent);
545
546 if (a->address != b->address) {
547 goto end;
548 }
549
550 is_equal = true;
551
552 end:
553 return is_equal;
554 }
555
556 static
557 unsigned long lttng_kernel_probe_location_symbol_hash(
558 const struct lttng_kernel_probe_location *location)
559 {
560 unsigned long hash = hash_key_ulong(
561 (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET,
562 lttng_ht_seed);
563 struct lttng_kernel_probe_location_symbol *symbol_location =
564 container_of(location, typeof(*symbol_location),
565 parent);
566
567 hash ^= hash_key_str(symbol_location->symbol_name, lttng_ht_seed);
568 hash ^= hash_key_u64(&symbol_location->offset, lttng_ht_seed);
569
570 return hash;
571 }
572
573 static
574 bool lttng_kernel_probe_location_symbol_is_equal(
575 const struct lttng_kernel_probe_location *_a,
576 const struct lttng_kernel_probe_location *_b)
577 {
578 bool is_equal = false;
579 struct lttng_kernel_probe_location_symbol *a, *b;
580
581 a = container_of(_a, struct lttng_kernel_probe_location_symbol,
582 parent);
583 b = container_of(_b, struct lttng_kernel_probe_location_symbol,
584 parent);
585
586 assert(a->symbol_name);
587 assert(b->symbol_name);
588 if (strcmp(a->symbol_name, b->symbol_name)) {
589 goto end;
590 }
591
592 if (a->offset != b->offset) {
593 goto end;
594 }
595
596 is_equal = true;
597
598 end:
599 return is_equal;
600 }
601
602 LTTNG_HIDDEN
603 bool lttng_kernel_probe_location_is_equal(
604 const struct lttng_kernel_probe_location *a,
605 const struct lttng_kernel_probe_location *b)
606 {
607 bool is_equal = false;
608
609 if (!a || !b) {
610 goto end;
611 }
612
613 if (a == b) {
614 is_equal = true;
615 goto end;
616 }
617
618 if (a->type != b->type) {
619 goto end;
620 }
621
622 is_equal = a->equal ? a->equal(a, b) : true;
623 end:
624 return is_equal;
625 }
626
627 static struct lttng_kernel_probe_location *
628 lttng_kernel_probe_location_symbol_copy(
629 const struct lttng_kernel_probe_location *location)
630 {
631 struct lttng_kernel_probe_location *new_location = NULL;
632 struct lttng_kernel_probe_location_symbol *symbol_location;
633 enum lttng_kernel_probe_location_status status;
634 const char *symbol_name = NULL;
635 uint64_t offset;
636
637 assert(location);
638 assert(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
639 symbol_location = container_of(
640 location, typeof(*symbol_location), parent);
641
642 /* Get probe location offset */
643 status = lttng_kernel_probe_location_symbol_get_offset(location, &offset);
644 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
645 ERR("Get kernel probe location offset failed.");
646 goto error;
647 }
648
649 symbol_name = lttng_kernel_probe_location_symbol_get_name(location);
650 if (!symbol_name) {
651 ERR("Kernel probe symbol name is NULL.");
652 goto error;
653 }
654
655 /* Create the probe_location */
656 new_location = lttng_kernel_probe_location_symbol_create(
657 symbol_name, offset);
658
659 goto end;
660
661 error:
662 new_location = NULL;
663 end:
664 return new_location;
665 }
666 static struct lttng_kernel_probe_location *
667 lttng_kernel_probe_location_address_copy(
668 const struct lttng_kernel_probe_location *location)
669 {
670 struct lttng_kernel_probe_location *new_location = NULL;
671 struct lttng_kernel_probe_location_address *address_location;
672 enum lttng_kernel_probe_location_status status;
673 uint64_t address;
674
675 assert(location);
676 assert(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
677 address_location = container_of(
678 location, typeof(*address_location), parent);
679
680
681 /* Get probe location fields */
682 status = lttng_kernel_probe_location_address_get_address(location, &address);
683 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
684 ERR("Get kernel probe address failed.");
685 goto error;
686 }
687
688 /* Create the probe_location */
689 new_location = lttng_kernel_probe_location_address_create(address);
690
691 goto end;
692
693 error:
694 new_location = NULL;
695 end:
696 return new_location;
697 }
698
699 LTTNG_HIDDEN
700 struct lttng_kernel_probe_location *lttng_kernel_probe_location_copy(
701 const struct lttng_kernel_probe_location *location)
702 {
703 struct lttng_kernel_probe_location *new_location = NULL;
704 enum lttng_kernel_probe_location_type type;
705
706 if (!location) {
707 goto err;
708 }
709
710 type = lttng_kernel_probe_location_get_type(location);
711 switch (type) {
712 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
713 new_location =
714 lttng_kernel_probe_location_address_copy(location);
715 if (!new_location) {
716 goto err;
717 }
718 break;
719 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
720 new_location =
721 lttng_kernel_probe_location_symbol_copy(location);
722 if (!new_location) {
723 goto err;
724 }
725 break;
726 default:
727 new_location = NULL;
728 goto err;
729 }
730 err:
731 return new_location;
732 }
733
734 LTTNG_HIDDEN
735 unsigned long lttng_kernel_probe_location_hash(
736 const struct lttng_kernel_probe_location *location)
737 {
738 return location->hash(location);
739 }
740
741 static
742 enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
743 const struct lttng_kernel_probe_location *location,
744 struct mi_writer *writer)
745 {
746 int ret;
747 enum lttng_error_code ret_code;
748 enum lttng_kernel_probe_location_status status;
749 uint64_t address;
750
751 assert(location);
752 assert(writer);
753 assert(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
754
755 status = lttng_kernel_probe_location_address_get_address(
756 location, &address);
757 assert(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
758
759 /* Open kernel probe location address element. */
760 ret = mi_lttng_writer_open_element(
761 writer, mi_lttng_element_kernel_probe_location_address);
762 if (ret) {
763 goto mi_error;
764 }
765
766 ret = mi_lttng_writer_write_element_unsigned_int(writer,
767 mi_lttng_element_kernel_probe_location_address_address,
768 address);
769 if (ret) {
770 goto mi_error;
771 }
772
773 /* Close kernel probe location address element. */
774 ret = mi_lttng_writer_close_element(writer);
775 if (ret) {
776 goto mi_error;
777 }
778
779 ret_code = LTTNG_OK;
780 goto end;
781
782 mi_error:
783 ret_code = LTTNG_ERR_MI_IO_FAIL;
784 end:
785 return ret_code;
786 }
787
788 static
789 enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
790 const struct lttng_kernel_probe_location *location,
791 struct mi_writer *writer)
792 {
793 int ret;
794 enum lttng_error_code ret_code;
795 enum lttng_kernel_probe_location_status status;
796 const char *name = NULL;
797 uint64_t offset;
798
799 assert(location);
800 assert(writer);
801 assert(location->type ==
802 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
803
804 name = lttng_kernel_probe_location_symbol_get_name(location);
805 assert(name);
806
807 status = lttng_kernel_probe_location_symbol_get_offset(
808 location, &offset);
809 assert(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
810
811 /* Open kernel probe location symbol offset element. */
812 ret = mi_lttng_writer_open_element(writer,
813 mi_lttng_element_kernel_probe_location_symbol_offset);
814 if (ret) {
815 goto mi_error;
816 }
817
818 /* Name. */
819 ret = mi_lttng_writer_write_element_string(writer,
820 mi_lttng_element_kernel_probe_location_symbol_offset_name,
821 name);
822 if (ret) {
823 goto mi_error;
824 }
825
826 /* Offset. */
827 ret = mi_lttng_writer_write_element_unsigned_int(writer,
828 mi_lttng_element_kernel_probe_location_symbol_offset_offset,
829 offset);
830 if (ret) {
831 goto mi_error;
832 }
833
834 /* Close kernel probe location symbol offset element. */
835 ret = mi_lttng_writer_close_element(writer);
836 if (ret) {
837 goto mi_error;
838 }
839
840 ret_code = LTTNG_OK;
841 goto end;
842
843 mi_error:
844 ret_code = LTTNG_ERR_MI_IO_FAIL;
845 end:
846 return ret_code;
847 }
848
849 LTTNG_HIDDEN
850 enum lttng_error_code lttng_kernel_probe_location_mi_serialize(
851 const struct lttng_kernel_probe_location *location,
852 struct mi_writer *writer)
853 {
854 int ret;
855 enum lttng_error_code ret_code;
856
857 assert(location);
858 assert(writer);
859
860 /* Open kernel probe location element. */
861 ret = mi_lttng_writer_open_element(
862 writer, mi_lttng_element_kernel_probe_location);
863 if (ret) {
864 goto mi_error;
865 }
866
867 /* Serialize the location sub type. */
868 ret_code = location->mi_serialize(location, writer);
869 if (ret_code != LTTNG_OK) {
870 goto end;
871 }
872
873 /* Close kernel probe location element. */
874 ret = mi_lttng_writer_close_element(writer);
875 if (ret) {
876 goto mi_error;
877 }
878
879 ret_code = LTTNG_OK;
880 goto end;
881
882 mi_error:
883 ret_code = LTTNG_ERR_MI_IO_FAIL;
884 end:
885 return ret_code;
886 }
This page took 0.046953 seconds and 5 git commands to generate.