common: uuid: add `uuid_to_str` which returns an std::string
[lttng-tools.git] / src / common / kernel-probe.cpp
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"
c9e313bc
SM
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>
808cb744
JR
16#include <fcntl.h>
17#include <lttng/constant.h>
c9e313bc 18#include <lttng/kernel-probe-internal.hpp>
6a751b95 19#include <lttng/kernel-probe.h>
808cb744
JR
20#include <sys/stat.h>
21#include <sys/types.h>
8f14767d 22#include <unistd.h>
808cb744
JR
23
24static
25int lttng_kernel_probe_location_address_serialize(
26 const struct lttng_kernel_probe_location *location,
27 struct lttng_payload *payload);
28
29static
30int lttng_kernel_probe_location_symbol_serialize(
31 const struct lttng_kernel_probe_location *location,
32 struct lttng_payload *payload);
33
34static
35bool lttng_kernel_probe_location_address_is_equal(
36 const struct lttng_kernel_probe_location *a,
37 const struct lttng_kernel_probe_location *b);
38
39static
40bool lttng_kernel_probe_location_symbol_is_equal(
41 const struct lttng_kernel_probe_location *a,
42 const struct lttng_kernel_probe_location *b);
43
959e3c66
JR
44static
45unsigned long lttng_kernel_probe_location_address_hash(
46 const struct lttng_kernel_probe_location *location);
47
48static
49unsigned long lttng_kernel_probe_location_symbol_hash(
50 const struct lttng_kernel_probe_location *location);
51
6a751b95
JR
52static
53enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
54 const struct lttng_kernel_probe_location *location,
55 struct mi_writer *writer);
56
57static
58enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
59 const struct lttng_kernel_probe_location *location,
60 struct mi_writer *writer);
61
808cb744
JR
62enum 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
69static
70void lttng_kernel_probe_location_address_destroy(
71 struct lttng_kernel_probe_location *location)
72{
a0377dfe 73 LTTNG_ASSERT(location);
808cb744
JR
74 free(location);
75}
76
77static
78void 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
a0377dfe 83 LTTNG_ASSERT(location);
808cb744
JR
84
85 location_symbol = container_of(location,
86 struct lttng_kernel_probe_location_symbol,
87 parent);
88
a0377dfe 89 LTTNG_ASSERT(location_symbol);
808cb744
JR
90
91 free(location_symbol->symbol_name);
92 free(location);
93}
94
95void 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
114struct lttng_kernel_probe_location *
115lttng_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
64803277 120 location = zmalloc<lttng_kernel_probe_location_address>();
808cb744 121 if (!location) {
077192fd 122 PERROR("Error allocating userspace probe location.");
808cb744
JR
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;
959e3c66 132 ret->hash = lttng_kernel_probe_location_address_hash;
6a751b95 133 ret->mi_serialize = lttng_kernel_probe_location_address_mi_serialize;
808cb744
JR
134
135end:
136 return ret;
137}
138
139struct lttng_kernel_probe_location *
140lttng_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
64803277 157 location = zmalloc<lttng_kernel_probe_location_symbol>();
808cb744
JR
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;
959e3c66 170 ret->hash = lttng_kernel_probe_location_symbol_hash;
6a751b95 171 ret->mi_serialize = lttng_kernel_probe_location_symbol_mi_serialize;
808cb744
JR
172 goto end;
173
174error:
175 free(symbol_name_copy);
176end:
177 return ret;
178}
179
180enum lttng_kernel_probe_location_status
181lttng_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
a0377dfe 189 LTTNG_ASSERT(offset);
808cb744
JR
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;
201end:
202 return ret;
203}
204
205const 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;
220end:
221 return ret;
222}
223
224enum lttng_kernel_probe_location_status
225lttng_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
a0377dfe 233 LTTNG_ASSERT(offset);
808cb744
JR
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;
245end:
246 return ret;
247}
248
249static
250int 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
a0377dfe 266 LTTNG_ASSERT(lttng_kernel_probe_location_get_type(location) ==
808cb744
JR
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);
303end:
304 return ret;
305}
306
307static
308int 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
a0377dfe
FD
317 LTTNG_ASSERT(location);
318 LTTNG_ASSERT(lttng_kernel_probe_location_get_type(location) ==
808cb744
JR
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);
337end:
338 return ret;
339}
340
808cb744
JR
341int 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);
370end:
371 return ret;
372}
373
374static
375int 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
a0377dfe 384 LTTNG_ASSERT(location);
808cb744
JR
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;
418end:
419 return ret;
420}
421
422static
423ssize_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
a0377dfe 431 LTTNG_ASSERT(location);
808cb744
JR
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;
450end:
451 return ret;
452}
453
808cb744
JR
454ssize_t lttng_kernel_probe_location_create_from_payload(
455 struct lttng_payload_view *view,
456 struct lttng_kernel_probe_location **location)
457{
808cb744
JR
458 enum lttng_kernel_probe_location_type type;
459 ssize_t consumed = 0;
460 ssize_t ret;
3e6e0df2
JG
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));
808cb744 465
a0377dfe
FD
466 LTTNG_ASSERT(view);
467 LTTNG_ASSERT(location);
808cb744 468
3e6e0df2 469 if (!lttng_payload_view_is_valid(&probe_location_comm_view)) {
808cb744
JR
470 ret = -LTTNG_ERR_INVALID;
471 goto end;
472 }
473
3e6e0df2 474 probe_location_comm = (typeof(probe_location_comm)) probe_location_comm_view.buffer.data;
808cb744
JR
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
510end:
511 return ret;
512}
513
959e3c66
JR
514static
515unsigned 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
808cb744
JR
530static
531bool 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
549end:
550 return is_equal;
551}
552
959e3c66
JR
553static
554unsigned 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
808cb744
JR
570static
571bool 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
a0377dfe
FD
583 LTTNG_ASSERT(a->symbol_name);
584 LTTNG_ASSERT(b->symbol_name);
808cb744
JR
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
595end:
596 return is_equal;
597}
598
808cb744
JR
599bool 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;
619end:
620 return is_equal;
621}
077192fd
JR
622
623static struct lttng_kernel_probe_location *
624lttng_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
a0377dfe
FD
633 LTTNG_ASSERT(location);
634 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
077192fd
JR
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
657error:
658 new_location = NULL;
659end:
660 return new_location;
661}
662static struct lttng_kernel_probe_location *
663lttng_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
a0377dfe
FD
671 LTTNG_ASSERT(location);
672 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
077192fd
JR
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
689error:
690 new_location = NULL;
691end:
692 return new_location;
693}
694
077192fd
JR
695struct 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 }
725err:
726 return new_location;
727}
959e3c66 728
959e3c66
JR
729unsigned long lttng_kernel_probe_location_hash(
730 const struct lttng_kernel_probe_location *location)
731{
732 return location->hash(location);
733}
6a751b95
JR
734
735static
736enum 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
a0377dfe
FD
745 LTTNG_ASSERT(location);
746 LTTNG_ASSERT(writer);
747 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
6a751b95
JR
748
749 status = lttng_kernel_probe_location_address_get_address(
750 location, &address);
a0377dfe 751 LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
6a751b95
JR
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
776mi_error:
777 ret_code = LTTNG_ERR_MI_IO_FAIL;
778end:
779 return ret_code;
780}
781
782static
783enum 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
a0377dfe
FD
793 LTTNG_ASSERT(location);
794 LTTNG_ASSERT(writer);
795 LTTNG_ASSERT(location->type ==
6a751b95
JR
796 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
797
798 name = lttng_kernel_probe_location_symbol_get_name(location);
a0377dfe 799 LTTNG_ASSERT(name);
6a751b95
JR
800
801 status = lttng_kernel_probe_location_symbol_get_offset(
802 location, &offset);
a0377dfe 803 LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
6a751b95
JR
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
837mi_error:
838 ret_code = LTTNG_ERR_MI_IO_FAIL;
839end:
840 return ret_code;
841}
842
6a751b95
JR
843enum 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
a0377dfe
FD
850 LTTNG_ASSERT(location);
851 LTTNG_ASSERT(writer);
6a751b95
JR
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
875mi_error:
876 ret_code = LTTNG_ERR_MI_IO_FAIL;
877end:
878 return ret_code;
879}
This page took 0.081795 seconds and 4 git commands to generate.