MI: xsd: sort output_type
[lttng-tools.git] / src / common / kernel-probe.c
CommitLineData
808cb744
JR
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>
959e3c66
JR
11#include <common/hashtable/hashtable.h>
12#include <common/hashtable/utils.h>
6a751b95
JR
13#include <common/macros.h>
14#include <common/mi-lttng.h>
15#include <common/payload-view.h>
16#include <common/payload.h>
808cb744
JR
17#include <fcntl.h>
18#include <lttng/constant.h>
808cb744 19#include <lttng/kernel-probe-internal.h>
6a751b95 20#include <lttng/kernel-probe.h>
808cb744
JR
21#include <sys/stat.h>
22#include <sys/types.h>
23#include <sys/unistd.h>
24
25static
26int lttng_kernel_probe_location_address_serialize(
27 const struct lttng_kernel_probe_location *location,
28 struct lttng_payload *payload);
29
30static
31int lttng_kernel_probe_location_symbol_serialize(
32 const struct lttng_kernel_probe_location *location,
33 struct lttng_payload *payload);
34
35static
36bool lttng_kernel_probe_location_address_is_equal(
37 const struct lttng_kernel_probe_location *a,
38 const struct lttng_kernel_probe_location *b);
39
40static
41bool lttng_kernel_probe_location_symbol_is_equal(
42 const struct lttng_kernel_probe_location *a,
43 const struct lttng_kernel_probe_location *b);
44
959e3c66
JR
45static
46unsigned long lttng_kernel_probe_location_address_hash(
47 const struct lttng_kernel_probe_location *location);
48
49static
50unsigned long lttng_kernel_probe_location_symbol_hash(
51 const struct lttng_kernel_probe_location *location);
52
6a751b95
JR
53static
54enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
55 const struct lttng_kernel_probe_location *location,
56 struct mi_writer *writer);
57
58static
59enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
60 const struct lttng_kernel_probe_location *location,
61 struct mi_writer *writer);
62
808cb744
JR
63enum 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
70static
71void lttng_kernel_probe_location_address_destroy(
72 struct lttng_kernel_probe_location *location)
73{
74 assert(location);
75 free(location);
76}
77
78static
79void 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
96void 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
115struct lttng_kernel_probe_location *
116lttng_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) {
077192fd 123 PERROR("Error allocating userspace probe location.");
808cb744
JR
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;
959e3c66 133 ret->hash = lttng_kernel_probe_location_address_hash;
6a751b95 134 ret->mi_serialize = lttng_kernel_probe_location_address_mi_serialize;
808cb744
JR
135
136end:
137 return ret;
138}
139
140struct lttng_kernel_probe_location *
141lttng_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;
959e3c66 171 ret->hash = lttng_kernel_probe_location_symbol_hash;
6a751b95 172 ret->mi_serialize = lttng_kernel_probe_location_symbol_mi_serialize;
808cb744
JR
173 goto end;
174
175error:
176 free(symbol_name_copy);
177end:
178 return ret;
179}
180
181enum lttng_kernel_probe_location_status
182lttng_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;
202end:
203 return ret;
204}
205
206const 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;
221end:
222 return ret;
223}
224
225enum lttng_kernel_probe_location_status
226lttng_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;
246end:
247 return ret;
248}
249
250static
251int 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);
304end:
305 return ret;
306}
307
308static
309int 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);
338end:
339 return ret;
340}
341
342LTTNG_HIDDEN
343int 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);
372end:
373 return ret;
374}
375
376static
377int 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;
420end:
421 return ret;
422}
423
424static
425ssize_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;
452end:
453 return ret;
454}
455
456LTTNG_HIDDEN
457ssize_t lttng_kernel_probe_location_create_from_payload(
458 struct lttng_payload_view *view,
459 struct lttng_kernel_probe_location **location)
460{
808cb744
JR
461 enum lttng_kernel_probe_location_type type;
462 ssize_t consumed = 0;
463 ssize_t ret;
3e6e0df2
JG
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));
808cb744
JR
468
469 assert(view);
470 assert(location);
471
3e6e0df2 472 if (!lttng_payload_view_is_valid(&probe_location_comm_view)) {
808cb744
JR
473 ret = -LTTNG_ERR_INVALID;
474 goto end;
475 }
476
3e6e0df2 477 probe_location_comm = (typeof(probe_location_comm)) probe_location_comm_view.buffer.data;
808cb744
JR
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
513end:
514 return ret;
515}
516
959e3c66
JR
517static
518unsigned 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
808cb744
JR
533static
534bool 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
552end:
553 return is_equal;
554}
555
959e3c66
JR
556static
557unsigned 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
808cb744
JR
573static
574bool 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
598end:
599 return is_equal;
600}
601
602LTTNG_HIDDEN
603bool 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;
623end:
624 return is_equal;
625}
077192fd
JR
626
627static struct lttng_kernel_probe_location *
628lttng_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
661error:
662 new_location = NULL;
663end:
664 return new_location;
665}
666static struct lttng_kernel_probe_location *
667lttng_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
693error:
694 new_location = NULL;
695end:
696 return new_location;
697}
698
699LTTNG_HIDDEN
700struct 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 }
730err:
731 return new_location;
732}
959e3c66
JR
733
734LTTNG_HIDDEN
735unsigned long lttng_kernel_probe_location_hash(
736 const struct lttng_kernel_probe_location *location)
737{
738 return location->hash(location);
739}
6a751b95
JR
740
741static
742enum 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
782mi_error:
783 ret_code = LTTNG_ERR_MI_IO_FAIL;
784end:
785 return ret_code;
786}
787
788static
789enum 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
843mi_error:
844 ret_code = LTTNG_ERR_MI_IO_FAIL;
845end:
846 return ret_code;
847}
848
849LTTNG_HIDDEN
850enum 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
882mi_error:
883 ret_code = LTTNG_ERR_MI_IO_FAIL;
884end:
885 return ret_code;
886}
This page took 0.057704 seconds and 4 git commands to generate.