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