2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include "lttng/lttng-error.h"
10 #include <common/align.hpp>
11 #include <common/compat/string.hpp>
12 #include <common/error.hpp>
13 #include <common/hashtable/hashtable.hpp>
14 #include <common/hashtable/utils.hpp>
15 #include <common/macros.hpp>
16 #include <common/mi-lttng.hpp>
17 #include <common/payload-view.hpp>
18 #include <common/payload.hpp>
20 #include <lttng/constant.h>
21 #include <lttng/userspace-probe-internal.hpp>
25 #include <sys/types.h>
28 static int lttng_userspace_probe_location_function_set_binary_fd_handle(
29 struct lttng_userspace_probe_location
*location
, struct fd_handle
*binary_fd_handle
);
31 static int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
32 struct lttng_userspace_probe_location
*location
, struct fd_handle
*binary_fd_handle
);
34 static enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
35 const struct lttng_userspace_probe_location_lookup_method
*method
,
36 struct mi_writer
*writer
);
38 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
39 const struct lttng_userspace_probe_location
*location
, struct mi_writer
*writer
);
41 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
42 const struct lttng_userspace_probe_location
*location
, struct mi_writer
*writer
);
44 enum lttng_userspace_probe_location_lookup_method_type
45 lttng_userspace_probe_location_lookup_method_get_type(
46 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
48 return lookup_method
? lookup_method
->type
:
49 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
52 void lttng_userspace_probe_location_lookup_method_destroy(
53 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
62 struct lttng_userspace_probe_location_lookup_method
*
63 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
65 struct lttng_userspace_probe_location_lookup_method
*ret
= nullptr;
66 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
68 elf_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_elf
>();
74 ret
= &elf_method
->parent
;
75 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
80 struct lttng_userspace_probe_location_lookup_method
*
81 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
83 struct lttng_userspace_probe_location_lookup_method
*ret
= nullptr;
84 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
86 sdt_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_sdt
>();
92 ret
= &sdt_method
->parent
;
93 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
98 enum lttng_userspace_probe_location_type
99 lttng_userspace_probe_location_get_type(const struct lttng_userspace_probe_location
*location
)
101 return location
? location
->type
: LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
105 lttng_userspace_probe_location_function_destroy(struct lttng_userspace_probe_location
*location
)
107 struct lttng_userspace_probe_location_function
*location_function
= nullptr;
109 LTTNG_ASSERT(location
);
111 location_function
= lttng::utils::container_of(
112 location
, <tng_userspace_probe_location_function::parent
);
114 LTTNG_ASSERT(location_function
);
116 free(location_function
->function_name
);
117 free(location_function
->binary_path
);
118 fd_handle_put(location_function
->binary_fd_handle
);
123 lttng_userspace_probe_location_tracepoint_destroy(struct lttng_userspace_probe_location
*location
)
125 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= nullptr;
127 LTTNG_ASSERT(location
);
129 location_tracepoint
= lttng::utils::container_of(
130 location
, <tng_userspace_probe_location_tracepoint::parent
);
132 LTTNG_ASSERT(location_tracepoint
);
134 free(location_tracepoint
->probe_name
);
135 free(location_tracepoint
->provider_name
);
136 free(location_tracepoint
->binary_path
);
137 fd_handle_put(location_tracepoint
->binary_fd_handle
);
141 void lttng_userspace_probe_location_destroy(struct lttng_userspace_probe_location
*location
)
147 lttng_userspace_probe_location_lookup_method_destroy(location
->lookup_method
);
149 switch (location
->type
) {
150 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
151 lttng_userspace_probe_location_function_destroy(location
);
153 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
154 lttng_userspace_probe_location_tracepoint_destroy(location
);
161 /* Compare two file descriptors based on their inode and device numbers. */
162 static bool fd_is_equal(int a
, int b
)
165 bool is_equal
= false;
166 struct stat a_stat
, b_stat
;
168 if (a
< 0 && b
>= 0) {
172 if (b
< 0 && a
>= 0) {
176 if (a
< 0 && b
< 0) {
177 if (a
== -1 && b
== -1) {
182 /* Invalid state, abort. */
186 /* Both are valid file descriptors. */
187 ret
= fstat(a
, &a_stat
);
189 PERROR("Failed to fstat userspace probe location binary fd %d", a
);
193 ret
= fstat(b
, &b_stat
);
195 PERROR("Failed to fstat userspace probe location binary fd %d", b
);
199 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) && (a_stat
.st_dev
== b_stat
.st_dev
);
206 lttng_userspace_probe_location_function_hash(const struct lttng_userspace_probe_location
*location
)
208 unsigned long hash
= hash_key_ulong((void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
,
210 struct lttng_userspace_probe_location_function
*function_location
=
211 lttng::utils::container_of(location
,
212 <tng_userspace_probe_location_function::parent
);
214 hash
^= hash_key_str(function_location
->function_name
, lttng_ht_seed
);
215 hash
^= hash_key_str(function_location
->binary_path
, lttng_ht_seed
);
217 * No need to hash on the fd. Worst comes to worse,
218 * the equal function will discriminate.
224 lttng_userspace_probe_location_function_is_equal(const struct lttng_userspace_probe_location
*_a
,
225 const struct lttng_userspace_probe_location
*_b
)
227 bool is_equal
= false;
228 struct lttng_userspace_probe_location_function
*a
, *b
;
230 a
= lttng::utils::container_of(_a
, <tng_userspace_probe_location_function::parent
);
231 b
= lttng::utils::container_of(_b
, <tng_userspace_probe_location_function::parent
);
233 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
237 LTTNG_ASSERT(a
->function_name
);
238 LTTNG_ASSERT(b
->function_name
);
239 if (strcmp(a
->function_name
, b
->function_name
) != 0) {
243 LTTNG_ASSERT(a
->binary_path
);
244 LTTNG_ASSERT(b
->binary_path
);
245 if (strcmp(a
->binary_path
, b
->binary_path
) != 0) {
249 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
250 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
255 static struct lttng_userspace_probe_location
*
256 lttng_userspace_probe_location_function_create_no_check(
257 const char *binary_path
,
258 const char *function_name
,
259 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
263 struct fd_handle
*binary_fd_handle
= nullptr;
264 char *function_name_copy
= nullptr, *binary_path_copy
= nullptr;
265 struct lttng_userspace_probe_location
*ret
= nullptr;
266 struct lttng_userspace_probe_location_function
*location
;
269 binary_fd
= open(binary_path
, O_RDONLY
);
271 PERROR("Error opening the binary");
275 binary_fd_handle
= fd_handle_create(binary_fd
);
280 /* Ownership transferred to fd_handle. */
284 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
285 if (!function_name_copy
) {
286 PERROR("Error duplicating the function name");
290 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
291 if (!binary_path_copy
) {
292 PERROR("Error duplicating the function name");
296 location
= zmalloc
<lttng_userspace_probe_location_function
>();
298 PERROR("Error allocating userspace probe location");
302 location
->function_name
= function_name_copy
;
303 location
->binary_path
= binary_path_copy
;
304 location
->binary_fd_handle
= binary_fd_handle
;
305 binary_fd_handle
= nullptr;
306 location
->instrumentation_type
=
307 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
309 ret
= &location
->parent
;
310 ret
->lookup_method
= lookup_method
;
311 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
312 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
313 ret
->hash
= lttng_userspace_probe_location_function_hash
;
317 free(function_name_copy
);
318 free(binary_path_copy
);
319 if (binary_fd
>= 0) {
320 if (close(binary_fd
)) {
321 PERROR("Error closing binary fd in error path");
324 fd_handle_put(binary_fd_handle
);
329 static unsigned long lttng_userspace_probe_location_tracepoint_hash(
330 const struct lttng_userspace_probe_location
*location
)
332 unsigned long hash
= hash_key_ulong((void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
,
334 struct lttng_userspace_probe_location_tracepoint
*tp_location
= lttng::utils::container_of(
335 location
, <tng_userspace_probe_location_tracepoint::parent
);
337 hash
^= hash_key_str(tp_location
->probe_name
, lttng_ht_seed
);
338 hash
^= hash_key_str(tp_location
->provider_name
, lttng_ht_seed
);
339 hash
^= hash_key_str(tp_location
->binary_path
, lttng_ht_seed
);
341 * No need to hash on the fd. Worst comes to worse,
342 * the equal function will discriminate.
348 lttng_userspace_probe_location_tracepoint_is_equal(const struct lttng_userspace_probe_location
*_a
,
349 const struct lttng_userspace_probe_location
*_b
)
351 bool is_equal
= false;
352 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
354 a
= lttng::utils::container_of(_a
, <tng_userspace_probe_location_tracepoint::parent
);
355 b
= lttng::utils::container_of(_b
, <tng_userspace_probe_location_tracepoint::parent
);
357 LTTNG_ASSERT(a
->probe_name
);
358 LTTNG_ASSERT(b
->probe_name
);
359 if (strcmp(a
->probe_name
, b
->probe_name
) != 0) {
363 LTTNG_ASSERT(a
->provider_name
);
364 LTTNG_ASSERT(b
->provider_name
);
365 if (strcmp(a
->provider_name
, b
->provider_name
) != 0) {
369 LTTNG_ASSERT(a
->binary_path
);
370 LTTNG_ASSERT(b
->binary_path
);
371 if (strcmp(a
->binary_path
, b
->binary_path
) != 0) {
375 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
376 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
382 static struct lttng_userspace_probe_location
*
383 lttng_userspace_probe_location_tracepoint_create_no_check(
384 const char *binary_path
,
385 const char *provider_name
,
386 const char *probe_name
,
387 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
391 struct fd_handle
*binary_fd_handle
= nullptr;
392 char *probe_name_copy
= nullptr;
393 char *provider_name_copy
= nullptr;
394 char *binary_path_copy
= nullptr;
395 struct lttng_userspace_probe_location
*ret
= nullptr;
396 struct lttng_userspace_probe_location_tracepoint
*location
;
399 binary_fd
= open(binary_path
, O_RDONLY
);
405 binary_fd_handle
= fd_handle_create(binary_fd
);
410 /* Ownership transferred to fd_handle. */
414 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
415 if (!probe_name_copy
) {
416 PERROR("lttng_strndup");
420 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
421 if (!provider_name_copy
) {
422 PERROR("lttng_strndup");
426 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
427 if (!binary_path_copy
) {
428 PERROR("lttng_strndup");
432 location
= zmalloc
<lttng_userspace_probe_location_tracepoint
>();
438 location
->probe_name
= probe_name_copy
;
439 location
->provider_name
= provider_name_copy
;
440 location
->binary_path
= binary_path_copy
;
441 location
->binary_fd_handle
= binary_fd_handle
;
442 binary_fd_handle
= nullptr;
444 ret
= &location
->parent
;
445 ret
->lookup_method
= lookup_method
;
446 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
447 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
448 ret
->hash
= lttng_userspace_probe_location_tracepoint_hash
;
452 free(probe_name_copy
);
453 free(provider_name_copy
);
454 free(binary_path_copy
);
455 if (binary_fd
>= 0) {
456 if (close(binary_fd
)) {
457 PERROR("Error closing binary fd in error path");
460 fd_handle_put(binary_fd_handle
);
465 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_function_create(
466 const char *binary_path
,
467 const char *function_name
,
468 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
470 struct lttng_userspace_probe_location
*ret
= nullptr;
472 if (!binary_path
|| !function_name
) {
473 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
477 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup_method
)) {
478 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
479 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
482 /* Invalid probe location lookup method. */
486 ret
= lttng_userspace_probe_location_function_create_no_check(
487 binary_path
, function_name
, lookup_method
, true);
492 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_tracepoint_create(
493 const char *binary_path
,
494 const char *provider_name
,
495 const char *probe_name
,
496 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
498 struct lttng_userspace_probe_location
*ret
= nullptr;
500 if (!binary_path
|| !probe_name
|| !provider_name
) {
501 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
505 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup_method
)) {
506 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
509 /* Invalid probe location lookup method. */
513 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
514 binary_path
, provider_name
, probe_name
, lookup_method
, true);
519 static struct lttng_userspace_probe_location_lookup_method
*
520 lttng_userspace_probe_location_lookup_method_function_elf_copy(
521 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
523 struct lttng_userspace_probe_location_lookup_method
*parent
= nullptr;
524 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
526 LTTNG_ASSERT(lookup_method
);
527 LTTNG_ASSERT(lookup_method
->type
==
528 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
530 elf_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_elf
>();
532 PERROR("Error allocating ELF userspace probe lookup method");
536 elf_method
->parent
.type
= lookup_method
->type
;
537 parent
= &elf_method
->parent
;
546 static struct lttng_userspace_probe_location_lookup_method
*
547 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
548 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
550 struct lttng_userspace_probe_location_lookup_method
*parent
= nullptr;
551 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
553 LTTNG_ASSERT(lookup_method
);
554 LTTNG_ASSERT(lookup_method
->type
==
555 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
557 sdt_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_sdt
>();
563 sdt_method
->parent
.type
= lookup_method
->type
;
564 parent
= &sdt_method
->parent
;
574 static struct lttng_userspace_probe_location
*
575 lttng_userspace_probe_location_function_copy(const struct lttng_userspace_probe_location
*location
)
577 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
578 struct lttng_userspace_probe_location
*new_location
= nullptr;
579 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= nullptr;
580 const char *binary_path
= nullptr;
581 const char *function_name
= nullptr;
582 struct lttng_userspace_probe_location_function
*function_location
;
584 LTTNG_ASSERT(location
);
585 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
586 function_location
= lttng::utils::container_of(
587 location
, <tng_userspace_probe_location_function::parent
);
589 /* Get probe location fields */
590 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
592 ERR("Userspace probe binary path is NULL");
596 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
597 if (!function_name
) {
598 ERR("Userspace probe function name is NULL");
603 * Duplicate probe location method fields
606 lttng_userspace_probe_location_lookup_method_get_type(location
->lookup_method
);
607 switch (lookup_type
) {
608 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
609 lookup_method
= lttng_userspace_probe_location_lookup_method_function_elf_copy(
610 location
->lookup_method
);
611 if (!lookup_method
) {
616 /* Invalid probe location lookup method. */
620 /* Create the probe_location */
621 new_location
= lttng_userspace_probe_location_function_create_no_check(
622 binary_path
, function_name
, lookup_method
, false);
624 goto destroy_lookup_method
;
627 /* Set the duplicated fd to the new probe_location */
628 if (lttng_userspace_probe_location_function_set_binary_fd_handle(
629 new_location
, function_location
->binary_fd_handle
) < 0) {
630 goto destroy_probe_location
;
635 destroy_probe_location
:
636 lttng_userspace_probe_location_destroy(new_location
);
637 destroy_lookup_method
:
638 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
640 new_location
= nullptr;
645 static struct lttng_userspace_probe_location
*lttng_userspace_probe_location_tracepoint_copy(
646 const struct lttng_userspace_probe_location
*location
)
648 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
649 struct lttng_userspace_probe_location
*new_location
= nullptr;
650 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= nullptr;
651 const char *binary_path
= nullptr;
652 const char *probe_name
= nullptr;
653 const char *provider_name
= nullptr;
654 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
656 LTTNG_ASSERT(location
);
657 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
658 tracepoint_location
= lttng::utils::container_of(
659 location
, <tng_userspace_probe_location_tracepoint::parent
);
661 /* Get probe location fields */
662 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
664 ERR("Userspace probe binary path is NULL");
668 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
670 ERR("Userspace probe probe name is NULL");
674 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
675 if (!provider_name
) {
676 ERR("Userspace probe provider name is NULL");
681 * Duplicate probe location method fields
684 lttng_userspace_probe_location_lookup_method_get_type(location
->lookup_method
);
685 switch (lookup_type
) {
686 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
687 lookup_method
= lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
688 location
->lookup_method
);
689 if (!lookup_method
) {
694 /* Invalid probe location lookup method. */
698 /* Create the probe_location */
699 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
700 binary_path
, provider_name
, probe_name
, lookup_method
, false);
702 goto destroy_lookup_method
;
705 /* Set the duplicated fd to the new probe_location */
706 if (lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
707 new_location
, tracepoint_location
->binary_fd_handle
) < 0) {
708 goto destroy_probe_location
;
713 destroy_probe_location
:
714 lttng_userspace_probe_location_destroy(new_location
);
715 destroy_lookup_method
:
716 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
718 new_location
= nullptr;
723 const char *lttng_userspace_probe_location_function_get_binary_path(
724 const struct lttng_userspace_probe_location
*location
)
726 const char *ret
= nullptr;
727 struct lttng_userspace_probe_location_function
*function_location
;
730 lttng_userspace_probe_location_get_type(location
) !=
731 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
732 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
736 function_location
= lttng::utils::container_of(
737 location
, <tng_userspace_probe_location_function::parent
);
738 ret
= function_location
->binary_path
;
743 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
744 const struct lttng_userspace_probe_location
*location
)
746 const char *ret
= nullptr;
747 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
750 lttng_userspace_probe_location_get_type(location
) !=
751 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
752 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
756 tracepoint_location
= lttng::utils::container_of(
757 location
, <tng_userspace_probe_location_tracepoint::parent
);
758 ret
= tracepoint_location
->binary_path
;
763 const char *lttng_userspace_probe_location_function_get_function_name(
764 const struct lttng_userspace_probe_location
*location
)
766 const char *ret
= nullptr;
767 struct lttng_userspace_probe_location_function
*function_location
;
770 lttng_userspace_probe_location_get_type(location
) !=
771 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
772 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
776 function_location
= lttng::utils::container_of(
777 location
, <tng_userspace_probe_location_function::parent
);
778 ret
= function_location
->function_name
;
783 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
784 const struct lttng_userspace_probe_location
*location
)
786 const char *ret
= nullptr;
787 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
790 lttng_userspace_probe_location_get_type(location
) !=
791 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
792 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
796 tracepoint_location
= lttng::utils::container_of(
797 location
, <tng_userspace_probe_location_tracepoint::parent
);
798 ret
= tracepoint_location
->probe_name
;
803 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
804 const struct lttng_userspace_probe_location
*location
)
806 const char *ret
= nullptr;
807 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
810 lttng_userspace_probe_location_get_type(location
) !=
811 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
812 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
816 tracepoint_location
= lttng::utils::container_of(
817 location
, <tng_userspace_probe_location_tracepoint::parent
);
818 ret
= tracepoint_location
->provider_name
;
823 int lttng_userspace_probe_location_function_get_binary_fd(
824 const struct lttng_userspace_probe_location
*location
)
827 struct lttng_userspace_probe_location_function
*function_location
;
830 lttng_userspace_probe_location_get_type(location
) !=
831 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
832 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
836 function_location
= lttng::utils::container_of(
837 location
, <tng_userspace_probe_location_function::parent
);
838 ret
= function_location
->binary_fd_handle
?
839 fd_handle_get_fd(function_location
->binary_fd_handle
) :
845 enum lttng_userspace_probe_location_function_instrumentation_type
846 lttng_userspace_probe_location_function_get_instrumentation_type(
847 const struct lttng_userspace_probe_location
*location
)
849 enum lttng_userspace_probe_location_function_instrumentation_type type
;
850 struct lttng_userspace_probe_location_function
*function_location
;
853 lttng_userspace_probe_location_get_type(location
) !=
854 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
855 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
856 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
860 function_location
= lttng::utils::container_of(
861 location
, <tng_userspace_probe_location_function::parent
);
862 type
= function_location
->instrumentation_type
;
867 enum lttng_userspace_probe_location_status
868 lttng_userspace_probe_location_function_set_instrumentation_type(
869 const struct lttng_userspace_probe_location
*location
,
870 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
872 enum lttng_userspace_probe_location_status status
=
873 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
874 struct lttng_userspace_probe_location_function
*function_location
;
877 lttng_userspace_probe_location_get_type(location
) !=
878 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
879 instrumentation_type
!=
880 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
881 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
882 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
886 function_location
= lttng::utils::container_of(
887 location
, <tng_userspace_probe_location_function::parent
);
888 function_location
->instrumentation_type
= instrumentation_type
;
893 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
894 const struct lttng_userspace_probe_location
*location
)
897 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
900 lttng_userspace_probe_location_get_type(location
) !=
901 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
902 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
906 tracepoint_location
= lttng::utils::container_of(
907 location
, <tng_userspace_probe_location_tracepoint::parent
);
908 ret
= tracepoint_location
->binary_fd_handle
?
909 fd_handle_get_fd(tracepoint_location
->binary_fd_handle
) :
915 static struct lttng_userspace_probe_location_lookup_method
*
916 lttng_userspace_probe_location_function_get_lookup_method(
917 const struct lttng_userspace_probe_location
*location
)
919 struct lttng_userspace_probe_location_lookup_method
*ret
= nullptr;
922 lttng_userspace_probe_location_get_type(location
) !=
923 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
924 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
928 ret
= location
->lookup_method
;
933 static struct lttng_userspace_probe_location_lookup_method
*
934 lttng_userspace_probe_location_tracepoint_get_lookup_method(
935 const struct lttng_userspace_probe_location
*location
)
937 struct lttng_userspace_probe_location_lookup_method
*ret
= nullptr;
940 lttng_userspace_probe_location_get_type(location
) !=
941 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
942 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
946 ret
= location
->lookup_method
;
951 const struct lttng_userspace_probe_location_lookup_method
*
952 lttng_userspace_probe_location_get_lookup_method(
953 const struct lttng_userspace_probe_location
*location
)
955 struct lttng_userspace_probe_location_lookup_method
*ret
= nullptr;
957 LTTNG_ASSERT(location
);
958 switch (location
->type
) {
959 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
960 ret
= lttng_userspace_probe_location_function_get_lookup_method(location
);
962 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
963 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(location
);
966 ERR("Unknowned lookup method.");
972 static int lttng_userspace_probe_location_lookup_method_serialize(
973 struct lttng_userspace_probe_location_lookup_method
*method
, struct lttng_payload
*payload
)
976 struct lttng_userspace_probe_location_lookup_method_comm lookup_method_comm
;
978 lookup_method_comm
.type
=
981 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
983 ret
= lttng_dynamic_buffer_append(
984 &payload
->buffer
, &lookup_method_comm
, sizeof(lookup_method_comm
));
989 ret
= sizeof(lookup_method_comm
);
994 static int lttng_userspace_probe_location_function_serialize(
995 const struct lttng_userspace_probe_location
*location
, struct lttng_payload
*payload
)
998 size_t function_name_len
, binary_path_len
;
999 struct lttng_userspace_probe_location_function
*location_function
;
1000 struct lttng_userspace_probe_location_function_comm location_function_comm
;
1002 LTTNG_ASSERT(location
);
1003 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1004 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1006 location_function
= lttng::utils::container_of(
1007 location
, <tng_userspace_probe_location_function::parent
);
1008 if (!location_function
->function_name
|| !location_function
->binary_path
) {
1009 ret
= -LTTNG_ERR_INVALID
;
1013 if (payload
&& !location_function
->binary_fd_handle
) {
1014 ret
= -LTTNG_ERR_INVALID
;
1018 function_name_len
= strlen(location_function
->function_name
);
1019 if (function_name_len
== 0) {
1020 ret
= -LTTNG_ERR_INVALID
;
1023 binary_path_len
= strlen(location_function
->binary_path
);
1024 if (binary_path_len
== 0) {
1025 ret
= -LTTNG_ERR_INVALID
;
1029 location_function_comm
.function_name_len
= function_name_len
+ 1;
1030 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
1033 ret
= lttng_dynamic_buffer_append(
1034 &payload
->buffer
, &location_function_comm
, sizeof(location_function_comm
));
1036 ret
= -LTTNG_ERR_INVALID
;
1039 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1040 location_function
->function_name
,
1041 location_function_comm
.function_name_len
);
1043 ret
= -LTTNG_ERR_INVALID
;
1046 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1047 location_function
->binary_path
,
1048 location_function_comm
.binary_path_len
);
1050 ret
= -LTTNG_ERR_INVALID
;
1053 ret
= lttng_payload_push_fd_handle(payload
, location_function
->binary_fd_handle
);
1055 ret
= -LTTNG_ERR_INVALID
;
1059 ret
= sizeof(location_function_comm
) + location_function_comm
.function_name_len
+
1060 location_function_comm
.binary_path_len
;
1065 static int lttng_userspace_probe_location_tracepoint_serialize(
1066 const struct lttng_userspace_probe_location
*location
, struct lttng_payload
*payload
)
1069 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1070 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1071 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1073 LTTNG_ASSERT(location
);
1074 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1075 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1077 location_tracepoint
= lttng::utils::container_of(
1078 location
, <tng_userspace_probe_location_tracepoint::parent
);
1079 if (!location_tracepoint
->probe_name
|| !location_tracepoint
->provider_name
||
1080 !location_tracepoint
->binary_path
) {
1081 ret
= -LTTNG_ERR_INVALID
;
1085 if (payload
&& !location_tracepoint
->binary_fd_handle
) {
1086 ret
= -LTTNG_ERR_INVALID
;
1090 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1091 if (probe_name_len
== 0) {
1092 ret
= -LTTNG_ERR_INVALID
;
1096 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1097 if (provider_name_len
== 0) {
1098 ret
= -LTTNG_ERR_INVALID
;
1102 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1103 if (binary_path_len
== 0) {
1104 ret
= -LTTNG_ERR_INVALID
;
1108 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1109 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1110 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1113 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1114 &location_tracepoint_comm
,
1115 sizeof(location_tracepoint_comm
));
1117 ret
= -LTTNG_ERR_INVALID
;
1120 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1121 location_tracepoint
->probe_name
,
1122 location_tracepoint_comm
.probe_name_len
);
1124 ret
= -LTTNG_ERR_INVALID
;
1127 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1128 location_tracepoint
->provider_name
,
1129 location_tracepoint_comm
.provider_name_len
);
1131 ret
= -LTTNG_ERR_INVALID
;
1134 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1135 location_tracepoint
->binary_path
,
1136 location_tracepoint_comm
.binary_path_len
);
1138 ret
= -LTTNG_ERR_INVALID
;
1141 ret
= lttng_payload_push_fd_handle(payload
, location_tracepoint
->binary_fd_handle
);
1143 ret
= -LTTNG_ERR_INVALID
;
1148 ret
= sizeof(location_tracepoint_comm
) + location_tracepoint_comm
.probe_name_len
+
1149 location_tracepoint_comm
.provider_name_len
+
1150 location_tracepoint_comm
.binary_path_len
;
1155 int lttng_userspace_probe_location_serialize(const struct lttng_userspace_probe_location
*location
,
1156 struct lttng_payload
*payload
)
1158 int ret
, buffer_use
= 0;
1159 struct lttng_userspace_probe_location_comm location_generic_comm
;
1162 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
1163 ret
= -LTTNG_ERR_INVALID
;
1167 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1169 location_generic_comm
.type
= (int8_t) location
->type
;
1171 ret
= lttng_dynamic_buffer_append(
1172 &payload
->buffer
, &location_generic_comm
, sizeof(location_generic_comm
));
1177 buffer_use
+= sizeof(location_generic_comm
);
1179 switch (lttng_userspace_probe_location_get_type(location
)) {
1180 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1181 ret
= lttng_userspace_probe_location_function_serialize(location
, payload
);
1183 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1184 ret
= lttng_userspace_probe_location_tracepoint_serialize(location
, payload
);
1187 ERR("Unsupported probe location type");
1188 ret
= -LTTNG_ERR_INVALID
;
1196 ret
= lttng_userspace_probe_location_lookup_method_serialize(location
->lookup_method
,
1206 static int lttng_userspace_probe_location_function_create_from_payload(
1207 struct lttng_payload_view
*view
, struct lttng_userspace_probe_location
**location
)
1209 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1210 const char *function_name_src
, *binary_path_src
;
1211 char *function_name
= nullptr, *binary_path
= nullptr;
1213 size_t expected_size
;
1214 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1216 LTTNG_ASSERT(location
);
1218 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1219 ret
= -LTTNG_ERR_INVALID
;
1223 location_function_comm
= (typeof(location_function_comm
)) view
->buffer
.data
;
1225 expected_size
= sizeof(*location_function_comm
) +
1226 location_function_comm
->function_name_len
+ location_function_comm
->binary_path_len
;
1228 if (view
->buffer
.size
< expected_size
) {
1229 ret
= -LTTNG_ERR_INVALID
;
1233 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1234 binary_path_src
= function_name_src
+ location_function_comm
->function_name_len
;
1236 if (!lttng_buffer_view_contains_string(
1237 &view
->buffer
, function_name_src
, location_function_comm
->function_name_len
)) {
1238 ret
= -LTTNG_ERR_INVALID
;
1242 if (!lttng_buffer_view_contains_string(
1243 &view
->buffer
, binary_path_src
, location_function_comm
->binary_path_len
)) {
1244 ret
= -LTTNG_ERR_INVALID
;
1248 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1249 if (!function_name
) {
1250 PERROR("lttng_strndup");
1251 ret
= -LTTNG_ERR_NOMEM
;
1255 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1257 PERROR("lttng_strndup");
1258 ret
= -LTTNG_ERR_NOMEM
;
1262 *location
= lttng_userspace_probe_location_function_create_no_check(
1263 binary_path
, function_name
, nullptr, false);
1265 ret
= -LTTNG_ERR_INVALID
;
1269 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(*location
,
1272 ret
= -LTTNG_ERR_INVALID
;
1276 ret
= (int) expected_size
;
1278 fd_handle_put(binary_fd_handle
);
1279 free(function_name
);
1284 static int lttng_userspace_probe_location_tracepoint_create_from_payload(
1285 struct lttng_payload_view
*view
, struct lttng_userspace_probe_location
**location
)
1287 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1288 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1289 char *probe_name
= nullptr, *provider_name
= nullptr, *binary_path
= nullptr;
1291 size_t expected_size
;
1292 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1294 LTTNG_ASSERT(location
);
1296 if (!binary_fd_handle
) {
1297 ret
= -LTTNG_ERR_INVALID
;
1301 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1302 ret
= -LTTNG_ERR_INVALID
;
1306 location_tracepoint_comm
= (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1308 expected_size
= sizeof(*location_tracepoint_comm
) +
1309 location_tracepoint_comm
->probe_name_len
+
1310 location_tracepoint_comm
->provider_name_len
+
1311 location_tracepoint_comm
->binary_path_len
;
1313 if (view
->buffer
.size
< expected_size
) {
1314 ret
= -LTTNG_ERR_INVALID
;
1318 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1319 provider_name_src
= probe_name_src
+ location_tracepoint_comm
->probe_name_len
;
1320 binary_path_src
= provider_name_src
+ location_tracepoint_comm
->provider_name_len
;
1322 if (!lttng_buffer_view_contains_string(
1323 &view
->buffer
, probe_name_src
, location_tracepoint_comm
->probe_name_len
)) {
1324 ret
= -LTTNG_ERR_INVALID
;
1328 if (!lttng_buffer_view_contains_string(&view
->buffer
,
1330 location_tracepoint_comm
->provider_name_len
)) {
1331 ret
= -LTTNG_ERR_INVALID
;
1335 if (!lttng_buffer_view_contains_string(
1336 &view
->buffer
, binary_path_src
, location_tracepoint_comm
->binary_path_len
)) {
1337 ret
= -LTTNG_ERR_INVALID
;
1341 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1343 PERROR("Failed to allocate probe name");
1344 ret
= -LTTNG_ERR_INVALID
;
1347 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1348 if (!provider_name
) {
1349 PERROR("Failed to allocate provider name");
1350 ret
= -LTTNG_ERR_INVALID
;
1354 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1356 PERROR("Failed to allocate binary path");
1357 ret
= -LTTNG_ERR_INVALID
;
1361 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1362 binary_path
, provider_name
, probe_name
, nullptr, false);
1364 ret
= -LTTNG_ERR_INVALID
;
1368 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(*location
,
1371 ret
= -LTTNG_ERR_INVALID
;
1375 ret
= (int) expected_size
;
1377 fd_handle_put(binary_fd_handle
);
1379 free(provider_name
);
1384 static int lttng_userspace_probe_location_lookup_method_create_from_payload(
1385 struct lttng_payload_view
*view
,
1386 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1389 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1390 enum lttng_userspace_probe_location_lookup_method_type type
;
1393 LTTNG_ASSERT(lookup_method
);
1395 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1396 ret
= -LTTNG_ERR_INVALID
;
1400 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1401 type
= (enum lttng_userspace_probe_location_lookup_method_type
) lookup_comm
->type
;
1403 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1404 *lookup_method
= nullptr;
1406 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1407 *lookup_method
= lttng_userspace_probe_location_lookup_method_function_elf_create();
1408 if (!(*lookup_method
)) {
1409 ret
= -LTTNG_ERR_INVALID
;
1413 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1415 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1416 if (!(*lookup_method
)) {
1417 ret
= -LTTNG_ERR_INVALID
;
1422 ret
= -LTTNG_ERR_INVALID
;
1426 ret
= sizeof(*lookup_comm
);
1431 int lttng_userspace_probe_location_create_from_payload(
1432 struct lttng_payload_view
*view
, struct lttng_userspace_probe_location
**location
)
1434 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1435 enum lttng_userspace_probe_location_type type
;
1438 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1439 const lttng_payload_view probe_location_comm_view
=
1440 lttng_payload_view_from_view(view
, 0, sizeof(*probe_location_comm
));
1443 LTTNG_ASSERT(location
);
1445 lookup_method
= nullptr;
1447 if (!lttng_payload_view_is_valid(&probe_location_comm_view
)) {
1448 ret
= -LTTNG_ERR_INVALID
;
1452 probe_location_comm
= (typeof(probe_location_comm
)) probe_location_comm_view
.buffer
.data
;
1453 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1454 consumed
+= sizeof(*probe_location_comm
);
1457 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1459 struct lttng_payload_view location_view
=
1460 lttng_payload_view_from_view(view
, consumed
, -1);
1462 ret
= lttng_userspace_probe_location_function_create_from_payload(&location_view
,
1469 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1471 struct lttng_payload_view location_view
=
1472 lttng_payload_view_from_view(view
, consumed
, -1);
1474 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(&location_view
,
1482 ret
= -LTTNG_ERR_INVALID
;
1487 if (view
->buffer
.size
<= consumed
) {
1488 ret
= -LTTNG_ERR_INVALID
;
1493 struct lttng_payload_view lookup_method_view
=
1494 lttng_payload_view_from_view(view
, consumed
, -1);
1496 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1497 &lookup_method_view
, &lookup_method
);
1500 ret
= -LTTNG_ERR_INVALID
;
1504 LTTNG_ASSERT(lookup_method
);
1505 (*location
)->lookup_method
= lookup_method
;
1506 lookup_method
= nullptr;
1512 static int lttng_userspace_probe_location_function_set_binary_fd_handle(
1513 struct lttng_userspace_probe_location
*location
, struct fd_handle
*binary_fd
)
1516 struct lttng_userspace_probe_location_function
*function_location
;
1518 LTTNG_ASSERT(location
);
1519 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1521 function_location
= lttng::utils::container_of(
1522 location
, <tng_userspace_probe_location_function::parent
);
1523 fd_handle_put(function_location
->binary_fd_handle
);
1524 fd_handle_get(binary_fd
);
1525 function_location
->binary_fd_handle
= binary_fd
;
1529 static int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1530 struct lttng_userspace_probe_location
*location
, struct fd_handle
*binary_fd
)
1533 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1535 LTTNG_ASSERT(location
);
1536 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1538 tracepoint_location
= lttng::utils::container_of(
1539 location
, <tng_userspace_probe_location_tracepoint::parent
);
1540 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1541 fd_handle_get(binary_fd
);
1542 tracepoint_location
->binary_fd_handle
= binary_fd
;
1546 static int lttng_userspace_probe_location_function_flatten(
1547 const struct lttng_userspace_probe_location
*location
, struct lttng_dynamic_buffer
*buffer
)
1549 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1550 struct lttng_userspace_probe_location_function
*probe_function
;
1551 struct lttng_userspace_probe_location_function flat_probe
;
1552 size_t function_name_len
, binary_path_len
;
1553 size_t padding_needed
= 0;
1554 char *flat_probe_start
;
1555 int storage_needed
= 0;
1558 LTTNG_ASSERT(location
);
1560 if (location
->lookup_method
&&
1561 location
->lookup_method
->type
!=
1562 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1563 ret
= -LTTNG_ERR_INVALID
;
1567 probe_function
= lttng::utils::container_of(
1568 location
, <tng_userspace_probe_location_function::parent
);
1569 LTTNG_ASSERT(probe_function
->function_name
);
1570 LTTNG_ASSERT(probe_function
->binary_path
);
1572 storage_needed
+= sizeof(struct lttng_userspace_probe_location_function
);
1573 function_name_len
= strlen(probe_function
->function_name
) + 1;
1574 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1575 storage_needed
+= function_name_len
+ binary_path_len
;
1578 * The lookup method is aligned to 64-bit within the buffer.
1579 * This is needed even if there is no lookup method since
1580 * the next structure in the buffer probably needs to be
1581 * aligned too (depending on the arch).
1583 padding_needed
= lttng_align_ceil(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1584 storage_needed
+= padding_needed
;
1586 if (location
->lookup_method
) {
1587 /* NOTE: elf look-up method is assumed here. */
1588 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1592 ret
= storage_needed
;
1596 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1597 ret
= lttng_dynamic_buffer_set_capacity(buffer
, buffer
->size
+ storage_needed
);
1603 memset(&flat_probe
, 0, sizeof(flat_probe
));
1605 flat_probe_start
= buffer
->data
+ buffer
->size
;
1606 flat_probe
.parent
.type
= location
->type
;
1608 * The lookup method, if present, is the last element in the flat
1609 * representation of the probe.
1611 if (location
->lookup_method
) {
1612 flat_probe
.parent
.lookup_method
=
1613 (struct lttng_userspace_probe_location_lookup_method
1614 *) (flat_probe_start
+ sizeof(flat_probe
) + function_name_len
+
1615 binary_path_len
+ padding_needed
);
1617 flat_probe
.parent
.lookup_method
= nullptr;
1620 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1621 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1622 flat_probe
.binary_fd_handle
= nullptr;
1623 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1628 ret
= lttng_dynamic_buffer_append(buffer
, probe_function
->function_name
, function_name_len
);
1632 ret
= lttng_dynamic_buffer_append(buffer
, probe_function
->binary_path
, binary_path_len
);
1637 /* Insert padding before the lookup method. */
1638 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1643 if (!location
->lookup_method
) {
1644 /* Not an error, the default method is used. */
1645 ret
= storage_needed
;
1649 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1650 flat_lookup_method
.parent
.type
=
1651 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1652 ret
= lttng_dynamic_buffer_append(buffer
, &flat_lookup_method
, sizeof(flat_lookup_method
));
1656 ret
= storage_needed
;
1661 static int lttng_userspace_probe_location_tracepoint_flatten(
1662 const struct lttng_userspace_probe_location
*location
, struct lttng_dynamic_buffer
*buffer
)
1664 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1665 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1666 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1667 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1668 size_t padding_needed
= 0;
1669 int storage_needed
= 0;
1670 char *flat_probe_start
;
1673 LTTNG_ASSERT(location
);
1675 /* Only SDT tracepoints are supported at the moment */
1676 if (location
->lookup_method
&&
1677 location
->lookup_method
->type
!=
1678 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1679 ret
= -LTTNG_ERR_INVALID
;
1682 probe_tracepoint
= lttng::utils::container_of(
1683 location
, <tng_userspace_probe_location_tracepoint::parent
);
1684 LTTNG_ASSERT(probe_tracepoint
->probe_name
);
1685 LTTNG_ASSERT(probe_tracepoint
->provider_name
);
1686 LTTNG_ASSERT(probe_tracepoint
->binary_path
);
1688 /* Compute the storage space needed to flatten the probe location */
1689 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1691 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1692 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1693 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1695 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1698 * The lookup method is aligned to 64-bit within the buffer.
1699 * This is needed even if there is no lookup method since
1700 * the next structure in the buffer probably needs to be
1701 * aligned too (depending on the arch).
1703 padding_needed
= lttng_align_ceil(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1704 storage_needed
+= padding_needed
;
1706 if (location
->lookup_method
) {
1707 /* NOTE: elf look-up method is assumed here. */
1708 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1712 * If the caller set buffer to NULL, return the size of the needed buffer.
1715 ret
= storage_needed
;
1719 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1720 ret
= lttng_dynamic_buffer_set_capacity(buffer
, buffer
->size
+ storage_needed
);
1726 memset(&flat_probe
, 0, sizeof(flat_probe
));
1728 flat_probe_start
= buffer
->data
+ buffer
->size
;
1729 flat_probe
.parent
.type
= location
->type
;
1732 * The lookup method, if present, is the last element in the flat
1733 * representation of the probe.
1735 if (location
->lookup_method
) {
1736 flat_probe
.parent
.lookup_method
=
1737 (struct lttng_userspace_probe_location_lookup_method
1738 *) (flat_probe_start
+ sizeof(flat_probe
) + probe_name_len
+
1739 provider_name_len
+ binary_path_len
+ padding_needed
);
1741 flat_probe
.parent
.lookup_method
= nullptr;
1744 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1745 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1746 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1747 flat_probe
.binary_fd_handle
= nullptr;
1748 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1753 /* Append all the fields to the buffer */
1754 ret
= lttng_dynamic_buffer_append(buffer
, probe_tracepoint
->probe_name
, probe_name_len
);
1758 ret
= lttng_dynamic_buffer_append(
1759 buffer
, probe_tracepoint
->provider_name
, provider_name_len
);
1763 ret
= lttng_dynamic_buffer_append(buffer
, probe_tracepoint
->binary_path
, binary_path_len
);
1768 /* Insert padding before the lookup method. */
1769 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1774 if (!location
->lookup_method
) {
1775 /* Not an error, the default method is used. */
1776 ret
= storage_needed
;
1780 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1782 flat_lookup_method
.parent
.type
=
1783 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1784 ret
= lttng_dynamic_buffer_append(buffer
, &flat_lookup_method
, sizeof(flat_lookup_method
));
1788 ret
= storage_needed
;
1793 int lttng_userspace_probe_location_flatten(const struct lttng_userspace_probe_location
*location
,
1794 struct lttng_dynamic_buffer
*buffer
)
1798 ret
= -LTTNG_ERR_INVALID
;
1802 /* Only types currently supported. */
1803 switch (location
->type
) {
1804 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1805 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1807 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1808 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1811 ret
= -LTTNG_ERR_INVALID
;
1819 struct lttng_userspace_probe_location
*
1820 lttng_userspace_probe_location_copy(const struct lttng_userspace_probe_location
*location
)
1822 struct lttng_userspace_probe_location
*new_location
= nullptr;
1823 enum lttng_userspace_probe_location_type type
;
1829 type
= lttng_userspace_probe_location_get_type(location
);
1831 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1832 new_location
= lttng_userspace_probe_location_function_copy(location
);
1833 if (!new_location
) {
1837 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1838 new_location
= lttng_userspace_probe_location_tracepoint_copy(location
);
1839 if (!new_location
) {
1844 new_location
= nullptr;
1848 return new_location
;
1851 bool lttng_userspace_probe_location_lookup_method_is_equal(
1852 const struct lttng_userspace_probe_location_lookup_method
*a
,
1853 const struct lttng_userspace_probe_location_lookup_method
*b
)
1855 bool is_equal
= false;
1866 if (a
->type
!= b
->type
) {
1875 bool lttng_userspace_probe_location_is_equal(const struct lttng_userspace_probe_location
*a
,
1876 const struct lttng_userspace_probe_location
*b
)
1878 bool is_equal
= false;
1889 if (!lttng_userspace_probe_location_lookup_method_is_equal(a
->lookup_method
,
1890 b
->lookup_method
)) {
1894 if (a
->type
!= b
->type
) {
1898 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1904 lttng_userspace_probe_location_hash(const struct lttng_userspace_probe_location
*location
)
1906 return location
->hash(location
);
1909 enum lttng_error_code
1910 lttng_userspace_probe_location_mi_serialize(const struct lttng_userspace_probe_location
*location
,
1911 struct mi_writer
*writer
)
1913 using mi_fp
= enum lttng_error_code (*)(const struct lttng_userspace_probe_location
*,
1914 struct mi_writer
*);
1917 enum lttng_error_code ret_code
;
1918 mi_fp mi_function
= nullptr;
1920 LTTNG_ASSERT(location
);
1921 LTTNG_ASSERT(writer
);
1923 switch (lttng_userspace_probe_location_get_type(location
)) {
1924 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1925 mi_function
= lttng_userspace_probe_location_function_mi_serialize
;
1927 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1928 mi_function
= lttng_userspace_probe_location_tracepoint_mi_serialize
;
1935 /* Open userspace probe location element. */
1936 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_userspace_probe_location
);
1941 /* Underlying user space probe location. */
1942 ret_code
= mi_function(location
, writer
);
1943 if (ret_code
!= LTTNG_OK
) {
1947 /* Close userspace probe location element. */
1948 ret
= mi_lttng_writer_close_element(writer
);
1953 ret_code
= LTTNG_OK
;
1957 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1962 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
1963 const struct lttng_userspace_probe_location_lookup_method
*method
, struct mi_writer
*writer
)
1966 enum lttng_error_code ret_code
;
1967 const char *type_element_str
;
1969 LTTNG_ASSERT(method
);
1970 LTTNG_ASSERT(writer
);
1972 switch (lttng_userspace_probe_location_lookup_method_get_type(method
)) {
1973 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1975 mi_lttng_element_userspace_probe_location_lookup_method_function_default
;
1977 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1979 mi_lttng_element_userspace_probe_location_lookup_method_function_elf
;
1981 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1983 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt
;
1990 /* Open userspace probe location lookup method element. */
1991 ret
= mi_lttng_writer_open_element(writer
,
1992 mi_lttng_element_userspace_probe_location_lookup_method
);
1997 /* User space probe location lookup method empty element. */
1998 ret
= mi_lttng_writer_open_element(writer
, type_element_str
);
2003 /* Close userspace probe location lookup method element. */
2004 ret
= mi_lttng_close_multi_element(writer
, 2);
2009 ret_code
= LTTNG_OK
;
2013 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2018 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
2019 const struct lttng_userspace_probe_location
*location
, struct mi_writer
*writer
)
2022 enum lttng_error_code ret_code
;
2023 const char *probe_name
= nullptr;
2024 const char *provider_name
= nullptr;
2025 const char *binary_path
= nullptr;
2026 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
= nullptr;
2028 LTTNG_ASSERT(location
);
2029 LTTNG_ASSERT(writer
);
2031 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
2032 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
2033 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
2034 lookup_method
= lttng_userspace_probe_location_tracepoint_get_lookup_method(location
);
2036 /* Open userspace probe location tracepoint element. */
2037 ret
= mi_lttng_writer_open_element(writer
,
2038 mi_lttng_element_userspace_probe_location_tracepoint
);
2044 ret
= mi_lttng_writer_write_element_string(
2046 mi_lttng_element_userspace_probe_location_tracepoint_probe_name
,
2052 /* Provider name. */
2053 ret
= mi_lttng_writer_write_element_string(
2055 mi_lttng_element_userspace_probe_location_tracepoint_provider_name
,
2062 ret
= mi_lttng_writer_write_element_string(
2063 writer
, mi_lttng_element_userspace_probe_location_binary_path
, binary_path
);
2068 /* The lookup method. */
2069 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(lookup_method
, writer
);
2070 if (ret_code
!= LTTNG_OK
) {
2074 /* Close userspace probe location tracepoint. */
2075 ret
= mi_lttng_writer_close_element(writer
);
2080 ret_code
= LTTNG_OK
;
2084 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2089 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
2090 const struct lttng_userspace_probe_location
*location
, struct mi_writer
*writer
)
2093 enum lttng_error_code ret_code
;
2094 const char *function_name
= nullptr;
2095 const char *binary_path
= nullptr;
2096 const char *instrumentation_type_str
= nullptr;
2097 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
;
2098 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
= nullptr;
2100 LTTNG_ASSERT(location
);
2101 LTTNG_ASSERT(writer
);
2103 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
2104 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
2105 instrumentation_type
=
2106 lttng_userspace_probe_location_function_get_instrumentation_type(location
);
2107 lookup_method
= lttng_userspace_probe_location_function_get_lookup_method(location
);
2109 switch (instrumentation_type
) {
2110 case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
:
2111 instrumentation_type_str
=
2112 mi_lttng_userspace_probe_location_function_instrumentation_type_entry
;
2119 /* Open userspace probe location function element. */
2120 ret
= mi_lttng_writer_open_element(writer
,
2121 mi_lttng_element_userspace_probe_location_function
);
2126 /* Function name. */
2127 ret
= mi_lttng_writer_write_element_string(
2128 writer
, mi_lttng_element_userspace_probe_location_function_name
, function_name
);
2134 ret
= mi_lttng_writer_write_element_string(
2135 writer
, mi_lttng_element_userspace_probe_location_binary_path
, binary_path
);
2140 /* Instrumentation type. */
2141 ret
= mi_lttng_writer_write_element_string(
2143 mi_lttng_element_userspace_probe_location_function_instrumentation_type
,
2144 instrumentation_type_str
);
2149 /* The lookup method. */
2150 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(lookup_method
, writer
);
2151 if (ret_code
!= LTTNG_OK
) {
2155 /* Close userspace probe location function element. */
2156 ret
= mi_lttng_writer_close_element(writer
);
2161 ret_code
= LTTNG_OK
;
2165 ret_code
= LTTNG_ERR_MI_IO_FAIL
;