2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include "lttng/lttng-error.h"
10 #include <common/compat/string.h>
11 #include <common/error.h>
12 #include <common/macros.h>
13 #include <common/payload.h>
14 #include <common/payload-view.h>
16 #include <lttng/constant.h>
17 #include <lttng/userspace-probe-internal.h>
19 #include <sys/types.h>
20 #include <sys/unistd.h>
22 enum lttng_userspace_probe_location_lookup_method_type
23 lttng_userspace_probe_location_lookup_method_get_type(
24 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
26 return lookup_method
? lookup_method
->type
:
27 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
30 void lttng_userspace_probe_location_lookup_method_destroy(
31 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
40 struct lttng_userspace_probe_location_lookup_method
*
41 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
43 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
44 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
46 elf_method
= zmalloc(sizeof(*elf_method
));
52 ret
= &elf_method
->parent
;
53 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
58 struct lttng_userspace_probe_location_lookup_method
*
59 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
61 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
62 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
64 sdt_method
= zmalloc(sizeof(*sdt_method
));
70 ret
= &sdt_method
->parent
;
71 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
76 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
77 const struct lttng_userspace_probe_location
*location
)
79 return location
? location
->type
:
80 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
84 void lttng_userspace_probe_location_function_destroy(
85 struct lttng_userspace_probe_location
*location
)
87 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
91 location_function
= container_of(location
,
92 struct lttng_userspace_probe_location_function
, parent
);
94 assert(location_function
);
96 free(location_function
->function_name
);
97 free(location_function
->binary_path
);
98 if (location_function
->binary_fd
>= 0) {
99 if (close(location_function
->binary_fd
)) {
107 void lttng_userspace_probe_location_tracepoint_destroy(
108 struct lttng_userspace_probe_location
*location
)
110 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
114 location_tracepoint
= container_of(location
,
115 struct lttng_userspace_probe_location_tracepoint
,
118 assert(location_tracepoint
);
120 free(location_tracepoint
->probe_name
);
121 free(location_tracepoint
->provider_name
);
122 free(location_tracepoint
->binary_path
);
123 if (location_tracepoint
->binary_fd
>= 0) {
124 if (close(location_tracepoint
->binary_fd
)) {
131 void lttng_userspace_probe_location_destroy(
132 struct lttng_userspace_probe_location
*location
)
138 lttng_userspace_probe_location_lookup_method_destroy(
139 location
->lookup_method
);
141 switch (location
->type
) {
142 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
143 lttng_userspace_probe_location_function_destroy(location
);
145 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
146 lttng_userspace_probe_location_tracepoint_destroy(location
);
153 /* Compare two file descriptors based on their inode and device numbers. */
154 static bool fd_is_equal(int a
, int b
)
157 bool is_equal
= false;
158 struct stat a_stat
, b_stat
;
160 if (a
< 0 && b
>= 0) {
164 if (b
< 0 && a
>= 0) {
168 if (a
< 0 && b
< 0) {
169 if (a
== -1 && b
== -1) {
174 /* Invalid state, abort. */
178 /* Both are valid file descriptors. */
179 ret
= fstat(a
, &a_stat
);
181 PERROR("Failed to fstat userspace probe location binary fd %d",
186 ret
= fstat(b
, &b_stat
);
188 PERROR("Failed to fstat userspace probe location binary fd %d",
193 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) &&
194 (a_stat
.st_dev
== b_stat
.st_dev
);
200 static bool lttng_userspace_probe_location_function_is_equal(
201 const struct lttng_userspace_probe_location
*_a
,
202 const struct lttng_userspace_probe_location
*_b
)
204 bool is_equal
= false;
205 struct lttng_userspace_probe_location_function
*a
, *b
;
207 a
= container_of(_a
, struct lttng_userspace_probe_location_function
,
209 b
= container_of(_b
, struct lttng_userspace_probe_location_function
,
212 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
216 assert(a
->function_name
);
217 assert(b
->function_name
);
218 if (strcmp(a
->function_name
, b
->function_name
)) {
222 assert(a
->binary_path
);
223 assert(b
->binary_path
);
224 if (strcmp(a
->binary_path
, b
->binary_path
)) {
228 is_equal
= fd_is_equal(a
->binary_fd
, b
->binary_fd
);
233 static struct lttng_userspace_probe_location
*
234 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
235 const char *function_name
,
236 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
240 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
241 struct lttng_userspace_probe_location
*ret
= NULL
;
242 struct lttng_userspace_probe_location_function
*location
;
245 binary_fd
= open(binary_path
, O_RDONLY
);
247 PERROR("Error opening the binary");
254 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
255 if (!function_name_copy
) {
256 PERROR("Error duplicating the function name");
260 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
261 if (!binary_path_copy
) {
262 PERROR("Error duplicating the function name");
266 location
= zmalloc(sizeof(*location
));
268 PERROR("Error allocating userspace probe location");
272 location
->function_name
= function_name_copy
;
273 location
->binary_path
= binary_path_copy
;
274 location
->binary_fd
= binary_fd
;
275 location
->instrumentation_type
=
276 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
278 ret
= &location
->parent
;
279 ret
->lookup_method
= lookup_method
;
280 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
281 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
285 free(function_name_copy
);
286 free(binary_path_copy
);
287 if (binary_fd
>= 0) {
288 if (close(binary_fd
)) {
289 PERROR("Error closing binary fd in error path");
296 static bool lttng_userspace_probe_location_tracepoint_is_equal(
297 const struct lttng_userspace_probe_location
*_a
,
298 const struct lttng_userspace_probe_location
*_b
)
300 bool is_equal
= false;
301 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
303 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
,
305 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
,
308 assert(a
->probe_name
);
309 assert(b
->probe_name
);
310 if (strcmp(a
->probe_name
, b
->probe_name
)) {
314 assert(a
->provider_name
);
315 assert(b
->provider_name
);
316 if (strcmp(a
->provider_name
, b
->provider_name
)) {
320 assert(a
->binary_path
);
321 assert(b
->binary_path
);
322 if (strcmp(a
->binary_path
, b
->binary_path
)) {
326 is_equal
= fd_is_equal(a
->binary_fd
, b
->binary_fd
);
332 static struct lttng_userspace_probe_location
*
333 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
334 const char *provider_name
, const char *probe_name
,
335 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
339 char *probe_name_copy
= NULL
;
340 char *provider_name_copy
= NULL
;
341 char *binary_path_copy
= NULL
;
342 struct lttng_userspace_probe_location
*ret
= NULL
;
343 struct lttng_userspace_probe_location_tracepoint
*location
;
346 binary_fd
= open(binary_path
, O_RDONLY
);
355 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
356 if (!probe_name_copy
) {
357 PERROR("lttng_strndup");
361 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
362 if (!provider_name_copy
) {
363 PERROR("lttng_strndup");
367 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
368 if (!binary_path_copy
) {
369 PERROR("lttng_strndup");
373 location
= zmalloc(sizeof(*location
));
379 location
->probe_name
= probe_name_copy
;
380 location
->provider_name
= provider_name_copy
;
381 location
->binary_path
= binary_path_copy
;
382 location
->binary_fd
= binary_fd
;
384 ret
= &location
->parent
;
385 ret
->lookup_method
= lookup_method
;
386 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
387 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
391 free(probe_name_copy
);
392 free(provider_name_copy
);
393 free(binary_path_copy
);
394 if (binary_fd
>= 0) {
395 if (close(binary_fd
)) {
396 PERROR("Error closing binary fd in error path");
403 struct lttng_userspace_probe_location
*
404 lttng_userspace_probe_location_function_create(const char *binary_path
,
405 const char *function_name
,
406 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
408 struct lttng_userspace_probe_location
*ret
= NULL
;
410 if (!binary_path
|| !function_name
) {
411 ERR("Invalid argument(s)");
415 switch (lttng_userspace_probe_location_lookup_method_get_type(
417 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
418 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
421 /* Invalid probe location lookup method. */
425 ret
= lttng_userspace_probe_location_function_create_no_check(
426 binary_path
, function_name
, lookup_method
, true);
431 struct lttng_userspace_probe_location
*
432 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
433 const char *provider_name
, const char *probe_name
,
434 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
436 struct lttng_userspace_probe_location
*ret
= NULL
;
438 if (!binary_path
|| !probe_name
|| !provider_name
) {
439 ERR("Invalid argument(s)");
443 switch (lttng_userspace_probe_location_lookup_method_get_type(
445 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
448 /* Invalid probe location lookup method. */
452 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
453 binary_path
, provider_name
, probe_name
, lookup_method
, true);
458 static struct lttng_userspace_probe_location_lookup_method
*
459 lttng_userspace_probe_location_lookup_method_function_elf_copy(
460 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
462 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
463 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
465 assert(lookup_method
);
466 assert(lookup_method
->type
==
467 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
469 elf_method
= zmalloc(sizeof(*elf_method
));
471 PERROR("Error allocating ELF userspace probe lookup method");
475 elf_method
->parent
.type
= lookup_method
->type
;
476 parent
= &elf_method
->parent
;
485 static struct lttng_userspace_probe_location_lookup_method
*
486 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
487 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
489 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
490 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
492 assert(lookup_method
);
493 assert(lookup_method
->type
==
494 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
496 sdt_method
= zmalloc(sizeof(*sdt_method
));
502 sdt_method
->parent
.type
= lookup_method
->type
;
503 parent
= &sdt_method
->parent
;
513 static struct lttng_userspace_probe_location
*
514 lttng_userspace_probe_location_function_copy(
515 const struct lttng_userspace_probe_location
*location
)
517 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
518 struct lttng_userspace_probe_location
*new_location
= NULL
;
519 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
520 const char *binary_path
= NULL
;
521 const char *function_name
= NULL
;
525 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
527 /* Get probe location fields */
528 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
530 ERR("Userspace probe binary path is NULL");
534 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
535 if (!function_name
) {
536 ERR("Userspace probe function name is NULL");
540 /* Duplicate the binary fd */
541 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
543 ERR("Error getting file descriptor to binary");
549 PERROR("Error duplicating file descriptor to binary");
554 * Duplicate probe location method fields
556 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
557 location
->lookup_method
);
558 switch (lookup_type
) {
559 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
561 lttng_userspace_probe_location_lookup_method_function_elf_copy(
562 location
->lookup_method
);
563 if (!lookup_method
) {
568 /* Invalid probe location lookup method. */
572 /* Create the probe_location */
573 new_location
= lttng_userspace_probe_location_function_create_no_check(
574 binary_path
, function_name
, lookup_method
, false);
576 goto destroy_lookup_method
;
579 /* Set the duplicated fd to the new probe_location */
580 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
581 goto destroy_probe_location
;
586 destroy_probe_location
:
587 lttng_userspace_probe_location_destroy(new_location
);
588 destroy_lookup_method
:
589 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
591 if (close(new_fd
) < 0) {
592 PERROR("Error closing duplicated file descriptor in error path");
600 static struct lttng_userspace_probe_location
*
601 lttng_userspace_probe_location_tracepoint_copy(
602 const struct lttng_userspace_probe_location
*location
)
604 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
605 struct lttng_userspace_probe_location
*new_location
= NULL
;
606 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
607 const char *binary_path
= NULL
;
608 const char *probe_name
= NULL
;
609 const char *provider_name
= NULL
;
613 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
615 /* Get probe location fields */
616 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
618 ERR("Userspace probe binary path is NULL");
622 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
624 ERR("Userspace probe probe name is NULL");
628 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
629 if (!provider_name
) {
630 ERR("Userspace probe provider name is NULL");
634 /* Duplicate the binary fd */
635 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
637 ERR("Error getting file descriptor to binary");
643 PERROR("Error duplicating file descriptor to binary");
648 * Duplicate probe location method fields
650 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
651 location
->lookup_method
);
652 switch (lookup_type
) {
653 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
655 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
656 location
->lookup_method
);
657 if (!lookup_method
) {
662 /* Invalid probe location lookup method. */
666 /* Create the probe_location */
667 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
668 binary_path
, provider_name
, probe_name
, lookup_method
, false);
670 goto destroy_lookup_method
;
673 /* Set the duplicated fd to the new probe_location */
674 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
675 goto destroy_probe_location
;
680 destroy_probe_location
:
681 lttng_userspace_probe_location_destroy(new_location
);
682 destroy_lookup_method
:
683 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
685 if (close(new_fd
) < 0) {
686 PERROR("Error closing duplicated file descriptor in error path");
694 const char *lttng_userspace_probe_location_function_get_binary_path(
695 const struct lttng_userspace_probe_location
*location
)
697 const char *ret
= NULL
;
698 struct lttng_userspace_probe_location_function
*function_location
;
700 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
701 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
702 ERR("Invalid argument(s)");
706 function_location
= container_of(location
,
707 struct lttng_userspace_probe_location_function
,
709 ret
= function_location
->binary_path
;
714 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
715 const struct lttng_userspace_probe_location
*location
)
717 const char *ret
= NULL
;
718 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
720 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
721 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
722 ERR("Invalid argument(s)");
726 tracepoint_location
= container_of(location
,
727 struct lttng_userspace_probe_location_tracepoint
,
729 ret
= tracepoint_location
->binary_path
;
734 const char *lttng_userspace_probe_location_function_get_function_name(
735 const struct lttng_userspace_probe_location
*location
)
737 const char *ret
= NULL
;
738 struct lttng_userspace_probe_location_function
*function_location
;
740 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
741 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
742 ERR("Invalid argument(s)");
746 function_location
= container_of(location
,
747 struct lttng_userspace_probe_location_function
, parent
);
748 ret
= function_location
->function_name
;
753 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
754 const struct lttng_userspace_probe_location
*location
)
756 const char *ret
= NULL
;
757 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
759 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
760 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
761 ERR("Invalid argument(s)");
765 tracepoint_location
= container_of(location
,
766 struct lttng_userspace_probe_location_tracepoint
, parent
);
767 ret
= tracepoint_location
->probe_name
;
772 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
773 const struct lttng_userspace_probe_location
*location
)
775 const char *ret
= NULL
;
776 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
778 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
779 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
780 ERR("Invalid argument(s)");
784 tracepoint_location
= container_of(location
,
785 struct lttng_userspace_probe_location_tracepoint
, parent
);
786 ret
= tracepoint_location
->provider_name
;
791 int lttng_userspace_probe_location_function_get_binary_fd(
792 const struct lttng_userspace_probe_location
*location
)
795 struct lttng_userspace_probe_location_function
*function_location
;
797 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
798 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
799 ERR("Invalid argument(s)");
803 function_location
= container_of(location
,
804 struct lttng_userspace_probe_location_function
, parent
);
805 ret
= function_location
->binary_fd
;
810 enum lttng_userspace_probe_location_function_instrumentation_type
811 lttng_userspace_probe_location_function_get_instrumentation_type(
812 const struct lttng_userspace_probe_location
*location
)
814 enum lttng_userspace_probe_location_function_instrumentation_type type
;
815 struct lttng_userspace_probe_location_function
*function_location
;
817 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
818 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
819 ERR("Invalid argument(s)");
820 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
824 function_location
= container_of(location
,
825 struct lttng_userspace_probe_location_function
, parent
);
826 type
= function_location
->instrumentation_type
;
831 enum lttng_userspace_probe_location_status
832 lttng_userspace_probe_location_function_set_instrumentation_type(
833 const struct lttng_userspace_probe_location
*location
,
834 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
836 enum lttng_userspace_probe_location_status status
=
837 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
838 struct lttng_userspace_probe_location_function
*function_location
;
840 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
841 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
842 instrumentation_type
!=
843 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
844 ERR("Invalid argument(s)");
845 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
849 function_location
= container_of(location
,
850 struct lttng_userspace_probe_location_function
, parent
);
851 function_location
->instrumentation_type
= instrumentation_type
;
856 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
857 const struct lttng_userspace_probe_location
*location
)
860 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
862 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
863 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
864 ERR("Invalid argument(s)");
868 tracepoint_location
= container_of(location
,
869 struct lttng_userspace_probe_location_tracepoint
, parent
);
870 ret
= tracepoint_location
->binary_fd
;
875 static struct lttng_userspace_probe_location_lookup_method
*
876 lttng_userspace_probe_location_function_get_lookup_method(
877 const struct lttng_userspace_probe_location
*location
)
879 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
881 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
882 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
883 ERR("Invalid argument(s)");
887 ret
= location
->lookup_method
;
892 static struct lttng_userspace_probe_location_lookup_method
*
893 lttng_userspace_probe_location_tracepoint_get_lookup_method(
894 const struct lttng_userspace_probe_location
*location
)
896 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
898 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
899 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
900 ERR("Invalid argument(s)");
904 ret
= location
->lookup_method
;
909 const struct lttng_userspace_probe_location_lookup_method
*
910 lttng_userspace_probe_location_get_lookup_method(
911 const struct lttng_userspace_probe_location
*location
)
913 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
916 switch (location
->type
) {
917 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
918 ret
= lttng_userspace_probe_location_function_get_lookup_method(
921 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
922 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
926 ERR("Unknowned lookup method.");
933 int lttng_userspace_probe_location_lookup_method_serialize(
934 struct lttng_userspace_probe_location_lookup_method
*method
,
935 struct lttng_payload
*payload
)
938 struct lttng_userspace_probe_location_lookup_method_comm
941 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
942 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
944 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &lookup_method_comm
,
945 sizeof(lookup_method_comm
));
950 ret
= sizeof(lookup_method_comm
);
956 int lttng_userspace_probe_location_function_serialize(
957 const struct lttng_userspace_probe_location
*location
,
958 struct lttng_payload
*payload
)
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 (payload
&& location_function
->binary_fd
< 0) {
978 ret
= -LTTNG_ERR_INVALID
;
982 function_name_len
= strlen(location_function
->function_name
);
983 if (function_name_len
== 0) {
984 ret
= -LTTNG_ERR_INVALID
;
987 binary_path_len
= strlen(location_function
->binary_path
);
988 if (binary_path_len
== 0) {
989 ret
= -LTTNG_ERR_INVALID
;
993 location_function_comm
.function_name_len
= function_name_len
+ 1;
994 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
997 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
998 &location_function_comm
,
999 sizeof(location_function_comm
));
1001 ret
= -LTTNG_ERR_INVALID
;
1004 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1005 location_function
->function_name
,
1006 location_function_comm
.function_name_len
);
1008 ret
= -LTTNG_ERR_INVALID
;
1011 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1012 location_function
->binary_path
,
1013 location_function_comm
.binary_path_len
);
1015 ret
= -LTTNG_ERR_INVALID
;
1018 ret
= lttng_payload_push_fd(
1019 payload
, location_function
->binary_fd
);
1021 ret
= -LTTNG_ERR_INVALID
;
1025 ret
= sizeof(location_function_comm
) +
1026 location_function_comm
.function_name_len
+
1027 location_function_comm
.binary_path_len
;
1033 int lttng_userspace_probe_location_tracepoint_serialize(
1034 const struct lttng_userspace_probe_location
*location
,
1035 struct lttng_payload
*payload
)
1038 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1039 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1040 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1043 assert(lttng_userspace_probe_location_get_type(location
) ==
1044 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1046 location_tracepoint
= container_of(location
,
1047 struct lttng_userspace_probe_location_tracepoint
,
1049 if (!location_tracepoint
->probe_name
||
1050 !location_tracepoint
->provider_name
||
1051 !location_tracepoint
->binary_path
) {
1052 ret
= -LTTNG_ERR_INVALID
;
1056 if (payload
&& location_tracepoint
->binary_fd
< 0) {
1057 ret
= -LTTNG_ERR_INVALID
;
1061 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1062 if (probe_name_len
== 0) {
1063 ret
= -LTTNG_ERR_INVALID
;
1067 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1068 if (provider_name_len
== 0) {
1069 ret
= -LTTNG_ERR_INVALID
;
1073 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1074 if (binary_path_len
== 0) {
1075 ret
= -LTTNG_ERR_INVALID
;
1079 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1080 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1081 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1084 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1085 &location_tracepoint_comm
,
1086 sizeof(location_tracepoint_comm
));
1088 ret
= -LTTNG_ERR_INVALID
;
1091 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1092 location_tracepoint
->probe_name
,
1093 location_tracepoint_comm
.probe_name_len
);
1095 ret
= -LTTNG_ERR_INVALID
;
1098 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1099 location_tracepoint
->provider_name
,
1100 location_tracepoint_comm
.provider_name_len
);
1102 ret
= -LTTNG_ERR_INVALID
;
1105 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1106 location_tracepoint
->binary_path
,
1107 location_tracepoint_comm
.binary_path_len
);
1109 ret
= -LTTNG_ERR_INVALID
;
1112 ret
= lttng_payload_push_fd(
1113 payload
, location_tracepoint
->binary_fd
);
1115 ret
= -LTTNG_ERR_INVALID
;
1120 ret
= sizeof(location_tracepoint_comm
) +
1121 location_tracepoint_comm
.probe_name_len
+
1122 location_tracepoint_comm
.provider_name_len
+
1123 location_tracepoint_comm
.binary_path_len
;
1129 int lttng_userspace_probe_location_serialize(
1130 const struct lttng_userspace_probe_location
*location
,
1131 struct lttng_payload
*payload
)
1133 int ret
, buffer_use
= 0;
1134 struct lttng_userspace_probe_location_comm location_generic_comm
;
1137 ERR("Invalid argument(s)");
1138 ret
= -LTTNG_ERR_INVALID
;
1142 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1144 location_generic_comm
.type
= (int8_t) location
->type
;
1146 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1147 &location_generic_comm
,
1148 sizeof(location_generic_comm
));
1153 buffer_use
+= sizeof(location_generic_comm
);
1155 switch (lttng_userspace_probe_location_get_type(location
)) {
1156 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1157 ret
= lttng_userspace_probe_location_function_serialize(
1160 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1161 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1165 ERR("Unsupported probe location type");
1166 ret
= -LTTNG_ERR_INVALID
;
1174 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1175 location
->lookup_method
, payload
);
1185 int lttng_userspace_probe_location_function_create_from_payload(
1186 struct lttng_payload_view
*view
,
1187 struct lttng_userspace_probe_location
**location
)
1189 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1190 const char *function_name_src
, *binary_path_src
;
1191 char *function_name
= NULL
, *binary_path
= NULL
;
1193 size_t expected_size
;
1194 const int binary_fd
= lttng_payload_view_pop_fd(view
);
1198 if (binary_fd
< 0) {
1199 ret
= -LTTNG_ERR_INVALID
;
1203 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1204 ret
= -LTTNG_ERR_INVALID
;
1208 location_function_comm
=
1209 (typeof(location_function_comm
)) view
->buffer
.data
;
1211 expected_size
= sizeof(*location_function_comm
) +
1212 location_function_comm
->function_name_len
+
1213 location_function_comm
->binary_path_len
;
1215 if (view
->buffer
.size
< expected_size
) {
1216 ret
= -LTTNG_ERR_INVALID
;
1220 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1221 binary_path_src
= function_name_src
+
1222 location_function_comm
->function_name_len
;
1224 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1225 ret
= -LTTNG_ERR_INVALID
;
1228 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1229 ret
= -LTTNG_ERR_INVALID
;
1233 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1234 if (!function_name
) {
1235 PERROR("lttng_strndup");
1236 ret
= -LTTNG_ERR_NOMEM
;
1240 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1242 PERROR("lttng_strndup");
1243 ret
= -LTTNG_ERR_NOMEM
;
1247 *location
= lttng_userspace_probe_location_function_create_no_check(
1248 binary_path
, function_name
, NULL
, false);
1250 ret
= -LTTNG_ERR_INVALID
;
1254 ret
= lttng_userspace_probe_location_function_set_binary_fd(
1255 *location
, binary_fd
);
1257 const int close_ret
= close(binary_fd
);
1260 PERROR("Failed to close userspace probe function binary fd");
1262 ret
= -LTTNG_ERR_INVALID
;
1266 ret
= (int) expected_size
;
1268 free(function_name
);
1274 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1275 struct lttng_payload_view
*view
,
1276 struct lttng_userspace_probe_location
**location
)
1278 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1279 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1280 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1282 size_t expected_size
;
1283 const int binary_fd
= lttng_payload_view_pop_fd(view
);
1287 if (binary_fd
< 0) {
1288 ret
= -LTTNG_ERR_INVALID
;
1292 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1293 ret
= -LTTNG_ERR_INVALID
;
1297 location_tracepoint_comm
=
1298 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1300 expected_size
= sizeof(*location_tracepoint_comm
) +
1301 location_tracepoint_comm
->probe_name_len
+
1302 location_tracepoint_comm
->provider_name_len
+
1303 location_tracepoint_comm
->binary_path_len
;
1305 if (view
->buffer
.size
< expected_size
) {
1306 ret
= -LTTNG_ERR_INVALID
;
1310 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1311 provider_name_src
= probe_name_src
+
1312 location_tracepoint_comm
->probe_name_len
;
1313 binary_path_src
= provider_name_src
+
1314 location_tracepoint_comm
->provider_name_len
;
1316 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1317 ret
= -LTTNG_ERR_INVALID
;
1321 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1322 ret
= -LTTNG_ERR_INVALID
;
1326 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1327 ret
= -LTTNG_ERR_INVALID
;
1331 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1333 PERROR("lttng_strndup");
1336 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1337 if (!provider_name
) {
1338 PERROR("lttng_strndup");
1342 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1344 PERROR("lttng_strndup");
1348 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1349 binary_path
, provider_name
, probe_name
, NULL
, false);
1351 ret
= -LTTNG_ERR_INVALID
;
1355 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd(
1356 *location
, binary_fd
);
1358 const int close_ret
= close(binary_fd
);
1361 PERROR("Failed to close userspace probe tracepoint binary fd");
1363 ret
= -LTTNG_ERR_INVALID
;
1367 ret
= (int) expected_size
;
1370 free(provider_name
);
1376 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1377 struct lttng_payload_view
*view
,
1378 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1381 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1382 enum lttng_userspace_probe_location_lookup_method_type type
;
1385 assert(lookup_method
);
1387 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1388 ret
= -LTTNG_ERR_INVALID
;
1392 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1393 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1396 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1397 *lookup_method
= NULL
;
1399 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1401 lttng_userspace_probe_location_lookup_method_function_elf_create();
1402 if (!(*lookup_method
)) {
1403 ret
= -LTTNG_ERR_INVALID
;
1407 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1409 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1410 if (!(*lookup_method
)) {
1411 ret
= -LTTNG_ERR_INVALID
;
1416 ret
= -LTTNG_ERR_INVALID
;
1420 ret
= sizeof(*lookup_comm
);
1426 int lttng_userspace_probe_location_create_from_payload(
1427 struct lttng_payload_view
*view
,
1428 struct lttng_userspace_probe_location
**location
)
1430 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1431 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1432 enum lttng_userspace_probe_location_type type
;
1439 lookup_method
= NULL
;
1441 if (view
->buffer
.size
<= sizeof(*probe_location_comm
)) {
1442 ret
= -LTTNG_ERR_INVALID
;
1446 probe_location_comm
= (typeof(probe_location_comm
)) view
->buffer
.data
;
1447 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1448 consumed
+= sizeof(*probe_location_comm
);
1451 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1453 struct lttng_payload_view location_view
=
1454 lttng_payload_view_from_view(
1455 view
, consumed
, -1);
1457 ret
= lttng_userspace_probe_location_function_create_from_payload(
1458 &location_view
, location
);
1464 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1466 struct lttng_payload_view location_view
=
1467 lttng_payload_view_from_view(view
, consumed
, -1);
1469 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1470 &location_view
, location
);
1477 ret
= -LTTNG_ERR_INVALID
;
1482 if (view
->buffer
.size
<= consumed
) {
1483 ret
= -LTTNG_ERR_INVALID
;
1488 struct lttng_payload_view lookup_method_view
=
1489 lttng_payload_view_from_view(
1490 view
, consumed
, -1);
1492 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1493 &lookup_method_view
, &lookup_method
);
1496 ret
= -LTTNG_ERR_INVALID
;
1500 assert(lookup_method
);
1501 (*location
)->lookup_method
= lookup_method
;
1502 lookup_method
= NULL
;
1509 int lttng_userspace_probe_location_function_set_binary_fd(
1510 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1513 struct lttng_userspace_probe_location_function
*function_location
;
1516 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1518 function_location
= container_of(location
,
1519 struct lttng_userspace_probe_location_function
, parent
);
1520 if (function_location
->binary_fd
>= 0) {
1521 ret
= close(function_location
->binary_fd
);
1524 ret
= -LTTNG_ERR_INVALID
;
1529 function_location
->binary_fd
= binary_fd
;
1535 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1536 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1539 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1542 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1544 tracepoint_location
= container_of(location
,
1545 struct lttng_userspace_probe_location_tracepoint
, parent
);
1546 if (tracepoint_location
->binary_fd
>= 0) {
1547 ret
= close(tracepoint_location
->binary_fd
);
1550 ret
= -LTTNG_ERR_INVALID
;
1555 tracepoint_location
->binary_fd
= binary_fd
;
1561 int lttng_userspace_probe_location_function_flatten(
1562 const struct lttng_userspace_probe_location
*location
,
1563 struct lttng_dynamic_buffer
*buffer
)
1565 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1566 struct lttng_userspace_probe_location_function
*probe_function
;
1567 struct lttng_userspace_probe_location_function flat_probe
;
1568 size_t function_name_len
, binary_path_len
;
1569 size_t padding_needed
= 0;
1570 char *flat_probe_start
;
1571 int storage_needed
= 0;
1576 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1577 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1578 ret
= -LTTNG_ERR_INVALID
;
1582 probe_function
= container_of(location
,
1583 struct lttng_userspace_probe_location_function
,
1585 assert(probe_function
->function_name
);
1586 assert(probe_function
->binary_path
);
1589 sizeof(struct lttng_userspace_probe_location_function
);
1590 function_name_len
= strlen(probe_function
->function_name
) + 1;
1591 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1592 storage_needed
+= function_name_len
+ binary_path_len
;
1595 * The lookup method is aligned to 64-bit within the buffer.
1596 * This is needed even if there is no lookup method since
1597 * the next structure in the buffer probably needs to be
1598 * aligned too (depending on the arch).
1600 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1601 storage_needed
+= padding_needed
;
1603 if (location
->lookup_method
) {
1604 /* NOTE: elf look-up method is assumed here. */
1605 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1609 ret
= storage_needed
;
1613 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1614 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1615 buffer
->size
+ storage_needed
);
1621 memset(&flat_probe
, 0, sizeof(flat_probe
));
1623 flat_probe_start
= buffer
->data
+ buffer
->size
;
1624 flat_probe
.parent
.type
= location
->type
;
1626 * The lookup method, if present, is the last element in the flat
1627 * representation of the probe.
1629 if (location
->lookup_method
) {
1630 flat_probe
.parent
.lookup_method
=
1631 (struct lttng_userspace_probe_location_lookup_method
*)
1632 (flat_probe_start
+ sizeof(flat_probe
) +
1633 function_name_len
+ binary_path_len
+ padding_needed
);
1635 flat_probe
.parent
.lookup_method
= NULL
;
1638 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1639 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1640 flat_probe
.binary_fd
= -1;
1641 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1642 sizeof(flat_probe
));
1647 ret
= lttng_dynamic_buffer_append(buffer
,
1648 probe_function
->function_name
, function_name_len
);
1652 ret
= lttng_dynamic_buffer_append(buffer
,
1653 probe_function
->binary_path
, binary_path_len
);
1658 /* Insert padding before the lookup method. */
1659 ret
= lttng_dynamic_buffer_set_size(buffer
,
1660 buffer
->size
+ padding_needed
);
1665 if (!location
->lookup_method
) {
1666 /* Not an error, the default method is used. */
1667 ret
= storage_needed
;
1671 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1672 flat_lookup_method
.parent
.type
=
1673 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1674 ret
= lttng_dynamic_buffer_append(buffer
,
1675 &flat_lookup_method
, sizeof(flat_lookup_method
));
1679 ret
= storage_needed
;
1685 int lttng_userspace_probe_location_tracepoint_flatten(
1686 const struct lttng_userspace_probe_location
*location
,
1687 struct lttng_dynamic_buffer
*buffer
)
1689 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1690 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1691 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1692 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1693 size_t padding_needed
= 0;
1694 int storage_needed
= 0;
1695 char *flat_probe_start
;
1700 /* Only SDT tracepoints are supported at the moment */
1701 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1702 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1703 ret
= -LTTNG_ERR_INVALID
;
1706 probe_tracepoint
= container_of(location
,
1707 struct lttng_userspace_probe_location_tracepoint
,
1709 assert(probe_tracepoint
->probe_name
);
1710 assert(probe_tracepoint
->provider_name
);
1711 assert(probe_tracepoint
->binary_path
);
1713 /* Compute the storage space needed to flatten the probe location */
1714 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1716 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1717 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1718 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1720 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1723 * The lookup method is aligned to 64-bit within the buffer.
1724 * This is needed even if there is no lookup method since
1725 * the next structure in the buffer probably needs to be
1726 * aligned too (depending on the arch).
1728 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1729 storage_needed
+= padding_needed
;
1731 if (location
->lookup_method
) {
1732 /* NOTE: elf look-up method is assumed here. */
1734 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1738 * If the caller set buffer to NULL, return the size of the needed buffer.
1741 ret
= storage_needed
;
1745 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1746 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1747 buffer
->size
+ storage_needed
);
1753 memset(&flat_probe
, 0, sizeof(flat_probe
));
1755 flat_probe_start
= buffer
->data
+ buffer
->size
;
1756 flat_probe
.parent
.type
= location
->type
;
1759 * The lookup method, if present, is the last element in the flat
1760 * representation of the probe.
1762 if (location
->lookup_method
) {
1763 flat_probe
.parent
.lookup_method
=
1764 (struct lttng_userspace_probe_location_lookup_method
*)
1765 (flat_probe_start
+ sizeof(flat_probe
) +
1766 probe_name_len
+ provider_name_len
+
1767 binary_path_len
+ padding_needed
);
1769 flat_probe
.parent
.lookup_method
= NULL
;
1772 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1773 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1774 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1775 flat_probe
.binary_fd
= -1;
1776 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1781 /* Append all the fields to the buffer */
1782 ret
= lttng_dynamic_buffer_append(buffer
,
1783 probe_tracepoint
->probe_name
, probe_name_len
);
1787 ret
= lttng_dynamic_buffer_append(buffer
,
1788 probe_tracepoint
->provider_name
, provider_name_len
);
1792 ret
= lttng_dynamic_buffer_append(buffer
,
1793 probe_tracepoint
->binary_path
, binary_path_len
);
1798 /* Insert padding before the lookup method. */
1799 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1804 if (!location
->lookup_method
) {
1805 /* Not an error, the default method is used. */
1806 ret
= storage_needed
;
1810 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1812 flat_lookup_method
.parent
.type
=
1813 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1814 ret
= lttng_dynamic_buffer_append(buffer
,
1815 &flat_lookup_method
, sizeof(flat_lookup_method
));
1819 ret
= storage_needed
;
1825 int lttng_userspace_probe_location_flatten(
1826 const struct lttng_userspace_probe_location
*location
,
1827 struct lttng_dynamic_buffer
*buffer
)
1831 ret
= -LTTNG_ERR_INVALID
;
1835 /* Only types currently supported. */
1836 switch (location
->type
) {
1837 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1838 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1840 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1841 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1844 ret
= -LTTNG_ERR_INVALID
;
1853 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1854 const struct lttng_userspace_probe_location
*location
)
1856 struct lttng_userspace_probe_location
*new_location
= NULL
;
1857 enum lttng_userspace_probe_location_type type
;
1863 type
= lttng_userspace_probe_location_get_type(location
);
1865 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1867 lttng_userspace_probe_location_function_copy(location
);
1868 if (!new_location
) {
1872 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1874 lttng_userspace_probe_location_tracepoint_copy(location
);
1875 if (!new_location
) {
1880 new_location
= NULL
;
1884 return new_location
;
1888 bool lttng_userspace_probe_location_lookup_method_is_equal(
1889 const struct lttng_userspace_probe_location_lookup_method
*a
,
1890 const struct lttng_userspace_probe_location_lookup_method
*b
)
1892 bool is_equal
= false;
1903 if (a
->type
!= b
->type
) {
1913 bool lttng_userspace_probe_location_is_equal(
1914 const struct lttng_userspace_probe_location
*a
,
1915 const struct lttng_userspace_probe_location
*b
)
1917 bool is_equal
= false;
1928 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1929 a
->lookup_method
, b
->lookup_method
)) {
1933 if (a
->type
!= b
->type
) {
1937 is_equal
= a
->equal
? a
->equal(a
, b
) : true;