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>
23 int lttng_userspace_probe_location_function_set_binary_fd_handle(
24 struct lttng_userspace_probe_location
*location
,
25 struct fd_handle
*binary_fd_handle
);
28 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
29 struct lttng_userspace_probe_location
*location
,
30 struct fd_handle
*binary_fd_handle
);
32 enum lttng_userspace_probe_location_lookup_method_type
33 lttng_userspace_probe_location_lookup_method_get_type(
34 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
36 return lookup_method
? lookup_method
->type
:
37 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
40 void lttng_userspace_probe_location_lookup_method_destroy(
41 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
50 struct lttng_userspace_probe_location_lookup_method
*
51 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
53 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
54 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
56 elf_method
= zmalloc(sizeof(*elf_method
));
62 ret
= &elf_method
->parent
;
63 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
68 struct lttng_userspace_probe_location_lookup_method
*
69 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
71 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
72 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
74 sdt_method
= zmalloc(sizeof(*sdt_method
));
80 ret
= &sdt_method
->parent
;
81 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
86 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
87 const struct lttng_userspace_probe_location
*location
)
89 return location
? location
->type
:
90 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
94 void lttng_userspace_probe_location_function_destroy(
95 struct lttng_userspace_probe_location
*location
)
97 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
101 location_function
= container_of(location
,
102 struct lttng_userspace_probe_location_function
, parent
);
104 assert(location_function
);
106 free(location_function
->function_name
);
107 free(location_function
->binary_path
);
108 fd_handle_put(location_function
->binary_fd_handle
);
113 void lttng_userspace_probe_location_tracepoint_destroy(
114 struct lttng_userspace_probe_location
*location
)
116 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
120 location_tracepoint
= container_of(location
,
121 struct lttng_userspace_probe_location_tracepoint
,
124 assert(location_tracepoint
);
126 free(location_tracepoint
->probe_name
);
127 free(location_tracepoint
->provider_name
);
128 free(location_tracepoint
->binary_path
);
129 fd_handle_put(location_tracepoint
->binary_fd_handle
);
133 void lttng_userspace_probe_location_destroy(
134 struct lttng_userspace_probe_location
*location
)
140 lttng_userspace_probe_location_lookup_method_destroy(
141 location
->lookup_method
);
143 switch (location
->type
) {
144 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
145 lttng_userspace_probe_location_function_destroy(location
);
147 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
148 lttng_userspace_probe_location_tracepoint_destroy(location
);
155 /* Compare two file descriptors based on their inode and device numbers. */
156 static bool fd_is_equal(int a
, int b
)
159 bool is_equal
= false;
160 struct stat a_stat
, b_stat
;
162 if (a
< 0 && b
>= 0) {
166 if (b
< 0 && a
>= 0) {
170 if (a
< 0 && b
< 0) {
171 if (a
== -1 && b
== -1) {
176 /* Invalid state, abort. */
180 /* Both are valid file descriptors. */
181 ret
= fstat(a
, &a_stat
);
183 PERROR("Failed to fstat userspace probe location binary fd %d",
188 ret
= fstat(b
, &b_stat
);
190 PERROR("Failed to fstat userspace probe location binary fd %d",
195 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) &&
196 (a_stat
.st_dev
== b_stat
.st_dev
);
202 static bool lttng_userspace_probe_location_function_is_equal(
203 const struct lttng_userspace_probe_location
*_a
,
204 const struct lttng_userspace_probe_location
*_b
)
206 bool is_equal
= false;
207 struct lttng_userspace_probe_location_function
*a
, *b
;
209 a
= container_of(_a
, struct lttng_userspace_probe_location_function
,
211 b
= container_of(_b
, struct lttng_userspace_probe_location_function
,
214 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
218 assert(a
->function_name
);
219 assert(b
->function_name
);
220 if (strcmp(a
->function_name
, b
->function_name
)) {
224 assert(a
->binary_path
);
225 assert(b
->binary_path
);
226 if (strcmp(a
->binary_path
, b
->binary_path
)) {
230 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
231 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
236 static struct lttng_userspace_probe_location
*
237 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
238 const char *function_name
,
239 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
243 struct fd_handle
*binary_fd_handle
= NULL
;
244 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
245 struct lttng_userspace_probe_location
*ret
= NULL
;
246 struct lttng_userspace_probe_location_function
*location
;
249 binary_fd
= open(binary_path
, O_RDONLY
);
251 PERROR("Error opening the binary");
255 binary_fd_handle
= fd_handle_create(binary_fd
);
260 /* Ownership transferred to fd_handle. */
264 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
265 if (!function_name_copy
) {
266 PERROR("Error duplicating the function name");
270 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
271 if (!binary_path_copy
) {
272 PERROR("Error duplicating the function name");
276 location
= zmalloc(sizeof(*location
));
278 PERROR("Error allocating userspace probe location");
282 location
->function_name
= function_name_copy
;
283 location
->binary_path
= binary_path_copy
;
284 location
->binary_fd_handle
= binary_fd_handle
;
285 binary_fd_handle
= NULL
;
286 location
->instrumentation_type
=
287 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
289 ret
= &location
->parent
;
290 ret
->lookup_method
= lookup_method
;
291 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
292 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
296 free(function_name_copy
);
297 free(binary_path_copy
);
298 if (binary_fd
>= 0) {
299 if (close(binary_fd
)) {
300 PERROR("Error closing binary fd in error path");
303 fd_handle_put(binary_fd_handle
);
308 static bool lttng_userspace_probe_location_tracepoint_is_equal(
309 const struct lttng_userspace_probe_location
*_a
,
310 const struct lttng_userspace_probe_location
*_b
)
312 bool is_equal
= false;
313 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
315 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
,
317 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
,
320 assert(a
->probe_name
);
321 assert(b
->probe_name
);
322 if (strcmp(a
->probe_name
, b
->probe_name
)) {
326 assert(a
->provider_name
);
327 assert(b
->provider_name
);
328 if (strcmp(a
->provider_name
, b
->provider_name
)) {
332 assert(a
->binary_path
);
333 assert(b
->binary_path
);
334 if (strcmp(a
->binary_path
, b
->binary_path
)) {
338 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
339 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
345 static struct lttng_userspace_probe_location
*
346 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
347 const char *provider_name
, const char *probe_name
,
348 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
352 struct fd_handle
*binary_fd_handle
= NULL
;
353 char *probe_name_copy
= NULL
;
354 char *provider_name_copy
= NULL
;
355 char *binary_path_copy
= NULL
;
356 struct lttng_userspace_probe_location
*ret
= NULL
;
357 struct lttng_userspace_probe_location_tracepoint
*location
;
360 binary_fd
= open(binary_path
, O_RDONLY
);
366 binary_fd_handle
= fd_handle_create(binary_fd
);
371 /* Ownership transferred to fd_handle. */
375 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
376 if (!probe_name_copy
) {
377 PERROR("lttng_strndup");
381 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
382 if (!provider_name_copy
) {
383 PERROR("lttng_strndup");
387 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
388 if (!binary_path_copy
) {
389 PERROR("lttng_strndup");
393 location
= zmalloc(sizeof(*location
));
399 location
->probe_name
= probe_name_copy
;
400 location
->provider_name
= provider_name_copy
;
401 location
->binary_path
= binary_path_copy
;
402 location
->binary_fd_handle
= binary_fd_handle
;
403 binary_fd_handle
= NULL
;
405 ret
= &location
->parent
;
406 ret
->lookup_method
= lookup_method
;
407 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
408 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
412 free(probe_name_copy
);
413 free(provider_name_copy
);
414 free(binary_path_copy
);
415 if (binary_fd
>= 0) {
416 if (close(binary_fd
)) {
417 PERROR("Error closing binary fd in error path");
420 fd_handle_put(binary_fd_handle
);
425 struct lttng_userspace_probe_location
*
426 lttng_userspace_probe_location_function_create(const char *binary_path
,
427 const char *function_name
,
428 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
430 struct lttng_userspace_probe_location
*ret
= NULL
;
432 if (!binary_path
|| !function_name
) {
433 ERR("Invalid argument(s)");
437 switch (lttng_userspace_probe_location_lookup_method_get_type(
439 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
440 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
443 /* Invalid probe location lookup method. */
447 ret
= lttng_userspace_probe_location_function_create_no_check(
448 binary_path
, function_name
, lookup_method
, true);
453 struct lttng_userspace_probe_location
*
454 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
455 const char *provider_name
, const char *probe_name
,
456 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
458 struct lttng_userspace_probe_location
*ret
= NULL
;
460 if (!binary_path
|| !probe_name
|| !provider_name
) {
461 ERR("Invalid argument(s)");
465 switch (lttng_userspace_probe_location_lookup_method_get_type(
467 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
470 /* Invalid probe location lookup method. */
474 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
475 binary_path
, provider_name
, probe_name
, lookup_method
, true);
480 static struct lttng_userspace_probe_location_lookup_method
*
481 lttng_userspace_probe_location_lookup_method_function_elf_copy(
482 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
484 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
485 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
487 assert(lookup_method
);
488 assert(lookup_method
->type
==
489 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
491 elf_method
= zmalloc(sizeof(*elf_method
));
493 PERROR("Error allocating ELF userspace probe lookup method");
497 elf_method
->parent
.type
= lookup_method
->type
;
498 parent
= &elf_method
->parent
;
507 static struct lttng_userspace_probe_location_lookup_method
*
508 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
509 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
511 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
512 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
514 assert(lookup_method
);
515 assert(lookup_method
->type
==
516 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
518 sdt_method
= zmalloc(sizeof(*sdt_method
));
524 sdt_method
->parent
.type
= lookup_method
->type
;
525 parent
= &sdt_method
->parent
;
535 static struct lttng_userspace_probe_location
*
536 lttng_userspace_probe_location_function_copy(
537 const struct lttng_userspace_probe_location
*location
)
539 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
540 struct lttng_userspace_probe_location
*new_location
= NULL
;
541 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
542 const char *binary_path
= NULL
;
543 const char *function_name
= NULL
;
544 struct lttng_userspace_probe_location_function
*function_location
;
547 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
548 function_location
= container_of(
549 location
, typeof(*function_location
), parent
);
551 /* Get probe location fields */
552 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
554 ERR("Userspace probe binary path is NULL");
558 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
559 if (!function_name
) {
560 ERR("Userspace probe function name is NULL");
565 * Duplicate probe location method fields
567 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
568 location
->lookup_method
);
569 switch (lookup_type
) {
570 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
572 lttng_userspace_probe_location_lookup_method_function_elf_copy(
573 location
->lookup_method
);
574 if (!lookup_method
) {
579 /* Invalid probe location lookup method. */
583 /* Create the probe_location */
584 new_location
= lttng_userspace_probe_location_function_create_no_check(
585 binary_path
, function_name
, lookup_method
, false);
587 goto destroy_lookup_method
;
590 /* Set the duplicated fd to the new probe_location */
591 if (lttng_userspace_probe_location_function_set_binary_fd_handle(new_location
,
592 function_location
->binary_fd_handle
) < 0) {
593 goto destroy_probe_location
;
598 destroy_probe_location
:
599 lttng_userspace_probe_location_destroy(new_location
);
600 destroy_lookup_method
:
601 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
608 static struct lttng_userspace_probe_location
*
609 lttng_userspace_probe_location_tracepoint_copy(
610 const struct lttng_userspace_probe_location
*location
)
612 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
613 struct lttng_userspace_probe_location
*new_location
= NULL
;
614 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
615 const char *binary_path
= NULL
;
616 const char *probe_name
= NULL
;
617 const char *provider_name
= NULL
;
618 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
621 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
622 tracepoint_location
= container_of(
623 location
, typeof(*tracepoint_location
), parent
);
625 /* Get probe location fields */
626 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
628 ERR("Userspace probe binary path is NULL");
632 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
634 ERR("Userspace probe probe name is NULL");
638 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
639 if (!provider_name
) {
640 ERR("Userspace probe provider name is NULL");
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_handle(new_location
,
672 tracepoint_location
->binary_fd_handle
) < 0) {
673 goto destroy_probe_location
;
678 destroy_probe_location
:
679 lttng_userspace_probe_location_destroy(new_location
);
680 destroy_lookup_method
:
681 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
688 const char *lttng_userspace_probe_location_function_get_binary_path(
689 const struct lttng_userspace_probe_location
*location
)
691 const char *ret
= NULL
;
692 struct lttng_userspace_probe_location_function
*function_location
;
694 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
695 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
696 ERR("Invalid argument(s)");
700 function_location
= container_of(location
,
701 struct lttng_userspace_probe_location_function
,
703 ret
= function_location
->binary_path
;
708 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
709 const struct lttng_userspace_probe_location
*location
)
711 const char *ret
= NULL
;
712 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
714 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
715 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
716 ERR("Invalid argument(s)");
720 tracepoint_location
= container_of(location
,
721 struct lttng_userspace_probe_location_tracepoint
,
723 ret
= tracepoint_location
->binary_path
;
728 const char *lttng_userspace_probe_location_function_get_function_name(
729 const struct lttng_userspace_probe_location
*location
)
731 const char *ret
= NULL
;
732 struct lttng_userspace_probe_location_function
*function_location
;
734 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
735 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
736 ERR("Invalid argument(s)");
740 function_location
= container_of(location
,
741 struct lttng_userspace_probe_location_function
, parent
);
742 ret
= function_location
->function_name
;
747 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
748 const struct lttng_userspace_probe_location
*location
)
750 const char *ret
= NULL
;
751 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
753 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
754 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
755 ERR("Invalid argument(s)");
759 tracepoint_location
= container_of(location
,
760 struct lttng_userspace_probe_location_tracepoint
, parent
);
761 ret
= tracepoint_location
->probe_name
;
766 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
767 const struct lttng_userspace_probe_location
*location
)
769 const char *ret
= NULL
;
770 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
772 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
773 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
774 ERR("Invalid argument(s)");
778 tracepoint_location
= container_of(location
,
779 struct lttng_userspace_probe_location_tracepoint
, parent
);
780 ret
= tracepoint_location
->provider_name
;
785 int lttng_userspace_probe_location_function_get_binary_fd(
786 const struct lttng_userspace_probe_location
*location
)
789 struct lttng_userspace_probe_location_function
*function_location
;
791 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
792 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
793 ERR("Invalid argument(s)");
797 function_location
= container_of(location
,
798 struct lttng_userspace_probe_location_function
, parent
);
799 ret
= function_location
->binary_fd_handle
?
800 fd_handle_get_fd(function_location
->binary_fd_handle
) : -1;
805 enum lttng_userspace_probe_location_function_instrumentation_type
806 lttng_userspace_probe_location_function_get_instrumentation_type(
807 const struct lttng_userspace_probe_location
*location
)
809 enum lttng_userspace_probe_location_function_instrumentation_type type
;
810 struct lttng_userspace_probe_location_function
*function_location
;
812 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
813 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
814 ERR("Invalid argument(s)");
815 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
819 function_location
= container_of(location
,
820 struct lttng_userspace_probe_location_function
, parent
);
821 type
= function_location
->instrumentation_type
;
826 enum lttng_userspace_probe_location_status
827 lttng_userspace_probe_location_function_set_instrumentation_type(
828 const struct lttng_userspace_probe_location
*location
,
829 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
831 enum lttng_userspace_probe_location_status status
=
832 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
833 struct lttng_userspace_probe_location_function
*function_location
;
835 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
836 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
837 instrumentation_type
!=
838 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
839 ERR("Invalid argument(s)");
840 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
844 function_location
= container_of(location
,
845 struct lttng_userspace_probe_location_function
, parent
);
846 function_location
->instrumentation_type
= instrumentation_type
;
851 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
852 const struct lttng_userspace_probe_location
*location
)
855 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
857 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
858 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
859 ERR("Invalid argument(s)");
863 tracepoint_location
= container_of(location
,
864 struct lttng_userspace_probe_location_tracepoint
, parent
);
865 ret
= tracepoint_location
->binary_fd_handle
?
866 fd_handle_get_fd(tracepoint_location
->binary_fd_handle
) : -1;
871 static struct lttng_userspace_probe_location_lookup_method
*
872 lttng_userspace_probe_location_function_get_lookup_method(
873 const struct lttng_userspace_probe_location
*location
)
875 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
877 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
878 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
879 ERR("Invalid argument(s)");
883 ret
= location
->lookup_method
;
888 static struct lttng_userspace_probe_location_lookup_method
*
889 lttng_userspace_probe_location_tracepoint_get_lookup_method(
890 const struct lttng_userspace_probe_location
*location
)
892 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
894 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
895 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
896 ERR("Invalid argument(s)");
900 ret
= location
->lookup_method
;
905 const struct lttng_userspace_probe_location_lookup_method
*
906 lttng_userspace_probe_location_get_lookup_method(
907 const struct lttng_userspace_probe_location
*location
)
909 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
912 switch (location
->type
) {
913 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
914 ret
= lttng_userspace_probe_location_function_get_lookup_method(
917 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
918 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
922 ERR("Unknowned lookup method.");
929 int lttng_userspace_probe_location_lookup_method_serialize(
930 struct lttng_userspace_probe_location_lookup_method
*method
,
931 struct lttng_payload
*payload
)
934 struct lttng_userspace_probe_location_lookup_method_comm
937 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
938 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
940 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &lookup_method_comm
,
941 sizeof(lookup_method_comm
));
946 ret
= sizeof(lookup_method_comm
);
952 int lttng_userspace_probe_location_function_serialize(
953 const struct lttng_userspace_probe_location
*location
,
954 struct lttng_payload
*payload
)
957 size_t function_name_len
, binary_path_len
;
958 struct lttng_userspace_probe_location_function
*location_function
;
959 struct lttng_userspace_probe_location_function_comm location_function_comm
;
962 assert(lttng_userspace_probe_location_get_type(location
) ==
963 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
965 location_function
= container_of(location
,
966 struct lttng_userspace_probe_location_function
,
968 if (!location_function
->function_name
|| !location_function
->binary_path
) {
969 ret
= -LTTNG_ERR_INVALID
;
973 if (payload
&& !location_function
->binary_fd_handle
) {
974 ret
= -LTTNG_ERR_INVALID
;
978 function_name_len
= strlen(location_function
->function_name
);
979 if (function_name_len
== 0) {
980 ret
= -LTTNG_ERR_INVALID
;
983 binary_path_len
= strlen(location_function
->binary_path
);
984 if (binary_path_len
== 0) {
985 ret
= -LTTNG_ERR_INVALID
;
989 location_function_comm
.function_name_len
= function_name_len
+ 1;
990 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
993 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
994 &location_function_comm
,
995 sizeof(location_function_comm
));
997 ret
= -LTTNG_ERR_INVALID
;
1000 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1001 location_function
->function_name
,
1002 location_function_comm
.function_name_len
);
1004 ret
= -LTTNG_ERR_INVALID
;
1007 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1008 location_function
->binary_path
,
1009 location_function_comm
.binary_path_len
);
1011 ret
= -LTTNG_ERR_INVALID
;
1014 ret
= lttng_payload_push_fd_handle(
1015 payload
, location_function
->binary_fd_handle
);
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_payload
*payload
)
1034 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1035 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1036 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1039 assert(lttng_userspace_probe_location_get_type(location
) ==
1040 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1042 location_tracepoint
= container_of(location
,
1043 struct lttng_userspace_probe_location_tracepoint
,
1045 if (!location_tracepoint
->probe_name
||
1046 !location_tracepoint
->provider_name
||
1047 !location_tracepoint
->binary_path
) {
1048 ret
= -LTTNG_ERR_INVALID
;
1052 if (payload
&& !location_tracepoint
->binary_fd_handle
) {
1053 ret
= -LTTNG_ERR_INVALID
;
1057 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1058 if (probe_name_len
== 0) {
1059 ret
= -LTTNG_ERR_INVALID
;
1063 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1064 if (provider_name_len
== 0) {
1065 ret
= -LTTNG_ERR_INVALID
;
1069 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1070 if (binary_path_len
== 0) {
1071 ret
= -LTTNG_ERR_INVALID
;
1075 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1076 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1077 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1080 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1081 &location_tracepoint_comm
,
1082 sizeof(location_tracepoint_comm
));
1084 ret
= -LTTNG_ERR_INVALID
;
1087 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1088 location_tracepoint
->probe_name
,
1089 location_tracepoint_comm
.probe_name_len
);
1091 ret
= -LTTNG_ERR_INVALID
;
1094 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1095 location_tracepoint
->provider_name
,
1096 location_tracepoint_comm
.provider_name_len
);
1098 ret
= -LTTNG_ERR_INVALID
;
1101 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1102 location_tracepoint
->binary_path
,
1103 location_tracepoint_comm
.binary_path_len
);
1105 ret
= -LTTNG_ERR_INVALID
;
1108 ret
= lttng_payload_push_fd_handle(
1109 payload
, location_tracepoint
->binary_fd_handle
);
1111 ret
= -LTTNG_ERR_INVALID
;
1116 ret
= sizeof(location_tracepoint_comm
) +
1117 location_tracepoint_comm
.probe_name_len
+
1118 location_tracepoint_comm
.provider_name_len
+
1119 location_tracepoint_comm
.binary_path_len
;
1125 int lttng_userspace_probe_location_serialize(
1126 const struct lttng_userspace_probe_location
*location
,
1127 struct lttng_payload
*payload
)
1129 int ret
, buffer_use
= 0;
1130 struct lttng_userspace_probe_location_comm location_generic_comm
;
1133 ERR("Invalid argument(s)");
1134 ret
= -LTTNG_ERR_INVALID
;
1138 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1140 location_generic_comm
.type
= (int8_t) location
->type
;
1142 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1143 &location_generic_comm
,
1144 sizeof(location_generic_comm
));
1149 buffer_use
+= sizeof(location_generic_comm
);
1151 switch (lttng_userspace_probe_location_get_type(location
)) {
1152 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1153 ret
= lttng_userspace_probe_location_function_serialize(
1156 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1157 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1161 ERR("Unsupported probe location type");
1162 ret
= -LTTNG_ERR_INVALID
;
1170 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1171 location
->lookup_method
, payload
);
1181 int lttng_userspace_probe_location_function_create_from_payload(
1182 struct lttng_payload_view
*view
,
1183 struct lttng_userspace_probe_location
**location
)
1185 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1186 const char *function_name_src
, *binary_path_src
;
1187 char *function_name
= NULL
, *binary_path
= NULL
;
1189 size_t expected_size
;
1190 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1194 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1195 ret
= -LTTNG_ERR_INVALID
;
1199 location_function_comm
=
1200 (typeof(location_function_comm
)) view
->buffer
.data
;
1202 expected_size
= sizeof(*location_function_comm
) +
1203 location_function_comm
->function_name_len
+
1204 location_function_comm
->binary_path_len
;
1206 if (view
->buffer
.size
< expected_size
) {
1207 ret
= -LTTNG_ERR_INVALID
;
1211 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1212 binary_path_src
= function_name_src
+
1213 location_function_comm
->function_name_len
;
1215 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1216 ret
= -LTTNG_ERR_INVALID
;
1219 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1220 ret
= -LTTNG_ERR_INVALID
;
1224 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1225 if (!function_name
) {
1226 PERROR("lttng_strndup");
1227 ret
= -LTTNG_ERR_NOMEM
;
1231 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1233 PERROR("lttng_strndup");
1234 ret
= -LTTNG_ERR_NOMEM
;
1238 *location
= lttng_userspace_probe_location_function_create_no_check(
1239 binary_path
, function_name
, NULL
, false);
1241 ret
= -LTTNG_ERR_INVALID
;
1245 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(
1246 *location
, binary_fd_handle
);
1248 ret
= -LTTNG_ERR_INVALID
;
1252 ret
= (int) expected_size
;
1254 fd_handle_put(binary_fd_handle
);
1255 free(function_name
);
1261 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1262 struct lttng_payload_view
*view
,
1263 struct lttng_userspace_probe_location
**location
)
1265 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1266 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1267 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1269 size_t expected_size
;
1270 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1274 if (!binary_fd_handle
) {
1275 ret
= -LTTNG_ERR_INVALID
;
1279 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1280 ret
= -LTTNG_ERR_INVALID
;
1284 location_tracepoint_comm
=
1285 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1287 expected_size
= sizeof(*location_tracepoint_comm
) +
1288 location_tracepoint_comm
->probe_name_len
+
1289 location_tracepoint_comm
->provider_name_len
+
1290 location_tracepoint_comm
->binary_path_len
;
1292 if (view
->buffer
.size
< expected_size
) {
1293 ret
= -LTTNG_ERR_INVALID
;
1297 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1298 provider_name_src
= probe_name_src
+
1299 location_tracepoint_comm
->probe_name_len
;
1300 binary_path_src
= provider_name_src
+
1301 location_tracepoint_comm
->provider_name_len
;
1303 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1304 ret
= -LTTNG_ERR_INVALID
;
1308 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1309 ret
= -LTTNG_ERR_INVALID
;
1313 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1314 ret
= -LTTNG_ERR_INVALID
;
1318 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1320 PERROR("lttng_strndup");
1323 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1324 if (!provider_name
) {
1325 PERROR("lttng_strndup");
1329 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1331 PERROR("lttng_strndup");
1335 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1336 binary_path
, provider_name
, probe_name
, NULL
, false);
1338 ret
= -LTTNG_ERR_INVALID
;
1342 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1343 *location
, binary_fd_handle
);
1345 ret
= -LTTNG_ERR_INVALID
;
1349 ret
= (int) expected_size
;
1351 fd_handle_put(binary_fd_handle
);
1353 free(provider_name
);
1359 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1360 struct lttng_payload_view
*view
,
1361 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1364 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1365 enum lttng_userspace_probe_location_lookup_method_type type
;
1368 assert(lookup_method
);
1370 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1371 ret
= -LTTNG_ERR_INVALID
;
1375 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1376 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1379 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1380 *lookup_method
= NULL
;
1382 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1384 lttng_userspace_probe_location_lookup_method_function_elf_create();
1385 if (!(*lookup_method
)) {
1386 ret
= -LTTNG_ERR_INVALID
;
1390 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1392 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1393 if (!(*lookup_method
)) {
1394 ret
= -LTTNG_ERR_INVALID
;
1399 ret
= -LTTNG_ERR_INVALID
;
1403 ret
= sizeof(*lookup_comm
);
1409 int lttng_userspace_probe_location_create_from_payload(
1410 struct lttng_payload_view
*view
,
1411 struct lttng_userspace_probe_location
**location
)
1413 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1414 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1415 enum lttng_userspace_probe_location_type type
;
1422 lookup_method
= NULL
;
1424 if (view
->buffer
.size
<= sizeof(*probe_location_comm
)) {
1425 ret
= -LTTNG_ERR_INVALID
;
1429 probe_location_comm
= (typeof(probe_location_comm
)) view
->buffer
.data
;
1430 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1431 consumed
+= sizeof(*probe_location_comm
);
1434 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1436 struct lttng_payload_view location_view
=
1437 lttng_payload_view_from_view(
1438 view
, consumed
, -1);
1440 ret
= lttng_userspace_probe_location_function_create_from_payload(
1441 &location_view
, location
);
1447 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1449 struct lttng_payload_view location_view
=
1450 lttng_payload_view_from_view(view
, consumed
, -1);
1452 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1453 &location_view
, location
);
1460 ret
= -LTTNG_ERR_INVALID
;
1465 if (view
->buffer
.size
<= consumed
) {
1466 ret
= -LTTNG_ERR_INVALID
;
1471 struct lttng_payload_view lookup_method_view
=
1472 lttng_payload_view_from_view(
1473 view
, consumed
, -1);
1475 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1476 &lookup_method_view
, &lookup_method
);
1479 ret
= -LTTNG_ERR_INVALID
;
1483 assert(lookup_method
);
1484 (*location
)->lookup_method
= lookup_method
;
1485 lookup_method
= NULL
;
1492 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1493 struct lttng_userspace_probe_location
*location
,
1494 struct fd_handle
*binary_fd
)
1497 struct lttng_userspace_probe_location_function
*function_location
;
1500 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1502 function_location
= container_of(location
,
1503 struct lttng_userspace_probe_location_function
, parent
);
1504 fd_handle_put(function_location
->binary_fd_handle
);
1505 fd_handle_get(binary_fd
);
1506 function_location
->binary_fd_handle
= binary_fd
;
1511 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1512 struct lttng_userspace_probe_location
*location
,
1513 struct fd_handle
*binary_fd
)
1516 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1519 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1521 tracepoint_location
= container_of(location
,
1522 struct lttng_userspace_probe_location_tracepoint
, parent
);
1523 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1524 fd_handle_get(binary_fd
);
1525 tracepoint_location
->binary_fd_handle
= binary_fd
;
1530 int lttng_userspace_probe_location_function_flatten(
1531 const struct lttng_userspace_probe_location
*location
,
1532 struct lttng_dynamic_buffer
*buffer
)
1534 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1535 struct lttng_userspace_probe_location_function
*probe_function
;
1536 struct lttng_userspace_probe_location_function flat_probe
;
1537 size_t function_name_len
, binary_path_len
;
1538 size_t padding_needed
= 0;
1539 char *flat_probe_start
;
1540 int storage_needed
= 0;
1545 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1546 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1547 ret
= -LTTNG_ERR_INVALID
;
1551 probe_function
= container_of(location
,
1552 struct lttng_userspace_probe_location_function
,
1554 assert(probe_function
->function_name
);
1555 assert(probe_function
->binary_path
);
1558 sizeof(struct lttng_userspace_probe_location_function
);
1559 function_name_len
= strlen(probe_function
->function_name
) + 1;
1560 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1561 storage_needed
+= function_name_len
+ binary_path_len
;
1564 * The lookup method is aligned to 64-bit within the buffer.
1565 * This is needed even if there is no lookup method since
1566 * the next structure in the buffer probably needs to be
1567 * aligned too (depending on the arch).
1569 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1570 storage_needed
+= padding_needed
;
1572 if (location
->lookup_method
) {
1573 /* NOTE: elf look-up method is assumed here. */
1574 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1578 ret
= storage_needed
;
1582 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1583 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1584 buffer
->size
+ storage_needed
);
1590 memset(&flat_probe
, 0, sizeof(flat_probe
));
1592 flat_probe_start
= buffer
->data
+ buffer
->size
;
1593 flat_probe
.parent
.type
= location
->type
;
1595 * The lookup method, if present, is the last element in the flat
1596 * representation of the probe.
1598 if (location
->lookup_method
) {
1599 flat_probe
.parent
.lookup_method
=
1600 (struct lttng_userspace_probe_location_lookup_method
*)
1601 (flat_probe_start
+ sizeof(flat_probe
) +
1602 function_name_len
+ binary_path_len
+ padding_needed
);
1604 flat_probe
.parent
.lookup_method
= NULL
;
1607 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1608 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1609 flat_probe
.binary_fd_handle
= NULL
;
1610 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1611 sizeof(flat_probe
));
1616 ret
= lttng_dynamic_buffer_append(buffer
,
1617 probe_function
->function_name
, function_name_len
);
1621 ret
= lttng_dynamic_buffer_append(buffer
,
1622 probe_function
->binary_path
, binary_path_len
);
1627 /* Insert padding before the lookup method. */
1628 ret
= lttng_dynamic_buffer_set_size(buffer
,
1629 buffer
->size
+ padding_needed
);
1634 if (!location
->lookup_method
) {
1635 /* Not an error, the default method is used. */
1636 ret
= storage_needed
;
1640 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1641 flat_lookup_method
.parent
.type
=
1642 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1643 ret
= lttng_dynamic_buffer_append(buffer
,
1644 &flat_lookup_method
, sizeof(flat_lookup_method
));
1648 ret
= storage_needed
;
1654 int lttng_userspace_probe_location_tracepoint_flatten(
1655 const struct lttng_userspace_probe_location
*location
,
1656 struct lttng_dynamic_buffer
*buffer
)
1658 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1659 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1660 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1661 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1662 size_t padding_needed
= 0;
1663 int storage_needed
= 0;
1664 char *flat_probe_start
;
1669 /* Only SDT tracepoints are supported at the moment */
1670 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1671 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1672 ret
= -LTTNG_ERR_INVALID
;
1675 probe_tracepoint
= container_of(location
,
1676 struct lttng_userspace_probe_location_tracepoint
,
1678 assert(probe_tracepoint
->probe_name
);
1679 assert(probe_tracepoint
->provider_name
);
1680 assert(probe_tracepoint
->binary_path
);
1682 /* Compute the storage space needed to flatten the probe location */
1683 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1685 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1686 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1687 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1689 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1692 * The lookup method is aligned to 64-bit within the buffer.
1693 * This is needed even if there is no lookup method since
1694 * the next structure in the buffer probably needs to be
1695 * aligned too (depending on the arch).
1697 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1698 storage_needed
+= padding_needed
;
1700 if (location
->lookup_method
) {
1701 /* NOTE: elf look-up method is assumed here. */
1703 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1707 * If the caller set buffer to NULL, return the size of the needed buffer.
1710 ret
= storage_needed
;
1714 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1715 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1716 buffer
->size
+ storage_needed
);
1722 memset(&flat_probe
, 0, sizeof(flat_probe
));
1724 flat_probe_start
= buffer
->data
+ buffer
->size
;
1725 flat_probe
.parent
.type
= location
->type
;
1728 * The lookup method, if present, is the last element in the flat
1729 * representation of the probe.
1731 if (location
->lookup_method
) {
1732 flat_probe
.parent
.lookup_method
=
1733 (struct lttng_userspace_probe_location_lookup_method
*)
1734 (flat_probe_start
+ sizeof(flat_probe
) +
1735 probe_name_len
+ provider_name_len
+
1736 binary_path_len
+ padding_needed
);
1738 flat_probe
.parent
.lookup_method
= NULL
;
1741 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1742 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1743 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1744 flat_probe
.binary_fd_handle
= NULL
;
1745 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1750 /* Append all the fields to the buffer */
1751 ret
= lttng_dynamic_buffer_append(buffer
,
1752 probe_tracepoint
->probe_name
, probe_name_len
);
1756 ret
= lttng_dynamic_buffer_append(buffer
,
1757 probe_tracepoint
->provider_name
, provider_name_len
);
1761 ret
= lttng_dynamic_buffer_append(buffer
,
1762 probe_tracepoint
->binary_path
, binary_path_len
);
1767 /* Insert padding before the lookup method. */
1768 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1773 if (!location
->lookup_method
) {
1774 /* Not an error, the default method is used. */
1775 ret
= storage_needed
;
1779 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1781 flat_lookup_method
.parent
.type
=
1782 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1783 ret
= lttng_dynamic_buffer_append(buffer
,
1784 &flat_lookup_method
, sizeof(flat_lookup_method
));
1788 ret
= storage_needed
;
1794 int lttng_userspace_probe_location_flatten(
1795 const struct lttng_userspace_probe_location
*location
,
1796 struct lttng_dynamic_buffer
*buffer
)
1800 ret
= -LTTNG_ERR_INVALID
;
1804 /* Only types currently supported. */
1805 switch (location
->type
) {
1806 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1807 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1809 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1810 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1813 ret
= -LTTNG_ERR_INVALID
;
1822 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1823 const struct lttng_userspace_probe_location
*location
)
1825 struct lttng_userspace_probe_location
*new_location
= NULL
;
1826 enum lttng_userspace_probe_location_type type
;
1832 type
= lttng_userspace_probe_location_get_type(location
);
1834 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1836 lttng_userspace_probe_location_function_copy(location
);
1837 if (!new_location
) {
1841 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1843 lttng_userspace_probe_location_tracepoint_copy(location
);
1844 if (!new_location
) {
1849 new_location
= NULL
;
1853 return new_location
;
1857 bool lttng_userspace_probe_location_lookup_method_is_equal(
1858 const struct lttng_userspace_probe_location_lookup_method
*a
,
1859 const struct lttng_userspace_probe_location_lookup_method
*b
)
1861 bool is_equal
= false;
1872 if (a
->type
!= b
->type
) {
1882 bool lttng_userspace_probe_location_is_equal(
1883 const struct lttng_userspace_probe_location
*a
,
1884 const struct lttng_userspace_probe_location
*b
)
1886 bool is_equal
= false;
1897 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1898 a
->lookup_method
, b
->lookup_method
)) {
1902 if (a
->type
!= b
->type
) {
1906 is_equal
= a
->equal
? a
->equal(a
, b
) : true;