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