2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/compat/string.h>
10 #include <common/error.h>
11 #include <common/macros.h>
12 #include <common/payload.h>
13 #include <common/payload-view.h>
15 #include <lttng/constant.h>
16 #include <lttng/userspace-probe-internal.h>
18 #include <sys/types.h>
19 #include <sys/unistd.h>
21 enum lttng_userspace_probe_location_lookup_method_type
22 lttng_userspace_probe_location_lookup_method_get_type(
23 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
25 return lookup_method
? lookup_method
->type
:
26 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
29 void lttng_userspace_probe_location_lookup_method_destroy(
30 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
39 struct lttng_userspace_probe_location_lookup_method
*
40 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
42 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
43 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
45 elf_method
= zmalloc(sizeof(*elf_method
));
51 ret
= &elf_method
->parent
;
52 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
57 struct lttng_userspace_probe_location_lookup_method
*
58 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
60 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
61 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
63 sdt_method
= zmalloc(sizeof(*sdt_method
));
69 ret
= &sdt_method
->parent
;
70 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
75 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
76 const struct lttng_userspace_probe_location
*location
)
78 return location
? location
->type
:
79 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
83 void lttng_userspace_probe_location_function_destroy(
84 struct lttng_userspace_probe_location
*location
)
86 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
90 location_function
= container_of(location
,
91 struct lttng_userspace_probe_location_function
, parent
);
93 assert(location_function
);
95 free(location_function
->function_name
);
96 free(location_function
->binary_path
);
97 if (location_function
->binary_fd
>= 0) {
98 if (close(location_function
->binary_fd
)) {
106 void lttng_userspace_probe_location_tracepoint_destroy(
107 struct lttng_userspace_probe_location
*location
)
109 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
113 location_tracepoint
= container_of(location
,
114 struct lttng_userspace_probe_location_tracepoint
,
117 assert(location_tracepoint
);
119 free(location_tracepoint
->probe_name
);
120 free(location_tracepoint
->provider_name
);
121 free(location_tracepoint
->binary_path
);
122 if (location_tracepoint
->binary_fd
>= 0) {
123 if (close(location_tracepoint
->binary_fd
)) {
130 void lttng_userspace_probe_location_destroy(
131 struct lttng_userspace_probe_location
*location
)
137 lttng_userspace_probe_location_lookup_method_destroy(
138 location
->lookup_method
);
140 switch (location
->type
) {
141 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
142 lttng_userspace_probe_location_function_destroy(location
);
144 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
145 lttng_userspace_probe_location_tracepoint_destroy(location
);
152 /* Compare two file descriptors based on their inode and device numbers. */
153 static bool fd_is_equal(int a
, int b
)
156 bool is_equal
= false;
157 struct stat a_stat
, b_stat
;
159 if (a
< 0 && b
>= 0) {
163 if (b
< 0 && a
>= 0) {
167 if (a
< 0 && b
< 0) {
168 if (a
== -1 && b
== -1) {
173 /* Invalid state, abort. */
177 /* Both are valid file descriptors. */
178 ret
= fstat(a
, &a_stat
);
180 PERROR("Failed to fstat userspace probe location binary fd %d",
185 ret
= fstat(b
, &b_stat
);
187 PERROR("Failed to fstat userspace probe location binary fd %d",
192 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) &&
193 (a_stat
.st_dev
== b_stat
.st_dev
);
199 static bool lttng_userspace_probe_location_function_is_equal(
200 const struct lttng_userspace_probe_location
*_a
,
201 const struct lttng_userspace_probe_location
*_b
)
203 bool is_equal
= false;
204 struct lttng_userspace_probe_location_function
*a
, *b
;
206 a
= container_of(_a
, struct lttng_userspace_probe_location_function
,
208 b
= container_of(_b
, struct lttng_userspace_probe_location_function
,
211 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
215 assert(a
->function_name
);
216 assert(b
->function_name
);
217 if (strcmp(a
->function_name
, b
->function_name
)) {
221 assert(a
->binary_path
);
222 assert(b
->binary_path
);
223 if (strcmp(a
->binary_path
, b
->binary_path
)) {
227 is_equal
= fd_is_equal(a
->binary_fd
, b
->binary_fd
);
232 static struct lttng_userspace_probe_location
*
233 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
234 const char *function_name
,
235 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
239 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
240 struct lttng_userspace_probe_location
*ret
= NULL
;
241 struct lttng_userspace_probe_location_function
*location
;
244 binary_fd
= open(binary_path
, O_RDONLY
);
246 PERROR("Error opening the binary");
253 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
254 if (!function_name_copy
) {
255 PERROR("Error duplicating the function name");
259 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
260 if (!binary_path_copy
) {
261 PERROR("Error duplicating the function name");
265 location
= zmalloc(sizeof(*location
));
267 PERROR("Error allocating userspace probe location");
271 location
->function_name
= function_name_copy
;
272 location
->binary_path
= binary_path_copy
;
273 location
->binary_fd
= binary_fd
;
274 location
->instrumentation_type
=
275 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
277 ret
= &location
->parent
;
278 ret
->lookup_method
= lookup_method
;
279 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
280 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
284 free(function_name_copy
);
285 free(binary_path_copy
);
286 if (binary_fd
>= 0) {
287 if (close(binary_fd
)) {
288 PERROR("Error closing binary fd in error path");
295 static bool lttng_userspace_probe_location_tracepoint_is_equal(
296 const struct lttng_userspace_probe_location
*_a
,
297 const struct lttng_userspace_probe_location
*_b
)
299 bool is_equal
= false;
300 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
302 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
,
304 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
,
307 assert(a
->probe_name
);
308 assert(b
->probe_name
);
309 if (strcmp(a
->probe_name
, b
->probe_name
)) {
313 assert(a
->provider_name
);
314 assert(b
->provider_name
);
315 if (strcmp(a
->provider_name
, b
->provider_name
)) {
319 assert(a
->binary_path
);
320 assert(b
->binary_path
);
321 if (strcmp(a
->binary_path
, b
->binary_path
)) {
325 is_equal
= fd_is_equal(a
->binary_fd
, b
->binary_fd
);
331 static struct lttng_userspace_probe_location
*
332 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
333 const char *provider_name
, const char *probe_name
,
334 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
338 char *probe_name_copy
= NULL
;
339 char *provider_name_copy
= NULL
;
340 char *binary_path_copy
= NULL
;
341 struct lttng_userspace_probe_location
*ret
= NULL
;
342 struct lttng_userspace_probe_location_tracepoint
*location
;
345 binary_fd
= open(binary_path
, O_RDONLY
);
354 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
355 if (!probe_name_copy
) {
356 PERROR("lttng_strndup");
360 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
361 if (!provider_name_copy
) {
362 PERROR("lttng_strndup");
366 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
367 if (!binary_path_copy
) {
368 PERROR("lttng_strndup");
372 location
= zmalloc(sizeof(*location
));
378 location
->probe_name
= probe_name_copy
;
379 location
->provider_name
= provider_name_copy
;
380 location
->binary_path
= binary_path_copy
;
381 location
->binary_fd
= binary_fd
;
383 ret
= &location
->parent
;
384 ret
->lookup_method
= lookup_method
;
385 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
386 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
390 free(probe_name_copy
);
391 free(provider_name_copy
);
392 free(binary_path_copy
);
393 if (binary_fd
>= 0) {
394 if (close(binary_fd
)) {
395 PERROR("Error closing binary fd in error path");
402 struct lttng_userspace_probe_location
*
403 lttng_userspace_probe_location_function_create(const char *binary_path
,
404 const char *function_name
,
405 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
407 struct lttng_userspace_probe_location
*ret
= NULL
;
409 if (!binary_path
|| !function_name
) {
410 ERR("Invalid argument(s)");
414 switch (lttng_userspace_probe_location_lookup_method_get_type(
416 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
417 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
420 /* Invalid probe location lookup method. */
424 ret
= lttng_userspace_probe_location_function_create_no_check(
425 binary_path
, function_name
, lookup_method
, true);
430 struct lttng_userspace_probe_location
*
431 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
432 const char *provider_name
, const char *probe_name
,
433 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
435 struct lttng_userspace_probe_location
*ret
= NULL
;
437 if (!binary_path
|| !probe_name
|| !provider_name
) {
438 ERR("Invalid argument(s)");
442 switch (lttng_userspace_probe_location_lookup_method_get_type(
444 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
447 /* Invalid probe location lookup method. */
451 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
452 binary_path
, provider_name
, probe_name
, lookup_method
, true);
457 static struct lttng_userspace_probe_location_lookup_method
*
458 lttng_userspace_probe_location_lookup_method_function_elf_copy(
459 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
461 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
462 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
464 assert(lookup_method
);
465 assert(lookup_method
->type
==
466 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
468 elf_method
= zmalloc(sizeof(*elf_method
));
470 PERROR("Error allocating ELF userspace probe lookup method");
474 elf_method
->parent
.type
= lookup_method
->type
;
475 parent
= &elf_method
->parent
;
484 static struct lttng_userspace_probe_location_lookup_method
*
485 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
486 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
488 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
489 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
491 assert(lookup_method
);
492 assert(lookup_method
->type
==
493 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
495 sdt_method
= zmalloc(sizeof(*sdt_method
));
501 sdt_method
->parent
.type
= lookup_method
->type
;
502 parent
= &sdt_method
->parent
;
512 static struct lttng_userspace_probe_location
*
513 lttng_userspace_probe_location_function_copy(
514 const struct lttng_userspace_probe_location
*location
)
516 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
517 struct lttng_userspace_probe_location
*new_location
= NULL
;
518 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
519 const char *binary_path
= NULL
;
520 const char *function_name
= NULL
;
524 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
526 /* Get probe location fields */
527 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
529 ERR("Userspace probe binary path is NULL");
533 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
534 if (!function_name
) {
535 ERR("Userspace probe function name is NULL");
539 /* Duplicate the binary fd */
540 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
542 ERR("Error getting file descriptor to binary");
548 PERROR("Error duplicating file descriptor to binary");
553 * Duplicate probe location method fields
555 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
556 location
->lookup_method
);
557 switch (lookup_type
) {
558 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
560 lttng_userspace_probe_location_lookup_method_function_elf_copy(
561 location
->lookup_method
);
562 if (!lookup_method
) {
567 /* Invalid probe location lookup method. */
571 /* Create the probe_location */
572 new_location
= lttng_userspace_probe_location_function_create_no_check(
573 binary_path
, function_name
, lookup_method
, false);
575 goto destroy_lookup_method
;
578 /* Set the duplicated fd to the new probe_location */
579 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
580 goto destroy_probe_location
;
585 destroy_probe_location
:
586 lttng_userspace_probe_location_destroy(new_location
);
587 destroy_lookup_method
:
588 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
590 if (close(new_fd
) < 0) {
591 PERROR("Error closing duplicated file descriptor in error path");
599 static struct lttng_userspace_probe_location
*
600 lttng_userspace_probe_location_tracepoint_copy(
601 const struct lttng_userspace_probe_location
*location
)
603 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
604 struct lttng_userspace_probe_location
*new_location
= NULL
;
605 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
606 const char *binary_path
= NULL
;
607 const char *probe_name
= NULL
;
608 const char *provider_name
= NULL
;
612 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
614 /* Get probe location fields */
615 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
617 ERR("Userspace probe binary path is NULL");
621 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
623 ERR("Userspace probe probe name is NULL");
627 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
628 if (!provider_name
) {
629 ERR("Userspace probe provider name is NULL");
633 /* Duplicate the binary fd */
634 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
636 ERR("Error getting file descriptor to binary");
642 PERROR("Error duplicating file descriptor to binary");
647 * Duplicate probe location method fields
649 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
650 location
->lookup_method
);
651 switch (lookup_type
) {
652 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
654 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
655 location
->lookup_method
);
656 if (!lookup_method
) {
661 /* Invalid probe location lookup method. */
665 /* Create the probe_location */
666 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
667 binary_path
, provider_name
, probe_name
, lookup_method
, false);
669 goto destroy_lookup_method
;
672 /* Set the duplicated fd to the new probe_location */
673 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
674 goto destroy_probe_location
;
679 destroy_probe_location
:
680 lttng_userspace_probe_location_destroy(new_location
);
681 destroy_lookup_method
:
682 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
684 if (close(new_fd
) < 0) {
685 PERROR("Error closing duplicated file descriptor in error path");
693 const char *lttng_userspace_probe_location_function_get_binary_path(
694 const struct lttng_userspace_probe_location
*location
)
696 const char *ret
= NULL
;
697 struct lttng_userspace_probe_location_function
*function_location
;
699 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
700 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
701 ERR("Invalid argument(s)");
705 function_location
= container_of(location
,
706 struct lttng_userspace_probe_location_function
,
708 ret
= function_location
->binary_path
;
713 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
714 const struct lttng_userspace_probe_location
*location
)
716 const char *ret
= NULL
;
717 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
719 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
720 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
721 ERR("Invalid argument(s)");
725 tracepoint_location
= container_of(location
,
726 struct lttng_userspace_probe_location_tracepoint
,
728 ret
= tracepoint_location
->binary_path
;
733 const char *lttng_userspace_probe_location_function_get_function_name(
734 const struct lttng_userspace_probe_location
*location
)
736 const char *ret
= NULL
;
737 struct lttng_userspace_probe_location_function
*function_location
;
739 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
740 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
741 ERR("Invalid argument(s)");
745 function_location
= container_of(location
,
746 struct lttng_userspace_probe_location_function
, parent
);
747 ret
= function_location
->function_name
;
752 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
753 const struct lttng_userspace_probe_location
*location
)
755 const char *ret
= NULL
;
756 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
758 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
759 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
760 ERR("Invalid argument(s)");
764 tracepoint_location
= container_of(location
,
765 struct lttng_userspace_probe_location_tracepoint
, parent
);
766 ret
= tracepoint_location
->probe_name
;
771 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
772 const struct lttng_userspace_probe_location
*location
)
774 const char *ret
= NULL
;
775 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
777 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
778 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
779 ERR("Invalid argument(s)");
783 tracepoint_location
= container_of(location
,
784 struct lttng_userspace_probe_location_tracepoint
, parent
);
785 ret
= tracepoint_location
->provider_name
;
790 int lttng_userspace_probe_location_function_get_binary_fd(
791 const struct lttng_userspace_probe_location
*location
)
794 struct lttng_userspace_probe_location_function
*function_location
;
796 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
797 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
798 ERR("Invalid argument(s)");
802 function_location
= container_of(location
,
803 struct lttng_userspace_probe_location_function
, parent
);
804 ret
= function_location
->binary_fd
;
809 enum lttng_userspace_probe_location_function_instrumentation_type
810 lttng_userspace_probe_location_function_get_instrumentation_type(
811 const struct lttng_userspace_probe_location
*location
)
813 enum lttng_userspace_probe_location_function_instrumentation_type type
;
814 struct lttng_userspace_probe_location_function
*function_location
;
816 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
817 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
818 ERR("Invalid argument(s)");
819 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
823 function_location
= container_of(location
,
824 struct lttng_userspace_probe_location_function
, parent
);
825 type
= function_location
->instrumentation_type
;
830 enum lttng_userspace_probe_location_status
831 lttng_userspace_probe_location_function_set_instrumentation_type(
832 const struct lttng_userspace_probe_location
*location
,
833 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
835 enum lttng_userspace_probe_location_status status
=
836 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
837 struct lttng_userspace_probe_location_function
*function_location
;
839 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
840 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
841 instrumentation_type
!=
842 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
843 ERR("Invalid argument(s)");
844 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
848 function_location
= container_of(location
,
849 struct lttng_userspace_probe_location_function
, parent
);
850 function_location
->instrumentation_type
= instrumentation_type
;
855 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
856 const struct lttng_userspace_probe_location
*location
)
859 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
861 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
862 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
863 ERR("Invalid argument(s)");
867 tracepoint_location
= container_of(location
,
868 struct lttng_userspace_probe_location_tracepoint
, parent
);
869 ret
= tracepoint_location
->binary_fd
;
874 static struct lttng_userspace_probe_location_lookup_method
*
875 lttng_userspace_probe_location_function_get_lookup_method(
876 const struct lttng_userspace_probe_location
*location
)
878 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
880 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
881 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
882 ERR("Invalid argument(s)");
886 ret
= location
->lookup_method
;
891 static struct lttng_userspace_probe_location_lookup_method
*
892 lttng_userspace_probe_location_tracepoint_get_lookup_method(
893 const struct lttng_userspace_probe_location
*location
)
895 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
897 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
898 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
899 ERR("Invalid argument(s)");
903 ret
= location
->lookup_method
;
908 const struct lttng_userspace_probe_location_lookup_method
*
909 lttng_userspace_probe_location_get_lookup_method(
910 const struct lttng_userspace_probe_location
*location
)
912 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
915 switch (location
->type
) {
916 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
917 ret
= lttng_userspace_probe_location_function_get_lookup_method(
920 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
921 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
925 ERR("Unknowned lookup method.");
932 int lttng_userspace_probe_location_lookup_method_serialize(
933 struct lttng_userspace_probe_location_lookup_method
*method
,
934 struct lttng_dynamic_buffer
*buffer
)
937 struct lttng_userspace_probe_location_lookup_method_comm
940 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
941 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
943 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
944 sizeof(lookup_method_comm
));
949 ret
= sizeof(lookup_method_comm
);
955 int lttng_userspace_probe_location_function_serialize(
956 const struct lttng_userspace_probe_location
*location
,
957 struct lttng_dynamic_buffer
*buffer
,
961 size_t function_name_len
, binary_path_len
;
962 struct lttng_userspace_probe_location_function
*location_function
;
963 struct lttng_userspace_probe_location_function_comm location_function_comm
;
966 assert(lttng_userspace_probe_location_get_type(location
) ==
967 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
969 location_function
= container_of(location
,
970 struct lttng_userspace_probe_location_function
,
972 if (!location_function
->function_name
|| !location_function
->binary_path
) {
973 ret
= -LTTNG_ERR_INVALID
;
977 if (binary_fd
&& location_function
->binary_fd
< 0) {
978 ret
= -LTTNG_ERR_INVALID
;
983 *binary_fd
= location_function
->binary_fd
;
986 function_name_len
= strlen(location_function
->function_name
);
987 if (function_name_len
== 0) {
988 ret
= -LTTNG_ERR_INVALID
;
991 binary_path_len
= strlen(location_function
->binary_path
);
992 if (binary_path_len
== 0) {
993 ret
= -LTTNG_ERR_INVALID
;
997 location_function_comm
.function_name_len
= function_name_len
+ 1;
998 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
1001 ret
= lttng_dynamic_buffer_append(buffer
,
1002 &location_function_comm
,
1003 sizeof(location_function_comm
));
1005 ret
= -LTTNG_ERR_INVALID
;
1008 ret
= lttng_dynamic_buffer_append(buffer
,
1009 location_function
->function_name
,
1010 location_function_comm
.function_name_len
);
1012 ret
= -LTTNG_ERR_INVALID
;
1015 ret
= lttng_dynamic_buffer_append(buffer
,
1016 location_function
->binary_path
,
1017 location_function_comm
.binary_path_len
);
1019 ret
= -LTTNG_ERR_INVALID
;
1023 ret
= sizeof(location_function_comm
) +
1024 location_function_comm
.function_name_len
+
1025 location_function_comm
.binary_path_len
;
1031 int lttng_userspace_probe_location_tracepoint_serialize(
1032 const struct lttng_userspace_probe_location
*location
,
1033 struct lttng_dynamic_buffer
*buffer
,
1037 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1038 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1039 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1042 assert(lttng_userspace_probe_location_get_type(location
) ==
1043 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1045 location_tracepoint
= container_of(location
,
1046 struct lttng_userspace_probe_location_tracepoint
,
1048 if (!location_tracepoint
->probe_name
||
1049 !location_tracepoint
->provider_name
||
1050 !location_tracepoint
->binary_path
) {
1051 ret
= -LTTNG_ERR_INVALID
;
1055 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
1056 ret
= -LTTNG_ERR_INVALID
;
1061 *binary_fd
= location_tracepoint
->binary_fd
;
1064 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1065 if (probe_name_len
== 0) {
1066 ret
= -LTTNG_ERR_INVALID
;
1070 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1071 if (provider_name_len
== 0) {
1072 ret
= -LTTNG_ERR_INVALID
;
1076 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1077 if (binary_path_len
== 0) {
1078 ret
= -LTTNG_ERR_INVALID
;
1082 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1083 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1084 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1087 ret
= lttng_dynamic_buffer_append(buffer
,
1088 &location_tracepoint_comm
,
1089 sizeof(location_tracepoint_comm
));
1091 ret
= -LTTNG_ERR_INVALID
;
1094 ret
= lttng_dynamic_buffer_append(buffer
,
1095 location_tracepoint
->probe_name
,
1096 location_tracepoint_comm
.probe_name_len
);
1098 ret
= -LTTNG_ERR_INVALID
;
1101 ret
= lttng_dynamic_buffer_append(buffer
,
1102 location_tracepoint
->provider_name
,
1103 location_tracepoint_comm
.provider_name_len
);
1105 ret
= -LTTNG_ERR_INVALID
;
1108 ret
= lttng_dynamic_buffer_append(buffer
,
1109 location_tracepoint
->binary_path
,
1110 location_tracepoint_comm
.binary_path_len
);
1112 ret
= -LTTNG_ERR_INVALID
;
1116 ret
= sizeof(location_tracepoint_comm
) +
1117 location_tracepoint_comm
.probe_name_len
+
1118 location_tracepoint_comm
.provider_name_len
+
1119 location_tracepoint_comm
.binary_path_len
;
1125 int lttng_userspace_probe_location_serialize(
1126 const struct lttng_userspace_probe_location
*location
,
1127 struct lttng_dynamic_buffer
*buffer
,
1130 int ret
, buffer_use
= 0;
1131 struct lttng_userspace_probe_location_comm location_generic_comm
;
1134 ERR("Invalid argument(s)");
1135 ret
= -LTTNG_ERR_INVALID
;
1139 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1141 location_generic_comm
.type
= (int8_t) location
->type
;
1143 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1144 sizeof(location_generic_comm
));
1149 buffer_use
+= sizeof(location_generic_comm
);
1151 switch (lttng_userspace_probe_location_get_type(location
)) {
1152 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1153 ret
= lttng_userspace_probe_location_function_serialize(
1154 location
, buffer
, binary_fd
);
1156 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1157 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1158 location
, buffer
, binary_fd
);
1161 ERR("Unsupported probe location type");
1162 ret
= -LTTNG_ERR_INVALID
;
1170 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1171 location
->lookup_method
, buffer
);
1181 int lttng_userspace_probe_location_function_create_from_buffer(
1182 const struct lttng_buffer_view
*buffer
,
1183 struct lttng_userspace_probe_location
**location
)
1185 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1186 const char *function_name_src
, *binary_path_src
;
1187 char *function_name
= NULL
, *binary_path
= NULL
;
1191 assert(buffer
->data
);
1194 location_function_comm
=
1195 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1197 const size_t expected_size
= sizeof(*location_function_comm
) +
1198 location_function_comm
->function_name_len
+
1199 location_function_comm
->binary_path_len
;
1201 if (buffer
->size
< expected_size
) {
1202 ret
= -LTTNG_ERR_INVALID
;
1206 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1207 binary_path_src
= function_name_src
+
1208 location_function_comm
->function_name_len
;
1210 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1211 ret
= -LTTNG_ERR_INVALID
;
1214 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1215 ret
= -LTTNG_ERR_INVALID
;
1219 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1220 if (!function_name
) {
1221 PERROR("lttng_strndup");
1222 ret
= -LTTNG_ERR_NOMEM
;
1226 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1228 PERROR("lttng_strndup");
1229 ret
= -LTTNG_ERR_NOMEM
;
1233 *location
= lttng_userspace_probe_location_function_create_no_check(
1234 binary_path
, function_name
, NULL
, false);
1236 ret
= -LTTNG_ERR_INVALID
;
1240 ret
= (int) expected_size
;
1242 free(function_name
);
1248 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1249 const struct lttng_buffer_view
*buffer
,
1250 struct lttng_userspace_probe_location
**location
)
1252 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1253 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1254 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1258 assert(buffer
->data
);
1261 location_tracepoint_comm
=
1262 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1264 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1265 location_tracepoint_comm
->probe_name_len
+
1266 location_tracepoint_comm
->provider_name_len
+
1267 location_tracepoint_comm
->binary_path_len
;
1269 if (buffer
->size
< expected_size
) {
1270 ret
= -LTTNG_ERR_INVALID
;
1274 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1275 provider_name_src
= probe_name_src
+
1276 location_tracepoint_comm
->probe_name_len
;
1277 binary_path_src
= provider_name_src
+
1278 location_tracepoint_comm
->provider_name_len
;
1280 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1281 ret
= -LTTNG_ERR_INVALID
;
1285 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1286 ret
= -LTTNG_ERR_INVALID
;
1290 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1291 ret
= -LTTNG_ERR_INVALID
;
1295 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1297 PERROR("lttng_strndup");
1300 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1301 if (!provider_name
) {
1302 PERROR("lttng_strndup");
1306 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1308 PERROR("lttng_strndup");
1312 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1313 binary_path
, provider_name
, probe_name
, NULL
, false);
1315 ret
= -LTTNG_ERR_INVALID
;
1319 ret
= (int) expected_size
;
1322 free(provider_name
);
1328 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1329 struct lttng_buffer_view
*buffer
,
1330 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1333 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1334 enum lttng_userspace_probe_location_lookup_method_type type
;
1337 assert(buffer
->data
);
1338 assert(lookup_method
);
1340 if (buffer
->size
< sizeof(*lookup_comm
)) {
1341 ret
= -LTTNG_ERR_INVALID
;
1345 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1347 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1350 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1351 *lookup_method
= NULL
;
1353 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1355 lttng_userspace_probe_location_lookup_method_function_elf_create();
1356 if (!(*lookup_method
)) {
1357 ret
= -LTTNG_ERR_INVALID
;
1361 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1363 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1364 if (!(*lookup_method
)) {
1365 ret
= -LTTNG_ERR_INVALID
;
1370 ret
= -LTTNG_ERR_INVALID
;
1374 ret
= sizeof(*lookup_comm
);
1380 int lttng_userspace_probe_location_create_from_buffer(
1381 const struct lttng_buffer_view
*buffer
,
1382 struct lttng_userspace_probe_location
**location
)
1384 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1385 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1386 enum lttng_userspace_probe_location_type type
;
1387 struct lttng_buffer_view lookup_method_view
;
1393 assert(buffer
->data
);
1396 lookup_method
= NULL
;
1398 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1399 ret
= -LTTNG_ERR_INVALID
;
1403 probe_location_comm
=
1404 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1405 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1406 consumed
+= sizeof(*probe_location_comm
);
1409 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1411 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1412 buffer
, consumed
, buffer
->size
- consumed
);
1414 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1421 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1423 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1424 buffer
, consumed
, buffer
->size
- consumed
);
1426 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1434 ret
= -LTTNG_ERR_INVALID
;
1439 if (buffer
->size
<= consumed
) {
1440 ret
= -LTTNG_ERR_INVALID
;
1444 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1445 buffer
->size
- consumed
);
1446 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1447 &lookup_method_view
, &lookup_method
);
1449 ret
= -LTTNG_ERR_INVALID
;
1453 assert(lookup_method
);
1454 (*location
)->lookup_method
= lookup_method
;
1455 lookup_method
= NULL
;
1462 int lttng_userspace_probe_location_function_set_binary_fd(
1463 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1466 struct lttng_userspace_probe_location_function
*function_location
;
1469 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1471 function_location
= container_of(location
,
1472 struct lttng_userspace_probe_location_function
, parent
);
1473 if (function_location
->binary_fd
>= 0) {
1474 ret
= close(function_location
->binary_fd
);
1477 ret
= -LTTNG_ERR_INVALID
;
1482 function_location
->binary_fd
= binary_fd
;
1488 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1489 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1492 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1495 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1497 tracepoint_location
= container_of(location
,
1498 struct lttng_userspace_probe_location_tracepoint
, parent
);
1499 if (tracepoint_location
->binary_fd
>= 0) {
1500 ret
= close(tracepoint_location
->binary_fd
);
1503 ret
= -LTTNG_ERR_INVALID
;
1508 tracepoint_location
->binary_fd
= binary_fd
;
1514 int lttng_userspace_probe_location_function_flatten(
1515 const struct lttng_userspace_probe_location
*location
,
1516 struct lttng_dynamic_buffer
*buffer
)
1518 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1519 struct lttng_userspace_probe_location_function
*probe_function
;
1520 struct lttng_userspace_probe_location_function flat_probe
;
1521 size_t function_name_len
, binary_path_len
;
1522 size_t padding_needed
= 0;
1523 char *flat_probe_start
;
1524 int storage_needed
= 0;
1529 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1530 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1531 ret
= -LTTNG_ERR_INVALID
;
1535 probe_function
= container_of(location
,
1536 struct lttng_userspace_probe_location_function
,
1538 assert(probe_function
->function_name
);
1539 assert(probe_function
->binary_path
);
1542 sizeof(struct lttng_userspace_probe_location_function
);
1543 function_name_len
= strlen(probe_function
->function_name
) + 1;
1544 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1545 storage_needed
+= function_name_len
+ binary_path_len
;
1548 * The lookup method is aligned to 64-bit within the buffer.
1549 * This is needed even if there is no lookup method since
1550 * the next structure in the buffer probably needs to be
1551 * aligned too (depending on the arch).
1553 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1554 storage_needed
+= padding_needed
;
1556 if (location
->lookup_method
) {
1557 /* NOTE: elf look-up method is assumed here. */
1558 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1562 ret
= storage_needed
;
1566 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1567 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1568 buffer
->size
+ storage_needed
);
1574 memset(&flat_probe
, 0, sizeof(flat_probe
));
1576 flat_probe_start
= buffer
->data
+ buffer
->size
;
1577 flat_probe
.parent
.type
= location
->type
;
1579 * The lookup method, if present, is the last element in the flat
1580 * representation of the probe.
1582 if (location
->lookup_method
) {
1583 flat_probe
.parent
.lookup_method
=
1584 (struct lttng_userspace_probe_location_lookup_method
*)
1585 (flat_probe_start
+ sizeof(flat_probe
) +
1586 function_name_len
+ binary_path_len
+ padding_needed
);
1588 flat_probe
.parent
.lookup_method
= NULL
;
1591 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1592 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1593 flat_probe
.binary_fd
= -1;
1594 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1595 sizeof(flat_probe
));
1600 ret
= lttng_dynamic_buffer_append(buffer
,
1601 probe_function
->function_name
, function_name_len
);
1605 ret
= lttng_dynamic_buffer_append(buffer
,
1606 probe_function
->binary_path
, binary_path_len
);
1611 /* Insert padding before the lookup method. */
1612 ret
= lttng_dynamic_buffer_set_size(buffer
,
1613 buffer
->size
+ padding_needed
);
1618 if (!location
->lookup_method
) {
1619 /* Not an error, the default method is used. */
1620 ret
= storage_needed
;
1624 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1625 flat_lookup_method
.parent
.type
=
1626 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1627 ret
= lttng_dynamic_buffer_append(buffer
,
1628 &flat_lookup_method
, sizeof(flat_lookup_method
));
1632 ret
= storage_needed
;
1638 int lttng_userspace_probe_location_tracepoint_flatten(
1639 const struct lttng_userspace_probe_location
*location
,
1640 struct lttng_dynamic_buffer
*buffer
)
1642 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1643 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1644 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1645 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1646 size_t padding_needed
= 0;
1647 int storage_needed
= 0;
1648 char *flat_probe_start
;
1653 /* Only SDT tracepoints are supported at the moment */
1654 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1655 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1656 ret
= -LTTNG_ERR_INVALID
;
1659 probe_tracepoint
= container_of(location
,
1660 struct lttng_userspace_probe_location_tracepoint
,
1662 assert(probe_tracepoint
->probe_name
);
1663 assert(probe_tracepoint
->provider_name
);
1664 assert(probe_tracepoint
->binary_path
);
1666 /* Compute the storage space needed to flatten the probe location */
1667 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1669 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1670 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1671 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1673 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1676 * The lookup method is aligned to 64-bit within the buffer.
1677 * This is needed even if there is no lookup method since
1678 * the next structure in the buffer probably needs to be
1679 * aligned too (depending on the arch).
1681 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1682 storage_needed
+= padding_needed
;
1684 if (location
->lookup_method
) {
1685 /* NOTE: elf look-up method is assumed here. */
1687 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1691 * If the caller set buffer to NULL, return the size of the needed buffer.
1694 ret
= storage_needed
;
1698 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1699 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1700 buffer
->size
+ storage_needed
);
1706 memset(&flat_probe
, 0, sizeof(flat_probe
));
1708 flat_probe_start
= buffer
->data
+ buffer
->size
;
1709 flat_probe
.parent
.type
= location
->type
;
1712 * The lookup method, if present, is the last element in the flat
1713 * representation of the probe.
1715 if (location
->lookup_method
) {
1716 flat_probe
.parent
.lookup_method
=
1717 (struct lttng_userspace_probe_location_lookup_method
*)
1718 (flat_probe_start
+ sizeof(flat_probe
) +
1719 probe_name_len
+ provider_name_len
+
1720 binary_path_len
+ padding_needed
);
1722 flat_probe
.parent
.lookup_method
= NULL
;
1725 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1726 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1727 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1728 flat_probe
.binary_fd
= -1;
1729 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1734 /* Append all the fields to the buffer */
1735 ret
= lttng_dynamic_buffer_append(buffer
,
1736 probe_tracepoint
->probe_name
, probe_name_len
);
1740 ret
= lttng_dynamic_buffer_append(buffer
,
1741 probe_tracepoint
->provider_name
, provider_name_len
);
1745 ret
= lttng_dynamic_buffer_append(buffer
,
1746 probe_tracepoint
->binary_path
, binary_path_len
);
1751 /* Insert padding before the lookup method. */
1752 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1757 if (!location
->lookup_method
) {
1758 /* Not an error, the default method is used. */
1759 ret
= storage_needed
;
1763 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1765 flat_lookup_method
.parent
.type
=
1766 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1767 ret
= lttng_dynamic_buffer_append(buffer
,
1768 &flat_lookup_method
, sizeof(flat_lookup_method
));
1772 ret
= storage_needed
;
1778 int lttng_userspace_probe_location_flatten(
1779 const struct lttng_userspace_probe_location
*location
,
1780 struct lttng_dynamic_buffer
*buffer
)
1784 ret
= -LTTNG_ERR_INVALID
;
1788 /* Only types currently supported. */
1789 switch (location
->type
) {
1790 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1791 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1793 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1794 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1797 ret
= -LTTNG_ERR_INVALID
;
1806 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1807 const struct lttng_userspace_probe_location
*location
)
1809 struct lttng_userspace_probe_location
*new_location
= NULL
;
1810 enum lttng_userspace_probe_location_type type
;
1816 type
= lttng_userspace_probe_location_get_type(location
);
1818 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1820 lttng_userspace_probe_location_function_copy(location
);
1821 if (!new_location
) {
1825 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1827 lttng_userspace_probe_location_tracepoint_copy(location
);
1828 if (!new_location
) {
1833 new_location
= NULL
;
1837 return new_location
;
1841 bool lttng_userspace_probe_location_lookup_method_is_equal(
1842 const struct lttng_userspace_probe_location_lookup_method
*a
,
1843 const struct lttng_userspace_probe_location_lookup_method
*b
)
1845 bool is_equal
= false;
1856 if (a
->type
!= b
->type
) {
1866 bool lttng_userspace_probe_location_is_equal(
1867 const struct lttng_userspace_probe_location
*a
,
1868 const struct lttng_userspace_probe_location
*b
)
1870 bool is_equal
= false;
1881 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1882 a
->lookup_method
, b
->lookup_method
)) {
1886 if (a
->type
!= b
->type
) {
1890 is_equal
= a
->equal
? a
->equal(a
, b
) : true;