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