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>
13 #include <lttng/constant.h>
14 #include <lttng/userspace-probe-internal.h>
16 #include <sys/types.h>
17 #include <sys/unistd.h>
19 enum lttng_userspace_probe_location_lookup_method_type
20 lttng_userspace_probe_location_lookup_method_get_type(
21 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
23 return lookup_method
? lookup_method
->type
:
24 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
27 void lttng_userspace_probe_location_lookup_method_destroy(
28 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
37 struct lttng_userspace_probe_location_lookup_method
*
38 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
40 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
41 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
43 elf_method
= zmalloc(sizeof(*elf_method
));
49 ret
= &elf_method
->parent
;
50 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
55 struct lttng_userspace_probe_location_lookup_method
*
56 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
58 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
59 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
61 sdt_method
= zmalloc(sizeof(*sdt_method
));
67 ret
= &sdt_method
->parent
;
68 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
73 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
74 const struct lttng_userspace_probe_location
*location
)
76 return location
? location
->type
:
77 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
81 void lttng_userspace_probe_location_function_destroy(
82 struct lttng_userspace_probe_location
*location
)
84 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
88 location_function
= container_of(location
,
89 struct lttng_userspace_probe_location_function
, parent
);
91 assert(location_function
);
93 free(location_function
->function_name
);
94 free(location_function
->binary_path
);
95 if (location_function
->binary_fd
>= 0) {
96 if (close(location_function
->binary_fd
)) {
104 void lttng_userspace_probe_location_tracepoint_destroy(
105 struct lttng_userspace_probe_location
*location
)
107 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
111 location_tracepoint
= container_of(location
,
112 struct lttng_userspace_probe_location_tracepoint
,
115 assert(location_tracepoint
);
117 free(location_tracepoint
->probe_name
);
118 free(location_tracepoint
->provider_name
);
119 free(location_tracepoint
->binary_path
);
120 if (location_tracepoint
->binary_fd
>= 0) {
121 if (close(location_tracepoint
->binary_fd
)) {
128 void lttng_userspace_probe_location_destroy(
129 struct lttng_userspace_probe_location
*location
)
135 lttng_userspace_probe_location_lookup_method_destroy(
136 location
->lookup_method
);
138 switch (location
->type
) {
139 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
140 lttng_userspace_probe_location_function_destroy(location
);
142 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
143 lttng_userspace_probe_location_tracepoint_destroy(location
);
150 /* Compare two file descriptors based on their inode and device numbers. */
151 static bool fd_is_equal(int a
, int b
)
154 bool is_equal
= false;
155 struct stat a_stat
, b_stat
;
157 if (a
< 0 && b
>= 0) {
161 if (b
< 0 && a
>= 0) {
165 if (a
< 0 && b
< 0) {
166 if (a
== -1 && b
== -1) {
171 /* Invalid state, abort. */
175 /* Both are valid file descriptors. */
176 ret
= fstat(a
, &a_stat
);
178 PERROR("Failed to fstat userspace probe location binary fd %d",
183 ret
= fstat(b
, &b_stat
);
185 PERROR("Failed to fstat userspace probe location binary fd %d",
190 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) &&
191 (a_stat
.st_dev
== b_stat
.st_dev
);
197 static bool lttng_userspace_probe_location_function_is_equal(
198 const struct lttng_userspace_probe_location
*_a
,
199 const struct lttng_userspace_probe_location
*_b
)
201 bool is_equal
= false;
202 struct lttng_userspace_probe_location_function
*a
, *b
;
204 a
= container_of(_a
, struct lttng_userspace_probe_location_function
,
206 b
= container_of(_b
, struct lttng_userspace_probe_location_function
,
209 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
213 assert(a
->function_name
);
214 assert(b
->function_name
);
215 if (strcmp(a
->function_name
, b
->function_name
)) {
219 assert(a
->binary_path
);
220 assert(b
->binary_path
);
221 if (strcmp(a
->binary_path
, b
->binary_path
)) {
225 is_equal
= fd_is_equal(a
->binary_fd
, b
->binary_fd
);
230 static struct lttng_userspace_probe_location
*
231 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
232 const char *function_name
,
233 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
237 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
238 struct lttng_userspace_probe_location
*ret
= NULL
;
239 struct lttng_userspace_probe_location_function
*location
;
242 binary_fd
= open(binary_path
, O_RDONLY
);
244 PERROR("Error opening the binary");
251 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
252 if (!function_name_copy
) {
253 PERROR("Error duplicating the function name");
257 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
258 if (!binary_path_copy
) {
259 PERROR("Error duplicating the function name");
263 location
= zmalloc(sizeof(*location
));
265 PERROR("Error allocating userspace probe location");
269 location
->function_name
= function_name_copy
;
270 location
->binary_path
= binary_path_copy
;
271 location
->binary_fd
= binary_fd
;
272 location
->instrumentation_type
=
273 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
275 ret
= &location
->parent
;
276 ret
->lookup_method
= lookup_method
;
277 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
278 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
282 free(function_name_copy
);
283 free(binary_path_copy
);
284 if (binary_fd
>= 0) {
285 if (close(binary_fd
)) {
286 PERROR("Error closing binary fd in error path");
293 static bool lttng_userspace_probe_location_tracepoint_is_equal(
294 const struct lttng_userspace_probe_location
*_a
,
295 const struct lttng_userspace_probe_location
*_b
)
297 bool is_equal
= false;
298 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
300 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
,
302 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
,
305 assert(a
->probe_name
);
306 assert(b
->probe_name
);
307 if (strcmp(a
->probe_name
, b
->probe_name
)) {
311 assert(a
->provider_name
);
312 assert(b
->provider_name
);
313 if (strcmp(a
->provider_name
, b
->provider_name
)) {
317 assert(a
->binary_path
);
318 assert(b
->binary_path
);
319 if (strcmp(a
->binary_path
, b
->binary_path
)) {
323 is_equal
= fd_is_equal(a
->binary_fd
, b
->binary_fd
);
329 static struct lttng_userspace_probe_location
*
330 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
331 const char *provider_name
, const char *probe_name
,
332 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
336 char *probe_name_copy
= NULL
;
337 char *provider_name_copy
= NULL
;
338 char *binary_path_copy
= NULL
;
339 struct lttng_userspace_probe_location
*ret
= NULL
;
340 struct lttng_userspace_probe_location_tracepoint
*location
;
343 binary_fd
= open(binary_path
, O_RDONLY
);
352 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
353 if (!probe_name_copy
) {
354 PERROR("lttng_strndup");
358 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
359 if (!provider_name_copy
) {
360 PERROR("lttng_strndup");
364 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
365 if (!binary_path_copy
) {
366 PERROR("lttng_strndup");
370 location
= zmalloc(sizeof(*location
));
376 location
->probe_name
= probe_name_copy
;
377 location
->provider_name
= provider_name_copy
;
378 location
->binary_path
= binary_path_copy
;
379 location
->binary_fd
= binary_fd
;
381 ret
= &location
->parent
;
382 ret
->lookup_method
= lookup_method
;
383 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
384 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
388 free(probe_name_copy
);
389 free(provider_name_copy
);
390 free(binary_path_copy
);
391 if (binary_fd
>= 0) {
392 if (close(binary_fd
)) {
393 PERROR("Error closing binary fd in error path");
400 struct lttng_userspace_probe_location
*
401 lttng_userspace_probe_location_function_create(const char *binary_path
,
402 const char *function_name
,
403 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
405 struct lttng_userspace_probe_location
*ret
= NULL
;
407 if (!binary_path
|| !function_name
) {
408 ERR("Invalid argument(s)");
412 switch (lttng_userspace_probe_location_lookup_method_get_type(
414 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
415 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
418 /* Invalid probe location lookup method. */
422 ret
= lttng_userspace_probe_location_function_create_no_check(
423 binary_path
, function_name
, lookup_method
, true);
428 struct lttng_userspace_probe_location
*
429 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
430 const char *provider_name
, const char *probe_name
,
431 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
433 struct lttng_userspace_probe_location
*ret
= NULL
;
435 if (!binary_path
|| !probe_name
|| !provider_name
) {
436 ERR("Invalid argument(s)");
440 switch (lttng_userspace_probe_location_lookup_method_get_type(
442 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
445 /* Invalid probe location lookup method. */
449 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
450 binary_path
, provider_name
, probe_name
, lookup_method
, true);
455 static struct lttng_userspace_probe_location_lookup_method
*
456 lttng_userspace_probe_location_lookup_method_function_elf_copy(
457 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
459 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
460 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
462 assert(lookup_method
);
463 assert(lookup_method
->type
==
464 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
466 elf_method
= zmalloc(sizeof(*elf_method
));
468 PERROR("Error allocating ELF userspace probe lookup method");
472 elf_method
->parent
.type
= lookup_method
->type
;
473 parent
= &elf_method
->parent
;
482 static struct lttng_userspace_probe_location_lookup_method
*
483 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
484 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
486 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
487 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
489 assert(lookup_method
);
490 assert(lookup_method
->type
==
491 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
493 sdt_method
= zmalloc(sizeof(*sdt_method
));
499 sdt_method
->parent
.type
= lookup_method
->type
;
500 parent
= &sdt_method
->parent
;
510 static struct lttng_userspace_probe_location
*
511 lttng_userspace_probe_location_function_copy(
512 const struct lttng_userspace_probe_location
*location
)
514 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
515 struct lttng_userspace_probe_location
*new_location
= NULL
;
516 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
517 const char *binary_path
= NULL
;
518 const char *function_name
= NULL
;
522 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
524 /* Get probe location fields */
525 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
527 ERR("Userspace probe binary path is NULL");
531 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
532 if (!function_name
) {
533 ERR("Userspace probe function name is NULL");
537 /* Duplicate the binary fd */
538 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
540 ERR("Error getting file descriptor to binary");
546 PERROR("Error duplicating file descriptor to binary");
551 * Duplicate probe location method fields
553 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
554 location
->lookup_method
);
555 switch (lookup_type
) {
556 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
558 lttng_userspace_probe_location_lookup_method_function_elf_copy(
559 location
->lookup_method
);
560 if (!lookup_method
) {
565 /* Invalid probe location lookup method. */
569 /* Create the probe_location */
570 new_location
= lttng_userspace_probe_location_function_create_no_check(
571 binary_path
, function_name
, lookup_method
, false);
573 goto destroy_lookup_method
;
576 /* Set the duplicated fd to the new probe_location */
577 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
578 goto destroy_probe_location
;
583 destroy_probe_location
:
584 lttng_userspace_probe_location_destroy(new_location
);
585 destroy_lookup_method
:
586 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
588 if (close(new_fd
) < 0) {
589 PERROR("Error closing duplicated file descriptor in error path");
597 static struct lttng_userspace_probe_location
*
598 lttng_userspace_probe_location_tracepoint_copy(
599 const struct lttng_userspace_probe_location
*location
)
601 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
602 struct lttng_userspace_probe_location
*new_location
= NULL
;
603 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
604 const char *binary_path
= NULL
;
605 const char *probe_name
= NULL
;
606 const char *provider_name
= NULL
;
610 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
612 /* Get probe location fields */
613 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
615 ERR("Userspace probe binary path is NULL");
619 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
621 ERR("Userspace probe probe name is NULL");
625 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
626 if (!provider_name
) {
627 ERR("Userspace probe provider name is NULL");
631 /* Duplicate the binary fd */
632 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
634 ERR("Error getting file descriptor to binary");
640 PERROR("Error duplicating file descriptor to binary");
645 * Duplicate probe location method fields
647 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
648 location
->lookup_method
);
649 switch (lookup_type
) {
650 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
652 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
653 location
->lookup_method
);
654 if (!lookup_method
) {
659 /* Invalid probe location lookup method. */
663 /* Create the probe_location */
664 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
665 binary_path
, provider_name
, probe_name
, lookup_method
, false);
667 goto destroy_lookup_method
;
670 /* Set the duplicated fd to the new probe_location */
671 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
672 goto destroy_probe_location
;
677 destroy_probe_location
:
678 lttng_userspace_probe_location_destroy(new_location
);
679 destroy_lookup_method
:
680 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
682 if (close(new_fd
) < 0) {
683 PERROR("Error closing duplicated file descriptor in error path");
691 const char *lttng_userspace_probe_location_function_get_binary_path(
692 const struct lttng_userspace_probe_location
*location
)
694 const char *ret
= NULL
;
695 struct lttng_userspace_probe_location_function
*function_location
;
697 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
698 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
699 ERR("Invalid argument(s)");
703 function_location
= container_of(location
,
704 struct lttng_userspace_probe_location_function
,
706 ret
= function_location
->binary_path
;
711 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
712 const struct lttng_userspace_probe_location
*location
)
714 const char *ret
= NULL
;
715 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
717 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
718 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
719 ERR("Invalid argument(s)");
723 tracepoint_location
= container_of(location
,
724 struct lttng_userspace_probe_location_tracepoint
,
726 ret
= tracepoint_location
->binary_path
;
731 const char *lttng_userspace_probe_location_function_get_function_name(
732 const struct lttng_userspace_probe_location
*location
)
734 const char *ret
= NULL
;
735 struct lttng_userspace_probe_location_function
*function_location
;
737 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
738 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
739 ERR("Invalid argument(s)");
743 function_location
= container_of(location
,
744 struct lttng_userspace_probe_location_function
, parent
);
745 ret
= function_location
->function_name
;
750 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
751 const struct lttng_userspace_probe_location
*location
)
753 const char *ret
= NULL
;
754 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
756 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
757 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
758 ERR("Invalid argument(s)");
762 tracepoint_location
= container_of(location
,
763 struct lttng_userspace_probe_location_tracepoint
, parent
);
764 ret
= tracepoint_location
->probe_name
;
769 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
770 const struct lttng_userspace_probe_location
*location
)
772 const char *ret
= NULL
;
773 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
775 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
776 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
777 ERR("Invalid argument(s)");
781 tracepoint_location
= container_of(location
,
782 struct lttng_userspace_probe_location_tracepoint
, parent
);
783 ret
= tracepoint_location
->provider_name
;
788 int lttng_userspace_probe_location_function_get_binary_fd(
789 const struct lttng_userspace_probe_location
*location
)
792 struct lttng_userspace_probe_location_function
*function_location
;
794 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
795 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
796 ERR("Invalid argument(s)");
800 function_location
= container_of(location
,
801 struct lttng_userspace_probe_location_function
, parent
);
802 ret
= function_location
->binary_fd
;
807 enum lttng_userspace_probe_location_function_instrumentation_type
808 lttng_userspace_probe_location_function_get_instrumentation_type(
809 const struct lttng_userspace_probe_location
*location
)
811 enum lttng_userspace_probe_location_function_instrumentation_type type
;
812 struct lttng_userspace_probe_location_function
*function_location
;
814 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
815 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
816 ERR("Invalid argument(s)");
817 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
821 function_location
= container_of(location
,
822 struct lttng_userspace_probe_location_function
, parent
);
823 type
= function_location
->instrumentation_type
;
828 enum lttng_userspace_probe_location_status
829 lttng_userspace_probe_location_function_set_instrumentation_type(
830 const struct lttng_userspace_probe_location
*location
,
831 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
833 enum lttng_userspace_probe_location_status status
=
834 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
835 struct lttng_userspace_probe_location_function
*function_location
;
837 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
838 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
839 instrumentation_type
!=
840 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
841 ERR("Invalid argument(s)");
842 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
846 function_location
= container_of(location
,
847 struct lttng_userspace_probe_location_function
, parent
);
848 function_location
->instrumentation_type
= instrumentation_type
;
853 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
854 const struct lttng_userspace_probe_location
*location
)
857 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
859 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
860 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
861 ERR("Invalid argument(s)");
865 tracepoint_location
= container_of(location
,
866 struct lttng_userspace_probe_location_tracepoint
, parent
);
867 ret
= tracepoint_location
->binary_fd
;
872 static struct lttng_userspace_probe_location_lookup_method
*
873 lttng_userspace_probe_location_function_get_lookup_method(
874 const struct lttng_userspace_probe_location
*location
)
876 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
878 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
879 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
880 ERR("Invalid argument(s)");
884 ret
= location
->lookup_method
;
889 static struct lttng_userspace_probe_location_lookup_method
*
890 lttng_userspace_probe_location_tracepoint_get_lookup_method(
891 const struct lttng_userspace_probe_location
*location
)
893 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
895 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
896 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
897 ERR("Invalid argument(s)");
901 ret
= location
->lookup_method
;
906 const struct lttng_userspace_probe_location_lookup_method
*
907 lttng_userspace_probe_location_get_lookup_method(
908 const struct lttng_userspace_probe_location
*location
)
910 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
913 switch (location
->type
) {
914 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
915 ret
= lttng_userspace_probe_location_function_get_lookup_method(
918 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
919 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
923 ERR("Unknowned lookup method.");
930 int lttng_userspace_probe_location_lookup_method_serialize(
931 struct lttng_userspace_probe_location_lookup_method
*method
,
932 struct lttng_dynamic_buffer
*buffer
)
935 struct lttng_userspace_probe_location_lookup_method_comm
938 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
939 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
941 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
942 sizeof(lookup_method_comm
));
947 ret
= sizeof(lookup_method_comm
);
953 int lttng_userspace_probe_location_function_serialize(
954 const struct lttng_userspace_probe_location
*location
,
955 struct lttng_dynamic_buffer
*buffer
,
959 size_t function_name_len
, binary_path_len
;
960 struct lttng_userspace_probe_location_function
*location_function
;
961 struct lttng_userspace_probe_location_function_comm location_function_comm
;
964 assert(lttng_userspace_probe_location_get_type(location
) ==
965 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
967 location_function
= container_of(location
,
968 struct lttng_userspace_probe_location_function
,
970 if (!location_function
->function_name
|| !location_function
->binary_path
) {
971 ret
= -LTTNG_ERR_INVALID
;
975 if (binary_fd
&& location_function
->binary_fd
< 0) {
976 ret
= -LTTNG_ERR_INVALID
;
981 *binary_fd
= location_function
->binary_fd
;
984 function_name_len
= strlen(location_function
->function_name
);
985 if (function_name_len
== 0) {
986 ret
= -LTTNG_ERR_INVALID
;
989 binary_path_len
= strlen(location_function
->binary_path
);
990 if (binary_path_len
== 0) {
991 ret
= -LTTNG_ERR_INVALID
;
995 location_function_comm
.function_name_len
= function_name_len
+ 1;
996 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
999 ret
= lttng_dynamic_buffer_append(buffer
,
1000 &location_function_comm
,
1001 sizeof(location_function_comm
));
1003 ret
= -LTTNG_ERR_INVALID
;
1006 ret
= lttng_dynamic_buffer_append(buffer
,
1007 location_function
->function_name
,
1008 location_function_comm
.function_name_len
);
1010 ret
= -LTTNG_ERR_INVALID
;
1013 ret
= lttng_dynamic_buffer_append(buffer
,
1014 location_function
->binary_path
,
1015 location_function_comm
.binary_path_len
);
1017 ret
= -LTTNG_ERR_INVALID
;
1021 ret
= sizeof(location_function_comm
) +
1022 location_function_comm
.function_name_len
+
1023 location_function_comm
.binary_path_len
;
1029 int lttng_userspace_probe_location_tracepoint_serialize(
1030 const struct lttng_userspace_probe_location
*location
,
1031 struct lttng_dynamic_buffer
*buffer
,
1035 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1036 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1037 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1040 assert(lttng_userspace_probe_location_get_type(location
) ==
1041 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1043 location_tracepoint
= container_of(location
,
1044 struct lttng_userspace_probe_location_tracepoint
,
1046 if (!location_tracepoint
->probe_name
||
1047 !location_tracepoint
->provider_name
||
1048 !location_tracepoint
->binary_path
) {
1049 ret
= -LTTNG_ERR_INVALID
;
1053 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
1054 ret
= -LTTNG_ERR_INVALID
;
1059 *binary_fd
= location_tracepoint
->binary_fd
;
1062 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1063 if (probe_name_len
== 0) {
1064 ret
= -LTTNG_ERR_INVALID
;
1068 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1069 if (provider_name_len
== 0) {
1070 ret
= -LTTNG_ERR_INVALID
;
1074 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1075 if (binary_path_len
== 0) {
1076 ret
= -LTTNG_ERR_INVALID
;
1080 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1081 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1082 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1085 ret
= lttng_dynamic_buffer_append(buffer
,
1086 &location_tracepoint_comm
,
1087 sizeof(location_tracepoint_comm
));
1089 ret
= -LTTNG_ERR_INVALID
;
1092 ret
= lttng_dynamic_buffer_append(buffer
,
1093 location_tracepoint
->probe_name
,
1094 location_tracepoint_comm
.probe_name_len
);
1096 ret
= -LTTNG_ERR_INVALID
;
1099 ret
= lttng_dynamic_buffer_append(buffer
,
1100 location_tracepoint
->provider_name
,
1101 location_tracepoint_comm
.provider_name_len
);
1103 ret
= -LTTNG_ERR_INVALID
;
1106 ret
= lttng_dynamic_buffer_append(buffer
,
1107 location_tracepoint
->binary_path
,
1108 location_tracepoint_comm
.binary_path_len
);
1110 ret
= -LTTNG_ERR_INVALID
;
1114 ret
= sizeof(location_tracepoint_comm
) +
1115 location_tracepoint_comm
.probe_name_len
+
1116 location_tracepoint_comm
.provider_name_len
+
1117 location_tracepoint_comm
.binary_path_len
;
1123 int lttng_userspace_probe_location_serialize(
1124 const struct lttng_userspace_probe_location
*location
,
1125 struct lttng_dynamic_buffer
*buffer
,
1128 int ret
, buffer_use
= 0;
1129 struct lttng_userspace_probe_location_comm location_generic_comm
;
1132 ERR("Invalid argument(s)");
1133 ret
= -LTTNG_ERR_INVALID
;
1137 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1139 location_generic_comm
.type
= (int8_t) location
->type
;
1141 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1142 sizeof(location_generic_comm
));
1147 buffer_use
+= sizeof(location_generic_comm
);
1149 switch (lttng_userspace_probe_location_get_type(location
)) {
1150 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1151 ret
= lttng_userspace_probe_location_function_serialize(
1152 location
, buffer
, binary_fd
);
1154 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1155 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1156 location
, buffer
, binary_fd
);
1159 ERR("Unsupported probe location type");
1160 ret
= -LTTNG_ERR_INVALID
;
1168 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1169 location
->lookup_method
, buffer
);
1179 int lttng_userspace_probe_location_function_create_from_buffer(
1180 const struct lttng_buffer_view
*buffer
,
1181 struct lttng_userspace_probe_location
**location
)
1183 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1184 const char *function_name_src
, *binary_path_src
;
1185 char *function_name
= NULL
, *binary_path
= NULL
;
1189 assert(buffer
->data
);
1192 location_function_comm
=
1193 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1195 const size_t expected_size
= sizeof(*location_function_comm
) +
1196 location_function_comm
->function_name_len
+
1197 location_function_comm
->binary_path_len
;
1199 if (buffer
->size
< expected_size
) {
1200 ret
= -LTTNG_ERR_INVALID
;
1204 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1205 binary_path_src
= function_name_src
+
1206 location_function_comm
->function_name_len
;
1208 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1209 ret
= -LTTNG_ERR_INVALID
;
1212 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1213 ret
= -LTTNG_ERR_INVALID
;
1217 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1218 if (!function_name
) {
1219 PERROR("lttng_strndup");
1220 ret
= -LTTNG_ERR_NOMEM
;
1224 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1226 PERROR("lttng_strndup");
1227 ret
= -LTTNG_ERR_NOMEM
;
1231 *location
= lttng_userspace_probe_location_function_create_no_check(
1232 binary_path
, function_name
, NULL
, false);
1234 ret
= -LTTNG_ERR_INVALID
;
1238 ret
= (int) expected_size
;
1240 free(function_name
);
1246 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1247 const struct lttng_buffer_view
*buffer
,
1248 struct lttng_userspace_probe_location
**location
)
1250 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1251 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1252 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1256 assert(buffer
->data
);
1259 location_tracepoint_comm
=
1260 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1262 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1263 location_tracepoint_comm
->probe_name_len
+
1264 location_tracepoint_comm
->provider_name_len
+
1265 location_tracepoint_comm
->binary_path_len
;
1267 if (buffer
->size
< expected_size
) {
1268 ret
= -LTTNG_ERR_INVALID
;
1272 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1273 provider_name_src
= probe_name_src
+
1274 location_tracepoint_comm
->probe_name_len
;
1275 binary_path_src
= provider_name_src
+
1276 location_tracepoint_comm
->provider_name_len
;
1278 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1279 ret
= -LTTNG_ERR_INVALID
;
1283 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1284 ret
= -LTTNG_ERR_INVALID
;
1288 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1289 ret
= -LTTNG_ERR_INVALID
;
1293 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1295 PERROR("lttng_strndup");
1298 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1299 if (!provider_name
) {
1300 PERROR("lttng_strndup");
1304 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1306 PERROR("lttng_strndup");
1310 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1311 binary_path
, provider_name
, probe_name
, NULL
, false);
1313 ret
= -LTTNG_ERR_INVALID
;
1317 ret
= (int) expected_size
;
1320 free(provider_name
);
1326 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1327 struct lttng_buffer_view
*buffer
,
1328 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1331 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1332 enum lttng_userspace_probe_location_lookup_method_type type
;
1335 assert(buffer
->data
);
1336 assert(lookup_method
);
1338 if (buffer
->size
< sizeof(*lookup_comm
)) {
1339 ret
= -LTTNG_ERR_INVALID
;
1343 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1345 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1348 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1349 *lookup_method
= NULL
;
1351 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1353 lttng_userspace_probe_location_lookup_method_function_elf_create();
1354 if (!(*lookup_method
)) {
1355 ret
= -LTTNG_ERR_INVALID
;
1359 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1361 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1362 if (!(*lookup_method
)) {
1363 ret
= -LTTNG_ERR_INVALID
;
1368 ret
= -LTTNG_ERR_INVALID
;
1372 ret
= sizeof(*lookup_comm
);
1378 int lttng_userspace_probe_location_create_from_buffer(
1379 const struct lttng_buffer_view
*buffer
,
1380 struct lttng_userspace_probe_location
**location
)
1382 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1383 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1384 enum lttng_userspace_probe_location_type type
;
1385 struct lttng_buffer_view lookup_method_view
;
1391 assert(buffer
->data
);
1394 lookup_method
= NULL
;
1396 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1397 ret
= -LTTNG_ERR_INVALID
;
1401 probe_location_comm
=
1402 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1403 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1404 consumed
+= sizeof(*probe_location_comm
);
1407 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1409 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1410 buffer
, consumed
, buffer
->size
- consumed
);
1412 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1419 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1421 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1422 buffer
, consumed
, buffer
->size
- consumed
);
1424 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1432 ret
= -LTTNG_ERR_INVALID
;
1437 if (buffer
->size
<= consumed
) {
1438 ret
= -LTTNG_ERR_INVALID
;
1442 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1443 buffer
->size
- consumed
);
1444 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1445 &lookup_method_view
, &lookup_method
);
1447 ret
= -LTTNG_ERR_INVALID
;
1451 assert(lookup_method
);
1452 (*location
)->lookup_method
= lookup_method
;
1453 lookup_method
= NULL
;
1460 int lttng_userspace_probe_location_function_set_binary_fd(
1461 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1464 struct lttng_userspace_probe_location_function
*function_location
;
1467 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1469 function_location
= container_of(location
,
1470 struct lttng_userspace_probe_location_function
, parent
);
1471 if (function_location
->binary_fd
>= 0) {
1472 ret
= close(function_location
->binary_fd
);
1475 ret
= -LTTNG_ERR_INVALID
;
1480 function_location
->binary_fd
= binary_fd
;
1486 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1487 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1490 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1493 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1495 tracepoint_location
= container_of(location
,
1496 struct lttng_userspace_probe_location_tracepoint
, parent
);
1497 if (tracepoint_location
->binary_fd
>= 0) {
1498 ret
= close(tracepoint_location
->binary_fd
);
1501 ret
= -LTTNG_ERR_INVALID
;
1506 tracepoint_location
->binary_fd
= binary_fd
;
1512 int lttng_userspace_probe_location_function_flatten(
1513 const struct lttng_userspace_probe_location
*location
,
1514 struct lttng_dynamic_buffer
*buffer
)
1516 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1517 struct lttng_userspace_probe_location_function
*probe_function
;
1518 struct lttng_userspace_probe_location_function flat_probe
;
1519 size_t function_name_len
, binary_path_len
;
1520 size_t padding_needed
= 0;
1521 char *flat_probe_start
;
1522 int storage_needed
= 0;
1527 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1528 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1529 ret
= -LTTNG_ERR_INVALID
;
1533 probe_function
= container_of(location
,
1534 struct lttng_userspace_probe_location_function
,
1536 assert(probe_function
->function_name
);
1537 assert(probe_function
->binary_path
);
1540 sizeof(struct lttng_userspace_probe_location_function
);
1541 function_name_len
= strlen(probe_function
->function_name
) + 1;
1542 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1543 storage_needed
+= function_name_len
+ binary_path_len
;
1546 * The lookup method is aligned to 64-bit within the buffer.
1547 * This is needed even if there is no lookup method since
1548 * the next structure in the buffer probably needs to be
1549 * aligned too (depending on the arch).
1551 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1552 storage_needed
+= padding_needed
;
1554 if (location
->lookup_method
) {
1555 /* NOTE: elf look-up method is assumed here. */
1556 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1560 ret
= storage_needed
;
1564 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1565 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1566 buffer
->size
+ storage_needed
);
1572 memset(&flat_probe
, 0, sizeof(flat_probe
));
1574 flat_probe_start
= buffer
->data
+ buffer
->size
;
1575 flat_probe
.parent
.type
= location
->type
;
1577 * The lookup method, if present, is the last element in the flat
1578 * representation of the probe.
1580 if (location
->lookup_method
) {
1581 flat_probe
.parent
.lookup_method
=
1582 (struct lttng_userspace_probe_location_lookup_method
*)
1583 (flat_probe_start
+ sizeof(flat_probe
) +
1584 function_name_len
+ binary_path_len
+ padding_needed
);
1586 flat_probe
.parent
.lookup_method
= NULL
;
1589 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1590 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1591 flat_probe
.binary_fd
= -1;
1592 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1593 sizeof(flat_probe
));
1598 ret
= lttng_dynamic_buffer_append(buffer
,
1599 probe_function
->function_name
, function_name_len
);
1603 ret
= lttng_dynamic_buffer_append(buffer
,
1604 probe_function
->binary_path
, binary_path_len
);
1609 /* Insert padding before the lookup method. */
1610 ret
= lttng_dynamic_buffer_set_size(buffer
,
1611 buffer
->size
+ padding_needed
);
1616 if (!location
->lookup_method
) {
1617 /* Not an error, the default method is used. */
1618 ret
= storage_needed
;
1622 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1623 flat_lookup_method
.parent
.type
=
1624 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1625 ret
= lttng_dynamic_buffer_append(buffer
,
1626 &flat_lookup_method
, sizeof(flat_lookup_method
));
1630 ret
= storage_needed
;
1636 int lttng_userspace_probe_location_tracepoint_flatten(
1637 const struct lttng_userspace_probe_location
*location
,
1638 struct lttng_dynamic_buffer
*buffer
)
1640 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1641 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1642 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1643 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1644 size_t padding_needed
= 0;
1645 int storage_needed
= 0;
1646 char *flat_probe_start
;
1651 /* Only SDT tracepoints are supported at the moment */
1652 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1653 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1654 ret
= -LTTNG_ERR_INVALID
;
1657 probe_tracepoint
= container_of(location
,
1658 struct lttng_userspace_probe_location_tracepoint
,
1660 assert(probe_tracepoint
->probe_name
);
1661 assert(probe_tracepoint
->provider_name
);
1662 assert(probe_tracepoint
->binary_path
);
1664 /* Compute the storage space needed to flatten the probe location */
1665 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1667 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1668 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1669 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1671 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1674 * The lookup method is aligned to 64-bit within the buffer.
1675 * This is needed even if there is no lookup method since
1676 * the next structure in the buffer probably needs to be
1677 * aligned too (depending on the arch).
1679 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1680 storage_needed
+= padding_needed
;
1682 if (location
->lookup_method
) {
1683 /* NOTE: elf look-up method is assumed here. */
1685 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1689 * If the caller set buffer to NULL, return the size of the needed buffer.
1692 ret
= storage_needed
;
1696 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1697 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1698 buffer
->size
+ storage_needed
);
1704 memset(&flat_probe
, 0, sizeof(flat_probe
));
1706 flat_probe_start
= buffer
->data
+ buffer
->size
;
1707 flat_probe
.parent
.type
= location
->type
;
1710 * The lookup method, if present, is the last element in the flat
1711 * representation of the probe.
1713 if (location
->lookup_method
) {
1714 flat_probe
.parent
.lookup_method
=
1715 (struct lttng_userspace_probe_location_lookup_method
*)
1716 (flat_probe_start
+ sizeof(flat_probe
) +
1717 probe_name_len
+ provider_name_len
+
1718 binary_path_len
+ padding_needed
);
1720 flat_probe
.parent
.lookup_method
= NULL
;
1723 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1724 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1725 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1726 flat_probe
.binary_fd
= -1;
1727 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1732 /* Append all the fields to the buffer */
1733 ret
= lttng_dynamic_buffer_append(buffer
,
1734 probe_tracepoint
->probe_name
, probe_name_len
);
1738 ret
= lttng_dynamic_buffer_append(buffer
,
1739 probe_tracepoint
->provider_name
, provider_name_len
);
1743 ret
= lttng_dynamic_buffer_append(buffer
,
1744 probe_tracepoint
->binary_path
, binary_path_len
);
1749 /* Insert padding before the lookup method. */
1750 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1755 if (!location
->lookup_method
) {
1756 /* Not an error, the default method is used. */
1757 ret
= storage_needed
;
1761 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1763 flat_lookup_method
.parent
.type
=
1764 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1765 ret
= lttng_dynamic_buffer_append(buffer
,
1766 &flat_lookup_method
, sizeof(flat_lookup_method
));
1770 ret
= storage_needed
;
1776 int lttng_userspace_probe_location_flatten(
1777 const struct lttng_userspace_probe_location
*location
,
1778 struct lttng_dynamic_buffer
*buffer
)
1782 ret
= -LTTNG_ERR_INVALID
;
1786 /* Only types currently supported. */
1787 switch (location
->type
) {
1788 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1789 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1791 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1792 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1795 ret
= -LTTNG_ERR_INVALID
;
1804 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1805 const struct lttng_userspace_probe_location
*location
)
1807 struct lttng_userspace_probe_location
*new_location
= NULL
;
1808 enum lttng_userspace_probe_location_type type
;
1814 type
= lttng_userspace_probe_location_get_type(location
);
1816 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1818 lttng_userspace_probe_location_function_copy(location
);
1819 if (!new_location
) {
1823 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1825 lttng_userspace_probe_location_tracepoint_copy(location
);
1826 if (!new_location
) {
1831 new_location
= NULL
;
1835 return new_location
;
1839 bool lttng_userspace_probe_location_lookup_method_is_equal(
1840 const struct lttng_userspace_probe_location_lookup_method
*a
,
1841 const struct lttng_userspace_probe_location_lookup_method
*b
)
1843 bool is_equal
= false;
1854 if (a
->type
!= b
->type
) {
1864 bool lttng_userspace_probe_location_is_equal(
1865 const struct lttng_userspace_probe_location
*a
,
1866 const struct lttng_userspace_probe_location
*b
)
1868 bool is_equal
= false;
1879 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1880 a
->lookup_method
, b
->lookup_method
)) {
1884 if (a
->type
!= b
->type
) {
1888 is_equal
= a
->equal
? a
->equal(a
, b
) : true;