Force usage of assert() condition when NDEBUG is defined
[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"
808cb744 9#include <common/error.h>
959e3c66
JR
10#include <common/hashtable/hashtable.h>
11#include <common/hashtable/utils.h>
6a751b95
JR
12#include <common/macros.h>
13#include <common/mi-lttng.h>
14#include <common/payload-view.h>
15#include <common/payload.h>
808cb744
JR
16#include <fcntl.h>
17#include <lttng/constant.h>
808cb744 18#include <lttng/kernel-probe-internal.h>
6a751b95 19#include <lttng/kernel-probe.h>
808cb744
JR
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <sys/unistd.h>
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
120 location = zmalloc(sizeof(*location));
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
157 location = zmalloc(sizeof(*location));
158 if (!location) {
159 PERROR("Failed to allocate kernel symbol probe location");
160 goto error;
161 }
162
163 location->symbol_name = symbol_name_copy;
164 location->offset = offset;
165
166 ret = &location->parent;
167 ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET;
168 ret->equal = lttng_kernel_probe_location_symbol_is_equal;
169 ret->serialize = lttng_kernel_probe_location_symbol_serialize;
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
341LTTNG_HIDDEN
342int lttng_kernel_probe_location_serialize(
343 const struct lttng_kernel_probe_location *location,
344 struct lttng_payload *payload)
345{
346 int ret;
347 size_t original_payload_size;
348 struct lttng_kernel_probe_location_comm location_generic_comm = {};
349
350 if (!location || !payload) {
351 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
352 ret = -LTTNG_ERR_INVALID;
353 goto end;
354 }
355
356 original_payload_size = payload->buffer.size;
357 location_generic_comm.type = (int8_t) location->type;
358 ret = lttng_dynamic_buffer_append(&payload->buffer,
359 &location_generic_comm,
360 sizeof(location_generic_comm));
361 if (ret) {
362 goto end;
363 }
364
365 ret = location->serialize(location, payload);
366 if (ret < 0) {
367 goto end;
368 }
369
370 ret = (int) (payload->buffer.size - original_payload_size);
371end:
372 return ret;
373}
374
375static
376int lttng_kernel_probe_location_symbol_create_from_payload(
377 struct lttng_payload_view *view,
378 struct lttng_kernel_probe_location **location)
379{
380 struct lttng_kernel_probe_location_symbol_comm *location_symbol_comm;
381 const char *symbol_name_src;
382 ssize_t ret = 0;
383 size_t expected_size;
384
a0377dfe 385 LTTNG_ASSERT(location);
808cb744
JR
386
387 if (view->buffer.size < sizeof(*location_symbol_comm)) {
388 ret = -LTTNG_ERR_INVALID;
389 goto end;
390 }
391
392 location_symbol_comm =
393 (typeof(location_symbol_comm)) view->buffer.data;
394
395 expected_size = sizeof(*location_symbol_comm) +
396 location_symbol_comm->symbol_len;
397
398 if (view->buffer.size < expected_size) {
399 ret = -LTTNG_ERR_INVALID;
400 goto end;
401 }
402
403 symbol_name_src = view->buffer.data + sizeof(*location_symbol_comm);
404
405 if (!lttng_buffer_view_contains_string(&view->buffer, symbol_name_src,
406 location_symbol_comm->symbol_len)) {
407 ret = -LTTNG_ERR_INVALID;
408 goto end;
409 }
410
411 *location = lttng_kernel_probe_location_symbol_create(
412 symbol_name_src, location_symbol_comm->offset);
413 if (!(*location)) {
414 ret = -LTTNG_ERR_INVALID;
415 goto end;
416 }
417
418 ret = (ssize_t) expected_size;
419end:
420 return ret;
421}
422
423static
424ssize_t lttng_kernel_probe_location_address_create_from_payload(
425 struct lttng_payload_view *view,
426 struct lttng_kernel_probe_location **location)
427{
428 struct lttng_kernel_probe_location_address_comm *location_address_comm;
429 ssize_t ret = 0;
430 size_t expected_size;
431
a0377dfe 432 LTTNG_ASSERT(location);
808cb744
JR
433
434 expected_size = sizeof(*location_address_comm);
435
436 if (view->buffer.size < expected_size) {
437 ret = -LTTNG_ERR_INVALID;
438 goto end;
439 }
440
441 location_address_comm =
442 (typeof(location_address_comm)) view->buffer.data;
443
444 *location = lttng_kernel_probe_location_address_create(location_address_comm->address);
445 if (!(*location)) {
446 ret = -LTTNG_ERR_INVALID;
447 goto end;
448 }
449
450 ret = (size_t) expected_size;
451end:
452 return ret;
453}
454
455LTTNG_HIDDEN
456ssize_t lttng_kernel_probe_location_create_from_payload(
457 struct lttng_payload_view *view,
458 struct lttng_kernel_probe_location **location)
459{
808cb744
JR
460 enum lttng_kernel_probe_location_type type;
461 ssize_t consumed = 0;
462 ssize_t ret;
3e6e0df2
JG
463 const struct lttng_kernel_probe_location_comm *probe_location_comm;
464 const struct lttng_payload_view probe_location_comm_view =
465 lttng_payload_view_from_view(
466 view, 0, sizeof(*probe_location_comm));
808cb744 467
a0377dfe
FD
468 LTTNG_ASSERT(view);
469 LTTNG_ASSERT(location);
808cb744 470
3e6e0df2 471 if (!lttng_payload_view_is_valid(&probe_location_comm_view)) {
808cb744
JR
472 ret = -LTTNG_ERR_INVALID;
473 goto end;
474 }
475
3e6e0df2 476 probe_location_comm = (typeof(probe_location_comm)) probe_location_comm_view.buffer.data;
808cb744
JR
477 type = (enum lttng_kernel_probe_location_type) probe_location_comm->type;
478 consumed += sizeof(*probe_location_comm);
479
480 switch (type) {
481 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
482 {
483 struct lttng_payload_view location_view =
484 lttng_payload_view_from_view(
485 view, consumed, -1);
486
487 ret = lttng_kernel_probe_location_symbol_create_from_payload(
488 &location_view, location);
489 break;
490 }
491 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
492 {
493 struct lttng_payload_view location_view =
494 lttng_payload_view_from_view(view, consumed, -1);
495
496 ret = lttng_kernel_probe_location_address_create_from_payload(
497 &location_view, location);
498 break;
499 }
500 default:
501 ret = -LTTNG_ERR_INVALID;
502 break;
503 }
504
505 if (ret < 0) {
506 ret = -LTTNG_ERR_INVALID;
507 goto end;
508 }
509
510 ret += consumed;
511
512end:
513 return ret;
514}
515
959e3c66
JR
516static
517unsigned long lttng_kernel_probe_location_address_hash(
518 const struct lttng_kernel_probe_location *location)
519{
520 unsigned long hash = hash_key_ulong(
521 (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS,
522 lttng_ht_seed);
523 struct lttng_kernel_probe_location_address *address_location =
524 container_of(location, typeof(*address_location),
525 parent);
526
527 hash ^= hash_key_u64(&address_location->address, lttng_ht_seed);
528
529 return hash;
530}
531
808cb744
JR
532static
533bool lttng_kernel_probe_location_address_is_equal(
534 const struct lttng_kernel_probe_location *_a,
535 const struct lttng_kernel_probe_location *_b)
536{
537 bool is_equal = false;
538 struct lttng_kernel_probe_location_address *a, *b;
539
540 a = container_of(_a, struct lttng_kernel_probe_location_address,
541 parent);
542 b = container_of(_b, struct lttng_kernel_probe_location_address,
543 parent);
544
545 if (a->address != b->address) {
546 goto end;
547 }
548
549 is_equal = true;
550
551end:
552 return is_equal;
553}
554
959e3c66
JR
555static
556unsigned long lttng_kernel_probe_location_symbol_hash(
557 const struct lttng_kernel_probe_location *location)
558{
559 unsigned long hash = hash_key_ulong(
560 (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET,
561 lttng_ht_seed);
562 struct lttng_kernel_probe_location_symbol *symbol_location =
563 container_of(location, typeof(*symbol_location),
564 parent);
565
566 hash ^= hash_key_str(symbol_location->symbol_name, lttng_ht_seed);
567 hash ^= hash_key_u64(&symbol_location->offset, lttng_ht_seed);
568
569 return hash;
570}
571
808cb744
JR
572static
573bool lttng_kernel_probe_location_symbol_is_equal(
574 const struct lttng_kernel_probe_location *_a,
575 const struct lttng_kernel_probe_location *_b)
576{
577 bool is_equal = false;
578 struct lttng_kernel_probe_location_symbol *a, *b;
579
580 a = container_of(_a, struct lttng_kernel_probe_location_symbol,
581 parent);
582 b = container_of(_b, struct lttng_kernel_probe_location_symbol,
583 parent);
584
a0377dfe
FD
585 LTTNG_ASSERT(a->symbol_name);
586 LTTNG_ASSERT(b->symbol_name);
808cb744
JR
587 if (strcmp(a->symbol_name, b->symbol_name)) {
588 goto end;
589 }
590
591 if (a->offset != b->offset) {
592 goto end;
593 }
594
595 is_equal = true;
596
597end:
598 return is_equal;
599}
600
601LTTNG_HIDDEN
602bool lttng_kernel_probe_location_is_equal(
603 const struct lttng_kernel_probe_location *a,
604 const struct lttng_kernel_probe_location *b)
605{
606 bool is_equal = false;
607
608 if (!a || !b) {
609 goto end;
610 }
611
612 if (a == b) {
613 is_equal = true;
614 goto end;
615 }
616
617 if (a->type != b->type) {
618 goto end;
619 }
620
621 is_equal = a->equal ? a->equal(a, b) : true;
622end:
623 return is_equal;
624}
077192fd
JR
625
626static struct lttng_kernel_probe_location *
627lttng_kernel_probe_location_symbol_copy(
628 const struct lttng_kernel_probe_location *location)
629{
630 struct lttng_kernel_probe_location *new_location = NULL;
631 struct lttng_kernel_probe_location_symbol *symbol_location;
632 enum lttng_kernel_probe_location_status status;
633 const char *symbol_name = NULL;
634 uint64_t offset;
635
a0377dfe
FD
636 LTTNG_ASSERT(location);
637 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
077192fd
JR
638 symbol_location = container_of(
639 location, typeof(*symbol_location), parent);
640
641 /* Get probe location offset */
642 status = lttng_kernel_probe_location_symbol_get_offset(location, &offset);
643 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
644 ERR("Get kernel probe location offset failed.");
645 goto error;
646 }
647
648 symbol_name = lttng_kernel_probe_location_symbol_get_name(location);
649 if (!symbol_name) {
650 ERR("Kernel probe symbol name is NULL.");
651 goto error;
652 }
653
654 /* Create the probe_location */
655 new_location = lttng_kernel_probe_location_symbol_create(
656 symbol_name, offset);
657
658 goto end;
659
660error:
661 new_location = NULL;
662end:
663 return new_location;
664}
665static struct lttng_kernel_probe_location *
666lttng_kernel_probe_location_address_copy(
667 const struct lttng_kernel_probe_location *location)
668{
669 struct lttng_kernel_probe_location *new_location = NULL;
670 struct lttng_kernel_probe_location_address *address_location;
671 enum lttng_kernel_probe_location_status status;
672 uint64_t address;
673
a0377dfe
FD
674 LTTNG_ASSERT(location);
675 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
077192fd
JR
676 address_location = container_of(
677 location, typeof(*address_location), parent);
678
679
680 /* Get probe location fields */
681 status = lttng_kernel_probe_location_address_get_address(location, &address);
682 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
683 ERR("Get kernel probe address failed.");
684 goto error;
685 }
686
687 /* Create the probe_location */
688 new_location = lttng_kernel_probe_location_address_create(address);
689
690 goto end;
691
692error:
693 new_location = NULL;
694end:
695 return new_location;
696}
697
698LTTNG_HIDDEN
699struct lttng_kernel_probe_location *lttng_kernel_probe_location_copy(
700 const struct lttng_kernel_probe_location *location)
701{
702 struct lttng_kernel_probe_location *new_location = NULL;
703 enum lttng_kernel_probe_location_type type;
704
705 if (!location) {
706 goto err;
707 }
708
709 type = lttng_kernel_probe_location_get_type(location);
710 switch (type) {
711 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
712 new_location =
713 lttng_kernel_probe_location_address_copy(location);
714 if (!new_location) {
715 goto err;
716 }
717 break;
718 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
719 new_location =
720 lttng_kernel_probe_location_symbol_copy(location);
721 if (!new_location) {
722 goto err;
723 }
724 break;
725 default:
726 new_location = NULL;
727 goto err;
728 }
729err:
730 return new_location;
731}
959e3c66
JR
732
733LTTNG_HIDDEN
734unsigned long lttng_kernel_probe_location_hash(
735 const struct lttng_kernel_probe_location *location)
736{
737 return location->hash(location);
738}
6a751b95
JR
739
740static
741enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
742 const struct lttng_kernel_probe_location *location,
743 struct mi_writer *writer)
744{
745 int ret;
746 enum lttng_error_code ret_code;
747 enum lttng_kernel_probe_location_status status;
748 uint64_t address;
749
a0377dfe
FD
750 LTTNG_ASSERT(location);
751 LTTNG_ASSERT(writer);
752 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
6a751b95
JR
753
754 status = lttng_kernel_probe_location_address_get_address(
755 location, &address);
a0377dfe 756 LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
6a751b95
JR
757
758 /* Open kernel probe location address element. */
759 ret = mi_lttng_writer_open_element(
760 writer, mi_lttng_element_kernel_probe_location_address);
761 if (ret) {
762 goto mi_error;
763 }
764
765 ret = mi_lttng_writer_write_element_unsigned_int(writer,
766 mi_lttng_element_kernel_probe_location_address_address,
767 address);
768 if (ret) {
769 goto mi_error;
770 }
771
772 /* Close kernel probe location address element. */
773 ret = mi_lttng_writer_close_element(writer);
774 if (ret) {
775 goto mi_error;
776 }
777
778 ret_code = LTTNG_OK;
779 goto end;
780
781mi_error:
782 ret_code = LTTNG_ERR_MI_IO_FAIL;
783end:
784 return ret_code;
785}
786
787static
788enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
789 const struct lttng_kernel_probe_location *location,
790 struct mi_writer *writer)
791{
792 int ret;
793 enum lttng_error_code ret_code;
794 enum lttng_kernel_probe_location_status status;
795 const char *name = NULL;
796 uint64_t offset;
797
a0377dfe
FD
798 LTTNG_ASSERT(location);
799 LTTNG_ASSERT(writer);
800 LTTNG_ASSERT(location->type ==
6a751b95
JR
801 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
802
803 name = lttng_kernel_probe_location_symbol_get_name(location);
a0377dfe 804 LTTNG_ASSERT(name);
6a751b95
JR
805
806 status = lttng_kernel_probe_location_symbol_get_offset(
807 location, &offset);
a0377dfe 808 LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
6a751b95
JR
809
810 /* Open kernel probe location symbol offset element. */
811 ret = mi_lttng_writer_open_element(writer,
812 mi_lttng_element_kernel_probe_location_symbol_offset);
813 if (ret) {
814 goto mi_error;
815 }
816
817 /* Name. */
818 ret = mi_lttng_writer_write_element_string(writer,
819 mi_lttng_element_kernel_probe_location_symbol_offset_name,
820 name);
821 if (ret) {
822 goto mi_error;
823 }
824
825 /* Offset. */
826 ret = mi_lttng_writer_write_element_unsigned_int(writer,
827 mi_lttng_element_kernel_probe_location_symbol_offset_offset,
828 offset);
829 if (ret) {
830 goto mi_error;
831 }
832
833 /* Close kernel probe location symbol offset element. */
834 ret = mi_lttng_writer_close_element(writer);
835 if (ret) {
836 goto mi_error;
837 }
838
839 ret_code = LTTNG_OK;
840 goto end;
841
842mi_error:
843 ret_code = LTTNG_ERR_MI_IO_FAIL;
844end:
845 return ret_code;
846}
847
848LTTNG_HIDDEN
849enum lttng_error_code lttng_kernel_probe_location_mi_serialize(
850 const struct lttng_kernel_probe_location *location,
851 struct mi_writer *writer)
852{
853 int ret;
854 enum lttng_error_code ret_code;
855
a0377dfe
FD
856 LTTNG_ASSERT(location);
857 LTTNG_ASSERT(writer);
6a751b95
JR
858
859 /* Open kernel probe location element. */
860 ret = mi_lttng_writer_open_element(
861 writer, mi_lttng_element_kernel_probe_location);
862 if (ret) {
863 goto mi_error;
864 }
865
866 /* Serialize the location sub type. */
867 ret_code = location->mi_serialize(location, writer);
868 if (ret_code != LTTNG_OK) {
869 goto end;
870 }
871
872 /* Close kernel probe location element. */
873 ret = mi_lttng_writer_close_element(writer);
874 if (ret) {
875 goto mi_error;
876 }
877
878 ret_code = LTTNG_OK;
879 goto end;
880
881mi_error:
882 ret_code = LTTNG_ERR_MI_IO_FAIL;
883end:
884 return ret_code;
885}
This page took 0.060422 seconds and 4 git commands to generate.