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"
9 #include <common/compat/string.hpp>
10 #include <common/align.hpp>
11 #include <common/error.hpp>
12 #include <common/hashtable/hashtable.hpp>
13 #include <common/hashtable/utils.hpp>
14 #include <common/macros.hpp>
15 #include <common/mi-lttng.hpp>
16 #include <common/payload-view.hpp>
17 #include <common/payload.hpp>
19 #include <lttng/constant.h>
20 #include <lttng/userspace-probe-internal.hpp>
22 #include <sys/types.h>
26 int lttng_userspace_probe_location_function_set_binary_fd_handle(
27 struct lttng_userspace_probe_location
*location
,
28 struct fd_handle
*binary_fd_handle
);
31 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
32 struct lttng_userspace_probe_location
*location
,
33 struct fd_handle
*binary_fd_handle
);
36 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
37 const struct lttng_userspace_probe_location_lookup_method
39 struct mi_writer
*writer
);
42 enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
43 const struct lttng_userspace_probe_location
*location
,
44 struct mi_writer
*writer
);
47 enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
48 const struct lttng_userspace_probe_location
*location
,
49 struct mi_writer
*writer
);
51 enum lttng_userspace_probe_location_lookup_method_type
52 lttng_userspace_probe_location_lookup_method_get_type(
53 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
55 return lookup_method
? lookup_method
->type
:
56 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
59 void lttng_userspace_probe_location_lookup_method_destroy(
60 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
69 struct lttng_userspace_probe_location_lookup_method
*
70 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
72 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
73 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
75 elf_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_elf
>();
81 ret
= &elf_method
->parent
;
82 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
87 struct lttng_userspace_probe_location_lookup_method
*
88 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
90 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
91 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
93 sdt_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_sdt
>();
99 ret
= &sdt_method
->parent
;
100 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
105 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
106 const struct lttng_userspace_probe_location
*location
)
108 return location
? location
->type
:
109 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
113 void lttng_userspace_probe_location_function_destroy(
114 struct lttng_userspace_probe_location
*location
)
116 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
118 LTTNG_ASSERT(location
);
120 location_function
= container_of(location
,
121 struct lttng_userspace_probe_location_function
, parent
);
123 LTTNG_ASSERT(location_function
);
125 free(location_function
->function_name
);
126 free(location_function
->binary_path
);
127 fd_handle_put(location_function
->binary_fd_handle
);
132 void lttng_userspace_probe_location_tracepoint_destroy(
133 struct lttng_userspace_probe_location
*location
)
135 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
137 LTTNG_ASSERT(location
);
139 location_tracepoint
= container_of(location
,
140 struct lttng_userspace_probe_location_tracepoint
,
143 LTTNG_ASSERT(location_tracepoint
);
145 free(location_tracepoint
->probe_name
);
146 free(location_tracepoint
->provider_name
);
147 free(location_tracepoint
->binary_path
);
148 fd_handle_put(location_tracepoint
->binary_fd_handle
);
152 void lttng_userspace_probe_location_destroy(
153 struct lttng_userspace_probe_location
*location
)
159 lttng_userspace_probe_location_lookup_method_destroy(
160 location
->lookup_method
);
162 switch (location
->type
) {
163 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
164 lttng_userspace_probe_location_function_destroy(location
);
166 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
167 lttng_userspace_probe_location_tracepoint_destroy(location
);
174 /* Compare two file descriptors based on their inode and device numbers. */
175 static bool fd_is_equal(int a
, int b
)
178 bool is_equal
= false;
179 struct stat a_stat
, b_stat
;
181 if (a
< 0 && b
>= 0) {
185 if (b
< 0 && a
>= 0) {
189 if (a
< 0 && b
< 0) {
190 if (a
== -1 && b
== -1) {
195 /* Invalid state, abort. */
199 /* Both are valid file descriptors. */
200 ret
= fstat(a
, &a_stat
);
202 PERROR("Failed to fstat userspace probe location binary fd %d",
207 ret
= fstat(b
, &b_stat
);
209 PERROR("Failed to fstat userspace probe location binary fd %d",
214 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) &&
215 (a_stat
.st_dev
== b_stat
.st_dev
);
221 static unsigned long lttng_userspace_probe_location_function_hash(
222 const struct lttng_userspace_probe_location
*location
)
224 unsigned long hash
= hash_key_ulong(
225 (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
,
227 struct lttng_userspace_probe_location_function
*function_location
=
228 container_of(location
, typeof(*function_location
),
231 hash
^= hash_key_str(function_location
->function_name
, lttng_ht_seed
);
232 hash
^= hash_key_str(function_location
->binary_path
, lttng_ht_seed
);
234 * No need to hash on the fd. Worst comes to worse,
235 * the equal function will discriminate.
240 static bool lttng_userspace_probe_location_function_is_equal(
241 const struct lttng_userspace_probe_location
*_a
,
242 const struct lttng_userspace_probe_location
*_b
)
244 bool is_equal
= false;
245 struct lttng_userspace_probe_location_function
*a
, *b
;
247 a
= container_of(_a
, struct lttng_userspace_probe_location_function
,
249 b
= container_of(_b
, struct lttng_userspace_probe_location_function
,
252 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
256 LTTNG_ASSERT(a
->function_name
);
257 LTTNG_ASSERT(b
->function_name
);
258 if (strcmp(a
->function_name
, b
->function_name
)) {
262 LTTNG_ASSERT(a
->binary_path
);
263 LTTNG_ASSERT(b
->binary_path
);
264 if (strcmp(a
->binary_path
, b
->binary_path
)) {
268 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
269 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
274 static struct lttng_userspace_probe_location
*
275 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
276 const char *function_name
,
277 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
281 struct fd_handle
*binary_fd_handle
= NULL
;
282 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
283 struct lttng_userspace_probe_location
*ret
= NULL
;
284 struct lttng_userspace_probe_location_function
*location
;
287 binary_fd
= open(binary_path
, O_RDONLY
);
289 PERROR("Error opening the binary");
293 binary_fd_handle
= fd_handle_create(binary_fd
);
298 /* Ownership transferred to fd_handle. */
302 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
303 if (!function_name_copy
) {
304 PERROR("Error duplicating the function name");
308 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
309 if (!binary_path_copy
) {
310 PERROR("Error duplicating the function name");
314 location
= zmalloc
<lttng_userspace_probe_location_function
>();
316 PERROR("Error allocating userspace probe location");
320 location
->function_name
= function_name_copy
;
321 location
->binary_path
= binary_path_copy
;
322 location
->binary_fd_handle
= binary_fd_handle
;
323 binary_fd_handle
= NULL
;
324 location
->instrumentation_type
=
325 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
327 ret
= &location
->parent
;
328 ret
->lookup_method
= lookup_method
;
329 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
330 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
331 ret
->hash
= lttng_userspace_probe_location_function_hash
;
335 free(function_name_copy
);
336 free(binary_path_copy
);
337 if (binary_fd
>= 0) {
338 if (close(binary_fd
)) {
339 PERROR("Error closing binary fd in error path");
342 fd_handle_put(binary_fd_handle
);
347 static unsigned long lttng_userspace_probe_location_tracepoint_hash(
348 const struct lttng_userspace_probe_location
*location
)
350 unsigned long hash
= hash_key_ulong(
351 (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
,
353 struct lttng_userspace_probe_location_tracepoint
*tp_location
=
354 container_of(location
, typeof(*tp_location
), parent
);
356 hash
^= hash_key_str(tp_location
->probe_name
, lttng_ht_seed
);
357 hash
^= hash_key_str(tp_location
->provider_name
, lttng_ht_seed
);
358 hash
^= hash_key_str(tp_location
->binary_path
, lttng_ht_seed
);
360 * No need to hash on the fd. Worst comes to worse,
361 * the equal function will discriminate.
366 static bool lttng_userspace_probe_location_tracepoint_is_equal(
367 const struct lttng_userspace_probe_location
*_a
,
368 const struct lttng_userspace_probe_location
*_b
)
370 bool is_equal
= false;
371 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
373 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
,
375 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
,
378 LTTNG_ASSERT(a
->probe_name
);
379 LTTNG_ASSERT(b
->probe_name
);
380 if (strcmp(a
->probe_name
, b
->probe_name
)) {
384 LTTNG_ASSERT(a
->provider_name
);
385 LTTNG_ASSERT(b
->provider_name
);
386 if (strcmp(a
->provider_name
, b
->provider_name
)) {
390 LTTNG_ASSERT(a
->binary_path
);
391 LTTNG_ASSERT(b
->binary_path
);
392 if (strcmp(a
->binary_path
, b
->binary_path
)) {
396 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
397 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
403 static struct lttng_userspace_probe_location
*
404 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
405 const char *provider_name
, const char *probe_name
,
406 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
410 struct fd_handle
*binary_fd_handle
= NULL
;
411 char *probe_name_copy
= NULL
;
412 char *provider_name_copy
= NULL
;
413 char *binary_path_copy
= NULL
;
414 struct lttng_userspace_probe_location
*ret
= NULL
;
415 struct lttng_userspace_probe_location_tracepoint
*location
;
418 binary_fd
= open(binary_path
, O_RDONLY
);
424 binary_fd_handle
= fd_handle_create(binary_fd
);
429 /* Ownership transferred to fd_handle. */
433 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
434 if (!probe_name_copy
) {
435 PERROR("lttng_strndup");
439 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
440 if (!provider_name_copy
) {
441 PERROR("lttng_strndup");
445 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
446 if (!binary_path_copy
) {
447 PERROR("lttng_strndup");
451 location
= zmalloc
<lttng_userspace_probe_location_tracepoint
>();
457 location
->probe_name
= probe_name_copy
;
458 location
->provider_name
= provider_name_copy
;
459 location
->binary_path
= binary_path_copy
;
460 location
->binary_fd_handle
= binary_fd_handle
;
461 binary_fd_handle
= NULL
;
463 ret
= &location
->parent
;
464 ret
->lookup_method
= lookup_method
;
465 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
466 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
467 ret
->hash
= lttng_userspace_probe_location_tracepoint_hash
;
471 free(probe_name_copy
);
472 free(provider_name_copy
);
473 free(binary_path_copy
);
474 if (binary_fd
>= 0) {
475 if (close(binary_fd
)) {
476 PERROR("Error closing binary fd in error path");
479 fd_handle_put(binary_fd_handle
);
484 struct lttng_userspace_probe_location
*
485 lttng_userspace_probe_location_function_create(const char *binary_path
,
486 const char *function_name
,
487 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
489 struct lttng_userspace_probe_location
*ret
= NULL
;
491 if (!binary_path
|| !function_name
) {
492 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
496 switch (lttng_userspace_probe_location_lookup_method_get_type(
498 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
499 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
502 /* Invalid probe location lookup method. */
506 ret
= lttng_userspace_probe_location_function_create_no_check(
507 binary_path
, function_name
, lookup_method
, true);
512 struct lttng_userspace_probe_location
*
513 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
514 const char *provider_name
, const char *probe_name
,
515 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
517 struct lttng_userspace_probe_location
*ret
= NULL
;
519 if (!binary_path
|| !probe_name
|| !provider_name
) {
520 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
524 switch (lttng_userspace_probe_location_lookup_method_get_type(
526 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
529 /* Invalid probe location lookup method. */
533 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
534 binary_path
, provider_name
, probe_name
, lookup_method
, true);
539 static struct lttng_userspace_probe_location_lookup_method
*
540 lttng_userspace_probe_location_lookup_method_function_elf_copy(
541 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
543 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
544 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
546 LTTNG_ASSERT(lookup_method
);
547 LTTNG_ASSERT(lookup_method
->type
==
548 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
550 elf_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_elf
>();
552 PERROR("Error allocating ELF userspace probe lookup method");
556 elf_method
->parent
.type
= lookup_method
->type
;
557 parent
= &elf_method
->parent
;
566 static struct lttng_userspace_probe_location_lookup_method
*
567 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
568 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
570 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
571 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
573 LTTNG_ASSERT(lookup_method
);
574 LTTNG_ASSERT(lookup_method
->type
==
575 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
577 sdt_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_sdt
>();
583 sdt_method
->parent
.type
= lookup_method
->type
;
584 parent
= &sdt_method
->parent
;
594 static struct lttng_userspace_probe_location
*
595 lttng_userspace_probe_location_function_copy(
596 const struct lttng_userspace_probe_location
*location
)
598 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
599 struct lttng_userspace_probe_location
*new_location
= NULL
;
600 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
601 const char *binary_path
= NULL
;
602 const char *function_name
= NULL
;
603 struct lttng_userspace_probe_location_function
*function_location
;
605 LTTNG_ASSERT(location
);
606 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
607 function_location
= container_of(
608 location
, typeof(*function_location
), parent
);
610 /* Get probe location fields */
611 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
613 ERR("Userspace probe binary path is NULL");
617 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
618 if (!function_name
) {
619 ERR("Userspace probe function name is NULL");
624 * Duplicate probe location method fields
626 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
627 location
->lookup_method
);
628 switch (lookup_type
) {
629 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
631 lttng_userspace_probe_location_lookup_method_function_elf_copy(
632 location
->lookup_method
);
633 if (!lookup_method
) {
638 /* Invalid probe location lookup method. */
642 /* Create the probe_location */
643 new_location
= lttng_userspace_probe_location_function_create_no_check(
644 binary_path
, function_name
, lookup_method
, false);
646 goto destroy_lookup_method
;
649 /* Set the duplicated fd to the new probe_location */
650 if (lttng_userspace_probe_location_function_set_binary_fd_handle(new_location
,
651 function_location
->binary_fd_handle
) < 0) {
652 goto destroy_probe_location
;
657 destroy_probe_location
:
658 lttng_userspace_probe_location_destroy(new_location
);
659 destroy_lookup_method
:
660 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
667 static struct lttng_userspace_probe_location
*
668 lttng_userspace_probe_location_tracepoint_copy(
669 const struct lttng_userspace_probe_location
*location
)
671 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
672 struct lttng_userspace_probe_location
*new_location
= NULL
;
673 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
674 const char *binary_path
= NULL
;
675 const char *probe_name
= NULL
;
676 const char *provider_name
= NULL
;
677 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
679 LTTNG_ASSERT(location
);
680 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
681 tracepoint_location
= container_of(
682 location
, typeof(*tracepoint_location
), parent
);
684 /* Get probe location fields */
685 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
687 ERR("Userspace probe binary path is NULL");
691 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
693 ERR("Userspace probe probe name is NULL");
697 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
698 if (!provider_name
) {
699 ERR("Userspace probe provider name is NULL");
704 * Duplicate probe location method fields
706 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
707 location
->lookup_method
);
708 switch (lookup_type
) {
709 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
711 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
712 location
->lookup_method
);
713 if (!lookup_method
) {
718 /* Invalid probe location lookup method. */
722 /* Create the probe_location */
723 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
724 binary_path
, provider_name
, probe_name
, lookup_method
, false);
726 goto destroy_lookup_method
;
729 /* Set the duplicated fd to the new probe_location */
730 if (lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(new_location
,
731 tracepoint_location
->binary_fd_handle
) < 0) {
732 goto destroy_probe_location
;
737 destroy_probe_location
:
738 lttng_userspace_probe_location_destroy(new_location
);
739 destroy_lookup_method
:
740 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
747 const char *lttng_userspace_probe_location_function_get_binary_path(
748 const struct lttng_userspace_probe_location
*location
)
750 const char *ret
= NULL
;
751 struct lttng_userspace_probe_location_function
*function_location
;
753 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
754 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
755 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
759 function_location
= container_of(location
,
760 struct lttng_userspace_probe_location_function
,
762 ret
= function_location
->binary_path
;
767 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
768 const struct lttng_userspace_probe_location
*location
)
770 const char *ret
= NULL
;
771 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
773 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
774 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
775 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
779 tracepoint_location
= container_of(location
,
780 struct lttng_userspace_probe_location_tracepoint
,
782 ret
= tracepoint_location
->binary_path
;
787 const char *lttng_userspace_probe_location_function_get_function_name(
788 const struct lttng_userspace_probe_location
*location
)
790 const char *ret
= NULL
;
791 struct lttng_userspace_probe_location_function
*function_location
;
793 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
794 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
795 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
799 function_location
= container_of(location
,
800 struct lttng_userspace_probe_location_function
, parent
);
801 ret
= function_location
->function_name
;
806 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
807 const struct lttng_userspace_probe_location
*location
)
809 const char *ret
= NULL
;
810 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
812 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
813 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
814 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
818 tracepoint_location
= container_of(location
,
819 struct lttng_userspace_probe_location_tracepoint
, parent
);
820 ret
= tracepoint_location
->probe_name
;
825 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
826 const struct lttng_userspace_probe_location
*location
)
828 const char *ret
= NULL
;
829 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
831 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
832 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
833 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
837 tracepoint_location
= container_of(location
,
838 struct lttng_userspace_probe_location_tracepoint
, parent
);
839 ret
= tracepoint_location
->provider_name
;
844 int lttng_userspace_probe_location_function_get_binary_fd(
845 const struct lttng_userspace_probe_location
*location
)
848 struct lttng_userspace_probe_location_function
*function_location
;
850 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
851 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
852 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
856 function_location
= container_of(location
,
857 struct lttng_userspace_probe_location_function
, parent
);
858 ret
= function_location
->binary_fd_handle
?
859 fd_handle_get_fd(function_location
->binary_fd_handle
) : -1;
864 enum lttng_userspace_probe_location_function_instrumentation_type
865 lttng_userspace_probe_location_function_get_instrumentation_type(
866 const struct lttng_userspace_probe_location
*location
)
868 enum lttng_userspace_probe_location_function_instrumentation_type type
;
869 struct lttng_userspace_probe_location_function
*function_location
;
871 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
872 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
873 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
874 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
878 function_location
= container_of(location
,
879 struct lttng_userspace_probe_location_function
, parent
);
880 type
= function_location
->instrumentation_type
;
885 enum lttng_userspace_probe_location_status
886 lttng_userspace_probe_location_function_set_instrumentation_type(
887 const struct lttng_userspace_probe_location
*location
,
888 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
890 enum lttng_userspace_probe_location_status status
=
891 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
892 struct lttng_userspace_probe_location_function
*function_location
;
894 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
895 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
896 instrumentation_type
!=
897 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
898 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
899 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
903 function_location
= container_of(location
,
904 struct lttng_userspace_probe_location_function
, parent
);
905 function_location
->instrumentation_type
= instrumentation_type
;
910 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
911 const struct lttng_userspace_probe_location
*location
)
914 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
916 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
917 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
918 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
922 tracepoint_location
= container_of(location
,
923 struct lttng_userspace_probe_location_tracepoint
, parent
);
924 ret
= tracepoint_location
->binary_fd_handle
?
925 fd_handle_get_fd(tracepoint_location
->binary_fd_handle
) : -1;
930 static struct lttng_userspace_probe_location_lookup_method
*
931 lttng_userspace_probe_location_function_get_lookup_method(
932 const struct lttng_userspace_probe_location
*location
)
934 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
936 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
937 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
938 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
942 ret
= location
->lookup_method
;
947 static struct lttng_userspace_probe_location_lookup_method
*
948 lttng_userspace_probe_location_tracepoint_get_lookup_method(
949 const struct lttng_userspace_probe_location
*location
)
951 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
953 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
954 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
955 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
959 ret
= location
->lookup_method
;
964 const struct lttng_userspace_probe_location_lookup_method
*
965 lttng_userspace_probe_location_get_lookup_method(
966 const struct lttng_userspace_probe_location
*location
)
968 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
970 LTTNG_ASSERT(location
);
971 switch (location
->type
) {
972 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
973 ret
= lttng_userspace_probe_location_function_get_lookup_method(
976 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
977 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
981 ERR("Unknowned lookup method.");
988 int lttng_userspace_probe_location_lookup_method_serialize(
989 struct lttng_userspace_probe_location_lookup_method
*method
,
990 struct lttng_payload
*payload
)
993 struct lttng_userspace_probe_location_lookup_method_comm
996 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
997 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
999 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &lookup_method_comm
,
1000 sizeof(lookup_method_comm
));
1005 ret
= sizeof(lookup_method_comm
);
1011 int lttng_userspace_probe_location_function_serialize(
1012 const struct lttng_userspace_probe_location
*location
,
1013 struct lttng_payload
*payload
)
1016 size_t function_name_len
, binary_path_len
;
1017 struct lttng_userspace_probe_location_function
*location_function
;
1018 struct lttng_userspace_probe_location_function_comm location_function_comm
;
1020 LTTNG_ASSERT(location
);
1021 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1022 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1024 location_function
= container_of(location
,
1025 struct lttng_userspace_probe_location_function
,
1027 if (!location_function
->function_name
|| !location_function
->binary_path
) {
1028 ret
= -LTTNG_ERR_INVALID
;
1032 if (payload
&& !location_function
->binary_fd_handle
) {
1033 ret
= -LTTNG_ERR_INVALID
;
1037 function_name_len
= strlen(location_function
->function_name
);
1038 if (function_name_len
== 0) {
1039 ret
= -LTTNG_ERR_INVALID
;
1042 binary_path_len
= strlen(location_function
->binary_path
);
1043 if (binary_path_len
== 0) {
1044 ret
= -LTTNG_ERR_INVALID
;
1048 location_function_comm
.function_name_len
= function_name_len
+ 1;
1049 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
1052 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1053 &location_function_comm
,
1054 sizeof(location_function_comm
));
1056 ret
= -LTTNG_ERR_INVALID
;
1059 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1060 location_function
->function_name
,
1061 location_function_comm
.function_name_len
);
1063 ret
= -LTTNG_ERR_INVALID
;
1066 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1067 location_function
->binary_path
,
1068 location_function_comm
.binary_path_len
);
1070 ret
= -LTTNG_ERR_INVALID
;
1073 ret
= lttng_payload_push_fd_handle(
1074 payload
, location_function
->binary_fd_handle
);
1076 ret
= -LTTNG_ERR_INVALID
;
1080 ret
= sizeof(location_function_comm
) +
1081 location_function_comm
.function_name_len
+
1082 location_function_comm
.binary_path_len
;
1088 int lttng_userspace_probe_location_tracepoint_serialize(
1089 const struct lttng_userspace_probe_location
*location
,
1090 struct lttng_payload
*payload
)
1093 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1094 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1095 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1097 LTTNG_ASSERT(location
);
1098 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1099 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1101 location_tracepoint
= container_of(location
,
1102 struct lttng_userspace_probe_location_tracepoint
,
1104 if (!location_tracepoint
->probe_name
||
1105 !location_tracepoint
->provider_name
||
1106 !location_tracepoint
->binary_path
) {
1107 ret
= -LTTNG_ERR_INVALID
;
1111 if (payload
&& !location_tracepoint
->binary_fd_handle
) {
1112 ret
= -LTTNG_ERR_INVALID
;
1116 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1117 if (probe_name_len
== 0) {
1118 ret
= -LTTNG_ERR_INVALID
;
1122 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1123 if (provider_name_len
== 0) {
1124 ret
= -LTTNG_ERR_INVALID
;
1128 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1129 if (binary_path_len
== 0) {
1130 ret
= -LTTNG_ERR_INVALID
;
1134 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1135 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1136 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1139 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1140 &location_tracepoint_comm
,
1141 sizeof(location_tracepoint_comm
));
1143 ret
= -LTTNG_ERR_INVALID
;
1146 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1147 location_tracepoint
->probe_name
,
1148 location_tracepoint_comm
.probe_name_len
);
1150 ret
= -LTTNG_ERR_INVALID
;
1153 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1154 location_tracepoint
->provider_name
,
1155 location_tracepoint_comm
.provider_name_len
);
1157 ret
= -LTTNG_ERR_INVALID
;
1160 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1161 location_tracepoint
->binary_path
,
1162 location_tracepoint_comm
.binary_path_len
);
1164 ret
= -LTTNG_ERR_INVALID
;
1167 ret
= lttng_payload_push_fd_handle(
1168 payload
, location_tracepoint
->binary_fd_handle
);
1170 ret
= -LTTNG_ERR_INVALID
;
1175 ret
= sizeof(location_tracepoint_comm
) +
1176 location_tracepoint_comm
.probe_name_len
+
1177 location_tracepoint_comm
.provider_name_len
+
1178 location_tracepoint_comm
.binary_path_len
;
1183 int lttng_userspace_probe_location_serialize(
1184 const struct lttng_userspace_probe_location
*location
,
1185 struct lttng_payload
*payload
)
1187 int ret
, buffer_use
= 0;
1188 struct lttng_userspace_probe_location_comm location_generic_comm
;
1191 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
1192 ret
= -LTTNG_ERR_INVALID
;
1196 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1198 location_generic_comm
.type
= (int8_t) location
->type
;
1200 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1201 &location_generic_comm
,
1202 sizeof(location_generic_comm
));
1207 buffer_use
+= sizeof(location_generic_comm
);
1209 switch (lttng_userspace_probe_location_get_type(location
)) {
1210 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1211 ret
= lttng_userspace_probe_location_function_serialize(
1214 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1215 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1219 ERR("Unsupported probe location type");
1220 ret
= -LTTNG_ERR_INVALID
;
1228 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1229 location
->lookup_method
, payload
);
1239 int lttng_userspace_probe_location_function_create_from_payload(
1240 struct lttng_payload_view
*view
,
1241 struct lttng_userspace_probe_location
**location
)
1243 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1244 const char *function_name_src
, *binary_path_src
;
1245 char *function_name
= NULL
, *binary_path
= NULL
;
1247 size_t expected_size
;
1248 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1250 LTTNG_ASSERT(location
);
1252 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1253 ret
= -LTTNG_ERR_INVALID
;
1257 location_function_comm
=
1258 (typeof(location_function_comm
)) view
->buffer
.data
;
1260 expected_size
= sizeof(*location_function_comm
) +
1261 location_function_comm
->function_name_len
+
1262 location_function_comm
->binary_path_len
;
1264 if (view
->buffer
.size
< expected_size
) {
1265 ret
= -LTTNG_ERR_INVALID
;
1269 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1270 binary_path_src
= function_name_src
+
1271 location_function_comm
->function_name_len
;
1273 if (!lttng_buffer_view_contains_string(&view
->buffer
, function_name_src
,
1274 location_function_comm
->function_name_len
)) {
1275 ret
= -LTTNG_ERR_INVALID
;
1279 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1280 location_function_comm
->binary_path_len
)) {
1281 ret
= -LTTNG_ERR_INVALID
;
1285 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1286 if (!function_name
) {
1287 PERROR("lttng_strndup");
1288 ret
= -LTTNG_ERR_NOMEM
;
1292 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1294 PERROR("lttng_strndup");
1295 ret
= -LTTNG_ERR_NOMEM
;
1299 *location
= lttng_userspace_probe_location_function_create_no_check(
1300 binary_path
, function_name
, NULL
, false);
1302 ret
= -LTTNG_ERR_INVALID
;
1306 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(
1307 *location
, binary_fd_handle
);
1309 ret
= -LTTNG_ERR_INVALID
;
1313 ret
= (int) expected_size
;
1315 fd_handle_put(binary_fd_handle
);
1316 free(function_name
);
1322 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1323 struct lttng_payload_view
*view
,
1324 struct lttng_userspace_probe_location
**location
)
1326 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1327 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1328 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1330 size_t expected_size
;
1331 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1333 LTTNG_ASSERT(location
);
1335 if (!binary_fd_handle
) {
1336 ret
= -LTTNG_ERR_INVALID
;
1340 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1341 ret
= -LTTNG_ERR_INVALID
;
1345 location_tracepoint_comm
=
1346 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1348 expected_size
= sizeof(*location_tracepoint_comm
) +
1349 location_tracepoint_comm
->probe_name_len
+
1350 location_tracepoint_comm
->provider_name_len
+
1351 location_tracepoint_comm
->binary_path_len
;
1353 if (view
->buffer
.size
< expected_size
) {
1354 ret
= -LTTNG_ERR_INVALID
;
1358 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1359 provider_name_src
= probe_name_src
+
1360 location_tracepoint_comm
->probe_name_len
;
1361 binary_path_src
= provider_name_src
+
1362 location_tracepoint_comm
->provider_name_len
;
1364 if (!lttng_buffer_view_contains_string(&view
->buffer
, probe_name_src
,
1365 location_tracepoint_comm
->probe_name_len
)) {
1366 ret
= -LTTNG_ERR_INVALID
;
1370 if (!lttng_buffer_view_contains_string(&view
->buffer
, provider_name_src
,
1371 location_tracepoint_comm
->provider_name_len
)) {
1372 ret
= -LTTNG_ERR_INVALID
;
1376 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1377 location_tracepoint_comm
->binary_path_len
)) {
1378 ret
= -LTTNG_ERR_INVALID
;
1382 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1384 PERROR("Failed to allocate probe name");
1385 ret
= -LTTNG_ERR_INVALID
;
1388 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1389 if (!provider_name
) {
1390 PERROR("Failed to allocate provider name");
1391 ret
= -LTTNG_ERR_INVALID
;
1395 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1397 PERROR("Failed to allocate binary path");
1398 ret
= -LTTNG_ERR_INVALID
;
1402 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1403 binary_path
, provider_name
, probe_name
, NULL
, false);
1405 ret
= -LTTNG_ERR_INVALID
;
1409 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1410 *location
, binary_fd_handle
);
1412 ret
= -LTTNG_ERR_INVALID
;
1416 ret
= (int) expected_size
;
1418 fd_handle_put(binary_fd_handle
);
1420 free(provider_name
);
1426 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1427 struct lttng_payload_view
*view
,
1428 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1431 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1432 enum lttng_userspace_probe_location_lookup_method_type type
;
1435 LTTNG_ASSERT(lookup_method
);
1437 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1438 ret
= -LTTNG_ERR_INVALID
;
1442 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1443 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1446 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1447 *lookup_method
= NULL
;
1449 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1451 lttng_userspace_probe_location_lookup_method_function_elf_create();
1452 if (!(*lookup_method
)) {
1453 ret
= -LTTNG_ERR_INVALID
;
1457 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1459 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1460 if (!(*lookup_method
)) {
1461 ret
= -LTTNG_ERR_INVALID
;
1466 ret
= -LTTNG_ERR_INVALID
;
1470 ret
= sizeof(*lookup_comm
);
1475 int lttng_userspace_probe_location_create_from_payload(
1476 struct lttng_payload_view
*view
,
1477 struct lttng_userspace_probe_location
**location
)
1479 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1480 enum lttng_userspace_probe_location_type type
;
1483 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1484 struct lttng_payload_view probe_location_comm_view
=
1485 lttng_payload_view_from_view(
1486 view
, 0, sizeof(*probe_location_comm
));
1489 LTTNG_ASSERT(location
);
1491 lookup_method
= NULL
;
1493 if (!lttng_payload_view_is_valid(&probe_location_comm_view
)) {
1494 ret
= -LTTNG_ERR_INVALID
;
1498 probe_location_comm
= (typeof(probe_location_comm
)) probe_location_comm_view
.buffer
.data
;
1499 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1500 consumed
+= sizeof(*probe_location_comm
);
1503 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1505 struct lttng_payload_view location_view
=
1506 lttng_payload_view_from_view(
1507 view
, consumed
, -1);
1509 ret
= lttng_userspace_probe_location_function_create_from_payload(
1510 &location_view
, location
);
1516 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1518 struct lttng_payload_view location_view
=
1519 lttng_payload_view_from_view(view
, consumed
, -1);
1521 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1522 &location_view
, location
);
1529 ret
= -LTTNG_ERR_INVALID
;
1534 if (view
->buffer
.size
<= consumed
) {
1535 ret
= -LTTNG_ERR_INVALID
;
1540 struct lttng_payload_view lookup_method_view
=
1541 lttng_payload_view_from_view(
1542 view
, consumed
, -1);
1544 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1545 &lookup_method_view
, &lookup_method
);
1548 ret
= -LTTNG_ERR_INVALID
;
1552 LTTNG_ASSERT(lookup_method
);
1553 (*location
)->lookup_method
= lookup_method
;
1554 lookup_method
= NULL
;
1561 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1562 struct lttng_userspace_probe_location
*location
,
1563 struct fd_handle
*binary_fd
)
1566 struct lttng_userspace_probe_location_function
*function_location
;
1568 LTTNG_ASSERT(location
);
1569 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1571 function_location
= container_of(location
,
1572 struct lttng_userspace_probe_location_function
, parent
);
1573 fd_handle_put(function_location
->binary_fd_handle
);
1574 fd_handle_get(binary_fd
);
1575 function_location
->binary_fd_handle
= binary_fd
;
1580 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1581 struct lttng_userspace_probe_location
*location
,
1582 struct fd_handle
*binary_fd
)
1585 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1587 LTTNG_ASSERT(location
);
1588 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1590 tracepoint_location
= container_of(location
,
1591 struct lttng_userspace_probe_location_tracepoint
, parent
);
1592 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1593 fd_handle_get(binary_fd
);
1594 tracepoint_location
->binary_fd_handle
= binary_fd
;
1599 int lttng_userspace_probe_location_function_flatten(
1600 const struct lttng_userspace_probe_location
*location
,
1601 struct lttng_dynamic_buffer
*buffer
)
1603 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1604 struct lttng_userspace_probe_location_function
*probe_function
;
1605 struct lttng_userspace_probe_location_function flat_probe
;
1606 size_t function_name_len
, binary_path_len
;
1607 size_t padding_needed
= 0;
1608 char *flat_probe_start
;
1609 int storage_needed
= 0;
1612 LTTNG_ASSERT(location
);
1614 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1615 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1616 ret
= -LTTNG_ERR_INVALID
;
1620 probe_function
= container_of(location
,
1621 struct lttng_userspace_probe_location_function
,
1623 LTTNG_ASSERT(probe_function
->function_name
);
1624 LTTNG_ASSERT(probe_function
->binary_path
);
1627 sizeof(struct lttng_userspace_probe_location_function
);
1628 function_name_len
= strlen(probe_function
->function_name
) + 1;
1629 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1630 storage_needed
+= function_name_len
+ binary_path_len
;
1633 * The lookup method is aligned to 64-bit within the buffer.
1634 * This is needed even if there is no lookup method since
1635 * the next structure in the buffer probably needs to be
1636 * aligned too (depending on the arch).
1638 padding_needed
= lttng_align_ceil(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1639 storage_needed
+= padding_needed
;
1641 if (location
->lookup_method
) {
1642 /* NOTE: elf look-up method is assumed here. */
1643 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1647 ret
= storage_needed
;
1651 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1652 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1653 buffer
->size
+ storage_needed
);
1659 memset(&flat_probe
, 0, sizeof(flat_probe
));
1661 flat_probe_start
= buffer
->data
+ buffer
->size
;
1662 flat_probe
.parent
.type
= location
->type
;
1664 * The lookup method, if present, is the last element in the flat
1665 * representation of the probe.
1667 if (location
->lookup_method
) {
1668 flat_probe
.parent
.lookup_method
=
1669 (struct lttng_userspace_probe_location_lookup_method
*)
1670 (flat_probe_start
+ sizeof(flat_probe
) +
1671 function_name_len
+ binary_path_len
+ padding_needed
);
1673 flat_probe
.parent
.lookup_method
= NULL
;
1676 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1677 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1678 flat_probe
.binary_fd_handle
= NULL
;
1679 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1680 sizeof(flat_probe
));
1685 ret
= lttng_dynamic_buffer_append(buffer
,
1686 probe_function
->function_name
, function_name_len
);
1690 ret
= lttng_dynamic_buffer_append(buffer
,
1691 probe_function
->binary_path
, binary_path_len
);
1696 /* Insert padding before the lookup method. */
1697 ret
= lttng_dynamic_buffer_set_size(buffer
,
1698 buffer
->size
+ padding_needed
);
1703 if (!location
->lookup_method
) {
1704 /* Not an error, the default method is used. */
1705 ret
= storage_needed
;
1709 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1710 flat_lookup_method
.parent
.type
=
1711 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1712 ret
= lttng_dynamic_buffer_append(buffer
,
1713 &flat_lookup_method
, sizeof(flat_lookup_method
));
1717 ret
= storage_needed
;
1723 int lttng_userspace_probe_location_tracepoint_flatten(
1724 const struct lttng_userspace_probe_location
*location
,
1725 struct lttng_dynamic_buffer
*buffer
)
1727 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1728 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1729 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1730 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1731 size_t padding_needed
= 0;
1732 int storage_needed
= 0;
1733 char *flat_probe_start
;
1736 LTTNG_ASSERT(location
);
1738 /* Only SDT tracepoints are supported at the moment */
1739 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1740 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1741 ret
= -LTTNG_ERR_INVALID
;
1744 probe_tracepoint
= container_of(location
,
1745 struct lttng_userspace_probe_location_tracepoint
,
1747 LTTNG_ASSERT(probe_tracepoint
->probe_name
);
1748 LTTNG_ASSERT(probe_tracepoint
->provider_name
);
1749 LTTNG_ASSERT(probe_tracepoint
->binary_path
);
1751 /* Compute the storage space needed to flatten the probe location */
1752 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1754 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1755 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1756 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1758 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1761 * The lookup method is aligned to 64-bit within the buffer.
1762 * This is needed even if there is no lookup method since
1763 * the next structure in the buffer probably needs to be
1764 * aligned too (depending on the arch).
1766 padding_needed
= lttng_align_ceil(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1767 storage_needed
+= padding_needed
;
1769 if (location
->lookup_method
) {
1770 /* NOTE: elf look-up method is assumed here. */
1772 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1776 * If the caller set buffer to NULL, return the size of the needed buffer.
1779 ret
= storage_needed
;
1783 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1784 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1785 buffer
->size
+ storage_needed
);
1791 memset(&flat_probe
, 0, sizeof(flat_probe
));
1793 flat_probe_start
= buffer
->data
+ buffer
->size
;
1794 flat_probe
.parent
.type
= location
->type
;
1797 * The lookup method, if present, is the last element in the flat
1798 * representation of the probe.
1800 if (location
->lookup_method
) {
1801 flat_probe
.parent
.lookup_method
=
1802 (struct lttng_userspace_probe_location_lookup_method
*)
1803 (flat_probe_start
+ sizeof(flat_probe
) +
1804 probe_name_len
+ provider_name_len
+
1805 binary_path_len
+ padding_needed
);
1807 flat_probe
.parent
.lookup_method
= NULL
;
1810 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1811 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1812 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1813 flat_probe
.binary_fd_handle
= NULL
;
1814 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1819 /* Append all the fields to the buffer */
1820 ret
= lttng_dynamic_buffer_append(buffer
,
1821 probe_tracepoint
->probe_name
, probe_name_len
);
1825 ret
= lttng_dynamic_buffer_append(buffer
,
1826 probe_tracepoint
->provider_name
, provider_name_len
);
1830 ret
= lttng_dynamic_buffer_append(buffer
,
1831 probe_tracepoint
->binary_path
, binary_path_len
);
1836 /* Insert padding before the lookup method. */
1837 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1842 if (!location
->lookup_method
) {
1843 /* Not an error, the default method is used. */
1844 ret
= storage_needed
;
1848 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1850 flat_lookup_method
.parent
.type
=
1851 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1852 ret
= lttng_dynamic_buffer_append(buffer
,
1853 &flat_lookup_method
, sizeof(flat_lookup_method
));
1857 ret
= storage_needed
;
1862 int lttng_userspace_probe_location_flatten(
1863 const struct lttng_userspace_probe_location
*location
,
1864 struct lttng_dynamic_buffer
*buffer
)
1868 ret
= -LTTNG_ERR_INVALID
;
1872 /* Only types currently supported. */
1873 switch (location
->type
) {
1874 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1875 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1877 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1878 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1881 ret
= -LTTNG_ERR_INVALID
;
1889 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1890 const struct lttng_userspace_probe_location
*location
)
1892 struct lttng_userspace_probe_location
*new_location
= NULL
;
1893 enum lttng_userspace_probe_location_type type
;
1899 type
= lttng_userspace_probe_location_get_type(location
);
1901 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1903 lttng_userspace_probe_location_function_copy(location
);
1904 if (!new_location
) {
1908 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1910 lttng_userspace_probe_location_tracepoint_copy(location
);
1911 if (!new_location
) {
1916 new_location
= NULL
;
1920 return new_location
;
1923 bool lttng_userspace_probe_location_lookup_method_is_equal(
1924 const struct lttng_userspace_probe_location_lookup_method
*a
,
1925 const struct lttng_userspace_probe_location_lookup_method
*b
)
1927 bool is_equal
= false;
1938 if (a
->type
!= b
->type
) {
1947 bool lttng_userspace_probe_location_is_equal(
1948 const struct lttng_userspace_probe_location
*a
,
1949 const struct lttng_userspace_probe_location
*b
)
1951 bool is_equal
= false;
1962 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1963 a
->lookup_method
, b
->lookup_method
)) {
1967 if (a
->type
!= b
->type
) {
1971 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1976 unsigned long lttng_userspace_probe_location_hash(
1977 const struct lttng_userspace_probe_location
*location
)
1979 return location
->hash(location
);
1982 enum lttng_error_code
lttng_userspace_probe_location_mi_serialize(
1983 const struct lttng_userspace_probe_location
*location
,
1984 struct mi_writer
*writer
)
1986 typedef enum lttng_error_code (*mi_fp
)(
1987 const struct lttng_userspace_probe_location
*,
1988 struct mi_writer
*);
1991 enum lttng_error_code ret_code
;
1992 mi_fp mi_function
= NULL
;
1994 LTTNG_ASSERT(location
);
1995 LTTNG_ASSERT(writer
);
1997 switch (lttng_userspace_probe_location_get_type(location
)) {
1998 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1999 mi_function
= lttng_userspace_probe_location_function_mi_serialize
;
2001 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
2002 mi_function
= lttng_userspace_probe_location_tracepoint_mi_serialize
;
2009 /* Open userspace probe location element. */
2010 ret
= mi_lttng_writer_open_element(
2011 writer
, mi_lttng_element_userspace_probe_location
);
2016 /* Underlying user space probe location. */
2017 ret_code
= mi_function(location
, writer
);
2018 if (ret_code
!= LTTNG_OK
) {
2022 /* Close userspace probe location element. */
2023 ret
= mi_lttng_writer_close_element(writer
);
2028 ret_code
= LTTNG_OK
;
2032 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2037 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
2038 const struct lttng_userspace_probe_location_lookup_method
2040 struct mi_writer
*writer
)
2043 enum lttng_error_code ret_code
;
2044 const char *type_element_str
;
2046 LTTNG_ASSERT(method
);
2047 LTTNG_ASSERT(writer
);
2049 switch (lttng_userspace_probe_location_lookup_method_get_type(method
)) {
2050 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
2052 mi_lttng_element_userspace_probe_location_lookup_method_function_default
;
2054 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
2056 mi_lttng_element_userspace_probe_location_lookup_method_function_elf
;
2058 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
2060 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt
;
2067 /* Open userspace probe location lookup method element. */
2068 ret
= mi_lttng_writer_open_element(writer
,
2069 mi_lttng_element_userspace_probe_location_lookup_method
);
2074 /* User space probe location lookup method empty element. */
2075 ret
= mi_lttng_writer_open_element(writer
, type_element_str
);
2080 /* Close userspace probe location lookup method element. */
2081 ret
= mi_lttng_close_multi_element(writer
, 2);
2086 ret_code
= LTTNG_OK
;
2090 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2095 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
2096 const struct lttng_userspace_probe_location
*location
,
2097 struct mi_writer
*writer
)
2100 enum lttng_error_code ret_code
;
2101 const char *probe_name
= NULL
;
2102 const char *provider_name
= NULL
;
2103 const char *binary_path
= NULL
;
2104 const struct lttng_userspace_probe_location_lookup_method
2105 *lookup_method
= NULL
;
2107 LTTNG_ASSERT(location
);
2108 LTTNG_ASSERT(writer
);
2110 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(
2112 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(
2114 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(
2116 lookup_method
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
2119 /* Open userspace probe location tracepoint element. */
2120 ret
= mi_lttng_writer_open_element(writer
,
2121 mi_lttng_element_userspace_probe_location_tracepoint
);
2127 ret
= mi_lttng_writer_write_element_string(writer
,
2128 mi_lttng_element_userspace_probe_location_tracepoint_probe_name
,
2134 /* Provider name. */
2135 ret
= mi_lttng_writer_write_element_string(writer
,
2136 mi_lttng_element_userspace_probe_location_tracepoint_provider_name
,
2143 ret
= mi_lttng_writer_write_element_string(writer
,
2144 mi_lttng_element_userspace_probe_location_binary_path
,
2150 /* The lookup method. */
2151 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2152 lookup_method
, writer
);
2153 if (ret_code
!= LTTNG_OK
) {
2157 /* Close userspace probe location tracepoint. */
2158 ret
= mi_lttng_writer_close_element(writer
);
2163 ret_code
= LTTNG_OK
;
2167 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2172 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
2173 const struct lttng_userspace_probe_location
*location
,
2174 struct mi_writer
*writer
)
2177 enum lttng_error_code ret_code
;
2178 const char *function_name
= NULL
;
2179 const char *binary_path
= NULL
;
2180 const char *instrumentation_type_str
= NULL
;
2181 enum lttng_userspace_probe_location_function_instrumentation_type
2182 instrumentation_type
;
2183 const struct lttng_userspace_probe_location_lookup_method
2184 *lookup_method
= NULL
;
2186 LTTNG_ASSERT(location
);
2187 LTTNG_ASSERT(writer
);
2189 function_name
= lttng_userspace_probe_location_function_get_function_name(
2191 binary_path
= lttng_userspace_probe_location_function_get_binary_path(
2193 instrumentation_type
=
2194 lttng_userspace_probe_location_function_get_instrumentation_type(
2196 lookup_method
= lttng_userspace_probe_location_function_get_lookup_method(
2199 switch (instrumentation_type
) {
2200 case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
:
2201 instrumentation_type_str
=
2202 mi_lttng_userspace_probe_location_function_instrumentation_type_entry
;
2209 /* Open userspace probe location function element. */
2210 ret
= mi_lttng_writer_open_element(writer
,
2211 mi_lttng_element_userspace_probe_location_function
);
2216 /* Function name. */
2217 ret
= mi_lttng_writer_write_element_string(writer
,
2218 mi_lttng_element_userspace_probe_location_function_name
,
2225 ret
= mi_lttng_writer_write_element_string(writer
,
2226 mi_lttng_element_userspace_probe_location_binary_path
,
2232 /* Instrumentation type. */
2233 ret
= mi_lttng_writer_write_element_string(writer
,
2234 mi_lttng_element_userspace_probe_location_function_instrumentation_type
,
2235 instrumentation_type_str
);
2240 /* The lookup method. */
2241 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2242 lookup_method
, writer
);
2243 if (ret_code
!= LTTNG_OK
) {
2247 /* Close userspace probe location function element. */
2248 ret
= mi_lttng_writer_close_element(writer
);
2253 ret_code
= LTTNG_OK
;
2257 ret_code
= LTTNG_ERR_MI_IO_FAIL
;