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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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) passed to '%s'", __FUNCTION__
);
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 (!lttng_buffer_view_contains_string(&view
->buffer
, function_name_src
,
1216 location_function_comm
->function_name_len
)) {
1217 ret
= -LTTNG_ERR_INVALID
;
1221 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1222 location_function_comm
->binary_path_len
)) {
1223 ret
= -LTTNG_ERR_INVALID
;
1227 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1228 if (!function_name
) {
1229 PERROR("lttng_strndup");
1230 ret
= -LTTNG_ERR_NOMEM
;
1234 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1236 PERROR("lttng_strndup");
1237 ret
= -LTTNG_ERR_NOMEM
;
1241 *location
= lttng_userspace_probe_location_function_create_no_check(
1242 binary_path
, function_name
, NULL
, false);
1244 ret
= -LTTNG_ERR_INVALID
;
1248 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(
1249 *location
, binary_fd_handle
);
1251 ret
= -LTTNG_ERR_INVALID
;
1255 ret
= (int) expected_size
;
1257 fd_handle_put(binary_fd_handle
);
1258 free(function_name
);
1264 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1265 struct lttng_payload_view
*view
,
1266 struct lttng_userspace_probe_location
**location
)
1268 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1269 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1270 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1272 size_t expected_size
;
1273 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1277 if (!binary_fd_handle
) {
1278 ret
= -LTTNG_ERR_INVALID
;
1282 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1283 ret
= -LTTNG_ERR_INVALID
;
1287 location_tracepoint_comm
=
1288 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1290 expected_size
= sizeof(*location_tracepoint_comm
) +
1291 location_tracepoint_comm
->probe_name_len
+
1292 location_tracepoint_comm
->provider_name_len
+
1293 location_tracepoint_comm
->binary_path_len
;
1295 if (view
->buffer
.size
< expected_size
) {
1296 ret
= -LTTNG_ERR_INVALID
;
1300 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1301 provider_name_src
= probe_name_src
+
1302 location_tracepoint_comm
->probe_name_len
;
1303 binary_path_src
= provider_name_src
+
1304 location_tracepoint_comm
->provider_name_len
;
1306 if (!lttng_buffer_view_contains_string(&view
->buffer
, probe_name_src
,
1307 location_tracepoint_comm
->probe_name_len
)) {
1308 ret
= -LTTNG_ERR_INVALID
;
1312 if (!lttng_buffer_view_contains_string(&view
->buffer
, provider_name_src
,
1313 location_tracepoint_comm
->provider_name_len
)) {
1314 ret
= -LTTNG_ERR_INVALID
;
1318 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1319 location_tracepoint_comm
->binary_path_len
)) {
1320 ret
= -LTTNG_ERR_INVALID
;
1324 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1326 PERROR("lttng_strndup");
1329 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1330 if (!provider_name
) {
1331 PERROR("lttng_strndup");
1335 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1337 PERROR("lttng_strndup");
1341 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1342 binary_path
, provider_name
, probe_name
, NULL
, false);
1344 ret
= -LTTNG_ERR_INVALID
;
1348 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1349 *location
, binary_fd_handle
);
1351 ret
= -LTTNG_ERR_INVALID
;
1355 ret
= (int) expected_size
;
1357 fd_handle_put(binary_fd_handle
);
1359 free(provider_name
);
1365 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1366 struct lttng_payload_view
*view
,
1367 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1370 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1371 enum lttng_userspace_probe_location_lookup_method_type type
;
1374 assert(lookup_method
);
1376 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1377 ret
= -LTTNG_ERR_INVALID
;
1381 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1382 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1385 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1386 *lookup_method
= NULL
;
1388 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1390 lttng_userspace_probe_location_lookup_method_function_elf_create();
1391 if (!(*lookup_method
)) {
1392 ret
= -LTTNG_ERR_INVALID
;
1396 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1398 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1399 if (!(*lookup_method
)) {
1400 ret
= -LTTNG_ERR_INVALID
;
1405 ret
= -LTTNG_ERR_INVALID
;
1409 ret
= sizeof(*lookup_comm
);
1415 int lttng_userspace_probe_location_create_from_payload(
1416 struct lttng_payload_view
*view
,
1417 struct lttng_userspace_probe_location
**location
)
1419 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1420 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1421 enum lttng_userspace_probe_location_type type
;
1428 lookup_method
= NULL
;
1430 if (view
->buffer
.size
<= sizeof(*probe_location_comm
)) {
1431 ret
= -LTTNG_ERR_INVALID
;
1435 probe_location_comm
= (typeof(probe_location_comm
)) view
->buffer
.data
;
1436 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1437 consumed
+= sizeof(*probe_location_comm
);
1440 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1442 struct lttng_payload_view location_view
=
1443 lttng_payload_view_from_view(
1444 view
, consumed
, -1);
1446 ret
= lttng_userspace_probe_location_function_create_from_payload(
1447 &location_view
, location
);
1453 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1455 struct lttng_payload_view location_view
=
1456 lttng_payload_view_from_view(view
, consumed
, -1);
1458 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1459 &location_view
, location
);
1466 ret
= -LTTNG_ERR_INVALID
;
1471 if (view
->buffer
.size
<= consumed
) {
1472 ret
= -LTTNG_ERR_INVALID
;
1477 struct lttng_payload_view lookup_method_view
=
1478 lttng_payload_view_from_view(
1479 view
, consumed
, -1);
1481 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1482 &lookup_method_view
, &lookup_method
);
1485 ret
= -LTTNG_ERR_INVALID
;
1489 assert(lookup_method
);
1490 (*location
)->lookup_method
= lookup_method
;
1491 lookup_method
= NULL
;
1498 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1499 struct lttng_userspace_probe_location
*location
,
1500 struct fd_handle
*binary_fd
)
1503 struct lttng_userspace_probe_location_function
*function_location
;
1506 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1508 function_location
= container_of(location
,
1509 struct lttng_userspace_probe_location_function
, parent
);
1510 fd_handle_put(function_location
->binary_fd_handle
);
1511 fd_handle_get(binary_fd
);
1512 function_location
->binary_fd_handle
= binary_fd
;
1517 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1518 struct lttng_userspace_probe_location
*location
,
1519 struct fd_handle
*binary_fd
)
1522 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1525 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1527 tracepoint_location
= container_of(location
,
1528 struct lttng_userspace_probe_location_tracepoint
, parent
);
1529 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1530 fd_handle_get(binary_fd
);
1531 tracepoint_location
->binary_fd_handle
= binary_fd
;
1536 int lttng_userspace_probe_location_function_flatten(
1537 const struct lttng_userspace_probe_location
*location
,
1538 struct lttng_dynamic_buffer
*buffer
)
1540 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1541 struct lttng_userspace_probe_location_function
*probe_function
;
1542 struct lttng_userspace_probe_location_function flat_probe
;
1543 size_t function_name_len
, binary_path_len
;
1544 size_t padding_needed
= 0;
1545 char *flat_probe_start
;
1546 int storage_needed
= 0;
1551 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1552 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1553 ret
= -LTTNG_ERR_INVALID
;
1557 probe_function
= container_of(location
,
1558 struct lttng_userspace_probe_location_function
,
1560 assert(probe_function
->function_name
);
1561 assert(probe_function
->binary_path
);
1564 sizeof(struct lttng_userspace_probe_location_function
);
1565 function_name_len
= strlen(probe_function
->function_name
) + 1;
1566 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1567 storage_needed
+= function_name_len
+ binary_path_len
;
1570 * The lookup method is aligned to 64-bit within the buffer.
1571 * This is needed even if there is no lookup method since
1572 * the next structure in the buffer probably needs to be
1573 * aligned too (depending on the arch).
1575 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1576 storage_needed
+= padding_needed
;
1578 if (location
->lookup_method
) {
1579 /* NOTE: elf look-up method is assumed here. */
1580 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1584 ret
= storage_needed
;
1588 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1589 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1590 buffer
->size
+ storage_needed
);
1596 memset(&flat_probe
, 0, sizeof(flat_probe
));
1598 flat_probe_start
= buffer
->data
+ buffer
->size
;
1599 flat_probe
.parent
.type
= location
->type
;
1601 * The lookup method, if present, is the last element in the flat
1602 * representation of the probe.
1604 if (location
->lookup_method
) {
1605 flat_probe
.parent
.lookup_method
=
1606 (struct lttng_userspace_probe_location_lookup_method
*)
1607 (flat_probe_start
+ sizeof(flat_probe
) +
1608 function_name_len
+ binary_path_len
+ padding_needed
);
1610 flat_probe
.parent
.lookup_method
= NULL
;
1613 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1614 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1615 flat_probe
.binary_fd_handle
= NULL
;
1616 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1617 sizeof(flat_probe
));
1622 ret
= lttng_dynamic_buffer_append(buffer
,
1623 probe_function
->function_name
, function_name_len
);
1627 ret
= lttng_dynamic_buffer_append(buffer
,
1628 probe_function
->binary_path
, binary_path_len
);
1633 /* Insert padding before the lookup method. */
1634 ret
= lttng_dynamic_buffer_set_size(buffer
,
1635 buffer
->size
+ padding_needed
);
1640 if (!location
->lookup_method
) {
1641 /* Not an error, the default method is used. */
1642 ret
= storage_needed
;
1646 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1647 flat_lookup_method
.parent
.type
=
1648 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1649 ret
= lttng_dynamic_buffer_append(buffer
,
1650 &flat_lookup_method
, sizeof(flat_lookup_method
));
1654 ret
= storage_needed
;
1660 int lttng_userspace_probe_location_tracepoint_flatten(
1661 const struct lttng_userspace_probe_location
*location
,
1662 struct lttng_dynamic_buffer
*buffer
)
1664 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1665 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1666 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1667 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1668 size_t padding_needed
= 0;
1669 int storage_needed
= 0;
1670 char *flat_probe_start
;
1675 /* Only SDT tracepoints are supported at the moment */
1676 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1677 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1678 ret
= -LTTNG_ERR_INVALID
;
1681 probe_tracepoint
= container_of(location
,
1682 struct lttng_userspace_probe_location_tracepoint
,
1684 assert(probe_tracepoint
->probe_name
);
1685 assert(probe_tracepoint
->provider_name
);
1686 assert(probe_tracepoint
->binary_path
);
1688 /* Compute the storage space needed to flatten the probe location */
1689 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1691 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1692 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1693 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1695 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1698 * The lookup method is aligned to 64-bit within the buffer.
1699 * This is needed even if there is no lookup method since
1700 * the next structure in the buffer probably needs to be
1701 * aligned too (depending on the arch).
1703 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1704 storage_needed
+= padding_needed
;
1706 if (location
->lookup_method
) {
1707 /* NOTE: elf look-up method is assumed here. */
1709 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1713 * If the caller set buffer to NULL, return the size of the needed buffer.
1716 ret
= storage_needed
;
1720 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1721 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1722 buffer
->size
+ storage_needed
);
1728 memset(&flat_probe
, 0, sizeof(flat_probe
));
1730 flat_probe_start
= buffer
->data
+ buffer
->size
;
1731 flat_probe
.parent
.type
= location
->type
;
1734 * The lookup method, if present, is the last element in the flat
1735 * representation of the probe.
1737 if (location
->lookup_method
) {
1738 flat_probe
.parent
.lookup_method
=
1739 (struct lttng_userspace_probe_location_lookup_method
*)
1740 (flat_probe_start
+ sizeof(flat_probe
) +
1741 probe_name_len
+ provider_name_len
+
1742 binary_path_len
+ padding_needed
);
1744 flat_probe
.parent
.lookup_method
= NULL
;
1747 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1748 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1749 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1750 flat_probe
.binary_fd_handle
= NULL
;
1751 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1756 /* Append all the fields to the buffer */
1757 ret
= lttng_dynamic_buffer_append(buffer
,
1758 probe_tracepoint
->probe_name
, probe_name_len
);
1762 ret
= lttng_dynamic_buffer_append(buffer
,
1763 probe_tracepoint
->provider_name
, provider_name_len
);
1767 ret
= lttng_dynamic_buffer_append(buffer
,
1768 probe_tracepoint
->binary_path
, binary_path_len
);
1773 /* Insert padding before the lookup method. */
1774 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1779 if (!location
->lookup_method
) {
1780 /* Not an error, the default method is used. */
1781 ret
= storage_needed
;
1785 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1787 flat_lookup_method
.parent
.type
=
1788 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1789 ret
= lttng_dynamic_buffer_append(buffer
,
1790 &flat_lookup_method
, sizeof(flat_lookup_method
));
1794 ret
= storage_needed
;
1800 int lttng_userspace_probe_location_flatten(
1801 const struct lttng_userspace_probe_location
*location
,
1802 struct lttng_dynamic_buffer
*buffer
)
1806 ret
= -LTTNG_ERR_INVALID
;
1810 /* Only types currently supported. */
1811 switch (location
->type
) {
1812 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1813 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1815 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1816 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1819 ret
= -LTTNG_ERR_INVALID
;
1828 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1829 const struct lttng_userspace_probe_location
*location
)
1831 struct lttng_userspace_probe_location
*new_location
= NULL
;
1832 enum lttng_userspace_probe_location_type type
;
1838 type
= lttng_userspace_probe_location_get_type(location
);
1840 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1842 lttng_userspace_probe_location_function_copy(location
);
1843 if (!new_location
) {
1847 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1849 lttng_userspace_probe_location_tracepoint_copy(location
);
1850 if (!new_location
) {
1855 new_location
= NULL
;
1859 return new_location
;
1863 bool lttng_userspace_probe_location_lookup_method_is_equal(
1864 const struct lttng_userspace_probe_location_lookup_method
*a
,
1865 const struct lttng_userspace_probe_location_lookup_method
*b
)
1867 bool is_equal
= false;
1878 if (a
->type
!= b
->type
) {
1888 bool lttng_userspace_probe_location_is_equal(
1889 const struct lttng_userspace_probe_location
*a
,
1890 const struct lttng_userspace_probe_location
*b
)
1892 bool is_equal
= false;
1903 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1904 a
->lookup_method
, b
->lookup_method
)) {
1908 if (a
->type
!= b
->type
) {
1912 is_equal
= a
->equal
? a
->equal(a
, b
) : true;