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"
9 #include <common/compat/string.h>
10 #include <common/error.h>
11 #include <common/hashtable/hashtable.h>
12 #include <common/hashtable/utils.h>
13 #include <common/macros.h>
14 #include <common/mi-lttng.h>
15 #include <common/payload-view.h>
16 #include <common/payload.h>
18 #include <lttng/constant.h>
19 #include <lttng/userspace-probe-internal.h>
21 #include <sys/types.h>
22 #include <sys/unistd.h>
25 int lttng_userspace_probe_location_function_set_binary_fd_handle(
26 struct lttng_userspace_probe_location
*location
,
27 struct fd_handle
*binary_fd_handle
);
30 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
31 struct lttng_userspace_probe_location
*location
,
32 struct fd_handle
*binary_fd_handle
);
35 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
36 const struct lttng_userspace_probe_location_lookup_method
38 struct mi_writer
*writer
);
41 enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
42 const struct lttng_userspace_probe_location
*location
,
43 struct mi_writer
*writer
);
46 enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
47 const struct lttng_userspace_probe_location
*location
,
48 struct mi_writer
*writer
);
50 enum lttng_userspace_probe_location_lookup_method_type
51 lttng_userspace_probe_location_lookup_method_get_type(
52 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
54 return lookup_method
? lookup_method
->type
:
55 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
58 void lttng_userspace_probe_location_lookup_method_destroy(
59 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
68 struct lttng_userspace_probe_location_lookup_method
*
69 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
71 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
72 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
74 elf_method
= zmalloc(sizeof(*elf_method
));
80 ret
= &elf_method
->parent
;
81 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
86 struct lttng_userspace_probe_location_lookup_method
*
87 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
89 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
90 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
92 sdt_method
= zmalloc(sizeof(*sdt_method
));
98 ret
= &sdt_method
->parent
;
99 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
104 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
105 const struct lttng_userspace_probe_location
*location
)
107 return location
? location
->type
:
108 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
112 void lttng_userspace_probe_location_function_destroy(
113 struct lttng_userspace_probe_location
*location
)
115 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
117 LTTNG_ASSERT(location
);
119 location_function
= container_of(location
,
120 struct lttng_userspace_probe_location_function
, parent
);
122 LTTNG_ASSERT(location_function
);
124 free(location_function
->function_name
);
125 free(location_function
->binary_path
);
126 fd_handle_put(location_function
->binary_fd_handle
);
131 void lttng_userspace_probe_location_tracepoint_destroy(
132 struct lttng_userspace_probe_location
*location
)
134 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
136 LTTNG_ASSERT(location
);
138 location_tracepoint
= container_of(location
,
139 struct lttng_userspace_probe_location_tracepoint
,
142 LTTNG_ASSERT(location_tracepoint
);
144 free(location_tracepoint
->probe_name
);
145 free(location_tracepoint
->provider_name
);
146 free(location_tracepoint
->binary_path
);
147 fd_handle_put(location_tracepoint
->binary_fd_handle
);
151 void lttng_userspace_probe_location_destroy(
152 struct lttng_userspace_probe_location
*location
)
158 lttng_userspace_probe_location_lookup_method_destroy(
159 location
->lookup_method
);
161 switch (location
->type
) {
162 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
163 lttng_userspace_probe_location_function_destroy(location
);
165 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
166 lttng_userspace_probe_location_tracepoint_destroy(location
);
173 /* Compare two file descriptors based on their inode and device numbers. */
174 static bool fd_is_equal(int a
, int b
)
177 bool is_equal
= false;
178 struct stat a_stat
, b_stat
;
180 if (a
< 0 && b
>= 0) {
184 if (b
< 0 && a
>= 0) {
188 if (a
< 0 && b
< 0) {
189 if (a
== -1 && b
== -1) {
194 /* Invalid state, abort. */
198 /* Both are valid file descriptors. */
199 ret
= fstat(a
, &a_stat
);
201 PERROR("Failed to fstat userspace probe location binary fd %d",
206 ret
= fstat(b
, &b_stat
);
208 PERROR("Failed to fstat userspace probe location binary fd %d",
213 is_equal
= (a_stat
.st_ino
== b_stat
.st_ino
) &&
214 (a_stat
.st_dev
== b_stat
.st_dev
);
220 static unsigned long lttng_userspace_probe_location_function_hash(
221 const struct lttng_userspace_probe_location
*location
)
223 unsigned long hash
= hash_key_ulong(
224 (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
,
226 struct lttng_userspace_probe_location_function
*function_location
=
227 container_of(location
, typeof(*function_location
),
230 hash
^= hash_key_str(function_location
->function_name
, lttng_ht_seed
);
231 hash
^= hash_key_str(function_location
->binary_path
, lttng_ht_seed
);
233 * No need to hash on the fd. Worst comes to worse,
234 * the equal function will discriminate.
239 static bool lttng_userspace_probe_location_function_is_equal(
240 const struct lttng_userspace_probe_location
*_a
,
241 const struct lttng_userspace_probe_location
*_b
)
243 bool is_equal
= false;
244 struct lttng_userspace_probe_location_function
*a
, *b
;
246 a
= container_of(_a
, struct lttng_userspace_probe_location_function
,
248 b
= container_of(_b
, struct lttng_userspace_probe_location_function
,
251 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
255 LTTNG_ASSERT(a
->function_name
);
256 LTTNG_ASSERT(b
->function_name
);
257 if (strcmp(a
->function_name
, b
->function_name
)) {
261 LTTNG_ASSERT(a
->binary_path
);
262 LTTNG_ASSERT(b
->binary_path
);
263 if (strcmp(a
->binary_path
, b
->binary_path
)) {
267 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
268 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
273 static struct lttng_userspace_probe_location
*
274 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
275 const char *function_name
,
276 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
280 struct fd_handle
*binary_fd_handle
= NULL
;
281 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
282 struct lttng_userspace_probe_location
*ret
= NULL
;
283 struct lttng_userspace_probe_location_function
*location
;
286 binary_fd
= open(binary_path
, O_RDONLY
);
288 PERROR("Error opening the binary");
292 binary_fd_handle
= fd_handle_create(binary_fd
);
297 /* Ownership transferred to fd_handle. */
301 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
302 if (!function_name_copy
) {
303 PERROR("Error duplicating the function name");
307 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
308 if (!binary_path_copy
) {
309 PERROR("Error duplicating the function name");
313 location
= zmalloc(sizeof(*location
));
315 PERROR("Error allocating userspace probe location");
319 location
->function_name
= function_name_copy
;
320 location
->binary_path
= binary_path_copy
;
321 location
->binary_fd_handle
= binary_fd_handle
;
322 binary_fd_handle
= NULL
;
323 location
->instrumentation_type
=
324 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
326 ret
= &location
->parent
;
327 ret
->lookup_method
= lookup_method
;
328 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
329 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
330 ret
->hash
= lttng_userspace_probe_location_function_hash
;
334 free(function_name_copy
);
335 free(binary_path_copy
);
336 if (binary_fd
>= 0) {
337 if (close(binary_fd
)) {
338 PERROR("Error closing binary fd in error path");
341 fd_handle_put(binary_fd_handle
);
346 static unsigned long lttng_userspace_probe_location_tracepoint_hash(
347 const struct lttng_userspace_probe_location
*location
)
349 unsigned long hash
= hash_key_ulong(
350 (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
,
352 struct lttng_userspace_probe_location_tracepoint
*tp_location
=
353 container_of(location
, typeof(*tp_location
), parent
);
355 hash
^= hash_key_str(tp_location
->probe_name
, lttng_ht_seed
);
356 hash
^= hash_key_str(tp_location
->provider_name
, lttng_ht_seed
);
357 hash
^= hash_key_str(tp_location
->binary_path
, lttng_ht_seed
);
359 * No need to hash on the fd. Worst comes to worse,
360 * the equal function will discriminate.
365 static bool lttng_userspace_probe_location_tracepoint_is_equal(
366 const struct lttng_userspace_probe_location
*_a
,
367 const struct lttng_userspace_probe_location
*_b
)
369 bool is_equal
= false;
370 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
372 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
,
374 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
,
377 LTTNG_ASSERT(a
->probe_name
);
378 LTTNG_ASSERT(b
->probe_name
);
379 if (strcmp(a
->probe_name
, b
->probe_name
)) {
383 LTTNG_ASSERT(a
->provider_name
);
384 LTTNG_ASSERT(b
->provider_name
);
385 if (strcmp(a
->provider_name
, b
->provider_name
)) {
389 LTTNG_ASSERT(a
->binary_path
);
390 LTTNG_ASSERT(b
->binary_path
);
391 if (strcmp(a
->binary_path
, b
->binary_path
)) {
395 is_equal
= fd_is_equal(a
->binary_fd_handle
? fd_handle_get_fd(a
->binary_fd_handle
) : -1,
396 b
->binary_fd_handle
? fd_handle_get_fd(b
->binary_fd_handle
) : -1);
402 static struct lttng_userspace_probe_location
*
403 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
404 const char *provider_name
, const char *probe_name
,
405 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
409 struct fd_handle
*binary_fd_handle
= NULL
;
410 char *probe_name_copy
= NULL
;
411 char *provider_name_copy
= NULL
;
412 char *binary_path_copy
= NULL
;
413 struct lttng_userspace_probe_location
*ret
= NULL
;
414 struct lttng_userspace_probe_location_tracepoint
*location
;
417 binary_fd
= open(binary_path
, O_RDONLY
);
423 binary_fd_handle
= fd_handle_create(binary_fd
);
428 /* Ownership transferred to fd_handle. */
432 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
433 if (!probe_name_copy
) {
434 PERROR("lttng_strndup");
438 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
439 if (!provider_name_copy
) {
440 PERROR("lttng_strndup");
444 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
445 if (!binary_path_copy
) {
446 PERROR("lttng_strndup");
450 location
= zmalloc(sizeof(*location
));
456 location
->probe_name
= probe_name_copy
;
457 location
->provider_name
= provider_name_copy
;
458 location
->binary_path
= binary_path_copy
;
459 location
->binary_fd_handle
= binary_fd_handle
;
460 binary_fd_handle
= NULL
;
462 ret
= &location
->parent
;
463 ret
->lookup_method
= lookup_method
;
464 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
465 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
466 ret
->hash
= lttng_userspace_probe_location_tracepoint_hash
;
470 free(probe_name_copy
);
471 free(provider_name_copy
);
472 free(binary_path_copy
);
473 if (binary_fd
>= 0) {
474 if (close(binary_fd
)) {
475 PERROR("Error closing binary fd in error path");
478 fd_handle_put(binary_fd_handle
);
483 struct lttng_userspace_probe_location
*
484 lttng_userspace_probe_location_function_create(const char *binary_path
,
485 const char *function_name
,
486 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
488 struct lttng_userspace_probe_location
*ret
= NULL
;
490 if (!binary_path
|| !function_name
) {
491 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
495 switch (lttng_userspace_probe_location_lookup_method_get_type(
497 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
498 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
501 /* Invalid probe location lookup method. */
505 ret
= lttng_userspace_probe_location_function_create_no_check(
506 binary_path
, function_name
, lookup_method
, true);
511 struct lttng_userspace_probe_location
*
512 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
513 const char *provider_name
, const char *probe_name
,
514 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
516 struct lttng_userspace_probe_location
*ret
= NULL
;
518 if (!binary_path
|| !probe_name
|| !provider_name
) {
519 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
523 switch (lttng_userspace_probe_location_lookup_method_get_type(
525 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
528 /* Invalid probe location lookup method. */
532 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
533 binary_path
, provider_name
, probe_name
, lookup_method
, true);
538 static struct lttng_userspace_probe_location_lookup_method
*
539 lttng_userspace_probe_location_lookup_method_function_elf_copy(
540 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
542 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
543 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
545 LTTNG_ASSERT(lookup_method
);
546 LTTNG_ASSERT(lookup_method
->type
==
547 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
549 elf_method
= zmalloc(sizeof(*elf_method
));
551 PERROR("Error allocating ELF userspace probe lookup method");
555 elf_method
->parent
.type
= lookup_method
->type
;
556 parent
= &elf_method
->parent
;
565 static struct lttng_userspace_probe_location_lookup_method
*
566 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
567 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
569 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
570 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
572 LTTNG_ASSERT(lookup_method
);
573 LTTNG_ASSERT(lookup_method
->type
==
574 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
576 sdt_method
= zmalloc(sizeof(*sdt_method
));
582 sdt_method
->parent
.type
= lookup_method
->type
;
583 parent
= &sdt_method
->parent
;
593 static struct lttng_userspace_probe_location
*
594 lttng_userspace_probe_location_function_copy(
595 const struct lttng_userspace_probe_location
*location
)
597 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
598 struct lttng_userspace_probe_location
*new_location
= NULL
;
599 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
600 const char *binary_path
= NULL
;
601 const char *function_name
= NULL
;
602 struct lttng_userspace_probe_location_function
*function_location
;
604 LTTNG_ASSERT(location
);
605 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
606 function_location
= container_of(
607 location
, typeof(*function_location
), parent
);
609 /* Get probe location fields */
610 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
612 ERR("Userspace probe binary path is NULL");
616 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
617 if (!function_name
) {
618 ERR("Userspace probe function name is NULL");
623 * Duplicate probe location method fields
625 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
626 location
->lookup_method
);
627 switch (lookup_type
) {
628 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
630 lttng_userspace_probe_location_lookup_method_function_elf_copy(
631 location
->lookup_method
);
632 if (!lookup_method
) {
637 /* Invalid probe location lookup method. */
641 /* Create the probe_location */
642 new_location
= lttng_userspace_probe_location_function_create_no_check(
643 binary_path
, function_name
, lookup_method
, false);
645 goto destroy_lookup_method
;
648 /* Set the duplicated fd to the new probe_location */
649 if (lttng_userspace_probe_location_function_set_binary_fd_handle(new_location
,
650 function_location
->binary_fd_handle
) < 0) {
651 goto destroy_probe_location
;
656 destroy_probe_location
:
657 lttng_userspace_probe_location_destroy(new_location
);
658 destroy_lookup_method
:
659 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
666 static struct lttng_userspace_probe_location
*
667 lttng_userspace_probe_location_tracepoint_copy(
668 const struct lttng_userspace_probe_location
*location
)
670 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
671 struct lttng_userspace_probe_location
*new_location
= NULL
;
672 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
673 const char *binary_path
= NULL
;
674 const char *probe_name
= NULL
;
675 const char *provider_name
= NULL
;
676 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
678 LTTNG_ASSERT(location
);
679 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
680 tracepoint_location
= container_of(
681 location
, typeof(*tracepoint_location
), parent
);
683 /* Get probe location fields */
684 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
686 ERR("Userspace probe binary path is NULL");
690 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
692 ERR("Userspace probe probe name is NULL");
696 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
697 if (!provider_name
) {
698 ERR("Userspace probe provider name is NULL");
703 * Duplicate probe location method fields
705 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
706 location
->lookup_method
);
707 switch (lookup_type
) {
708 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
710 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
711 location
->lookup_method
);
712 if (!lookup_method
) {
717 /* Invalid probe location lookup method. */
721 /* Create the probe_location */
722 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
723 binary_path
, provider_name
, probe_name
, lookup_method
, false);
725 goto destroy_lookup_method
;
728 /* Set the duplicated fd to the new probe_location */
729 if (lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(new_location
,
730 tracepoint_location
->binary_fd_handle
) < 0) {
731 goto destroy_probe_location
;
736 destroy_probe_location
:
737 lttng_userspace_probe_location_destroy(new_location
);
738 destroy_lookup_method
:
739 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
746 const char *lttng_userspace_probe_location_function_get_binary_path(
747 const struct lttng_userspace_probe_location
*location
)
749 const char *ret
= NULL
;
750 struct lttng_userspace_probe_location_function
*function_location
;
752 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
753 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
754 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
758 function_location
= container_of(location
,
759 struct lttng_userspace_probe_location_function
,
761 ret
= function_location
->binary_path
;
766 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
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
,
781 ret
= tracepoint_location
->binary_path
;
786 const char *lttng_userspace_probe_location_function_get_function_name(
787 const struct lttng_userspace_probe_location
*location
)
789 const char *ret
= NULL
;
790 struct lttng_userspace_probe_location_function
*function_location
;
792 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
793 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
794 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
798 function_location
= container_of(location
,
799 struct lttng_userspace_probe_location_function
, parent
);
800 ret
= function_location
->function_name
;
805 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
806 const struct lttng_userspace_probe_location
*location
)
808 const char *ret
= NULL
;
809 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
811 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
812 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
813 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
817 tracepoint_location
= container_of(location
,
818 struct lttng_userspace_probe_location_tracepoint
, parent
);
819 ret
= tracepoint_location
->probe_name
;
824 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
825 const struct lttng_userspace_probe_location
*location
)
827 const char *ret
= NULL
;
828 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
830 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
831 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
832 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
836 tracepoint_location
= container_of(location
,
837 struct lttng_userspace_probe_location_tracepoint
, parent
);
838 ret
= tracepoint_location
->provider_name
;
843 int lttng_userspace_probe_location_function_get_binary_fd(
844 const struct lttng_userspace_probe_location
*location
)
847 struct lttng_userspace_probe_location_function
*function_location
;
849 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
850 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
851 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
855 function_location
= container_of(location
,
856 struct lttng_userspace_probe_location_function
, parent
);
857 ret
= function_location
->binary_fd_handle
?
858 fd_handle_get_fd(function_location
->binary_fd_handle
) : -1;
863 enum lttng_userspace_probe_location_function_instrumentation_type
864 lttng_userspace_probe_location_function_get_instrumentation_type(
865 const struct lttng_userspace_probe_location
*location
)
867 enum lttng_userspace_probe_location_function_instrumentation_type type
;
868 struct lttng_userspace_probe_location_function
*function_location
;
870 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
871 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
872 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
873 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
877 function_location
= container_of(location
,
878 struct lttng_userspace_probe_location_function
, parent
);
879 type
= function_location
->instrumentation_type
;
884 enum lttng_userspace_probe_location_status
885 lttng_userspace_probe_location_function_set_instrumentation_type(
886 const struct lttng_userspace_probe_location
*location
,
887 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
889 enum lttng_userspace_probe_location_status status
=
890 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
891 struct lttng_userspace_probe_location_function
*function_location
;
893 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
894 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
895 instrumentation_type
!=
896 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
897 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
898 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
902 function_location
= container_of(location
,
903 struct lttng_userspace_probe_location_function
, parent
);
904 function_location
->instrumentation_type
= instrumentation_type
;
909 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
910 const struct lttng_userspace_probe_location
*location
)
913 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
915 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
916 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
917 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
921 tracepoint_location
= container_of(location
,
922 struct lttng_userspace_probe_location_tracepoint
, parent
);
923 ret
= tracepoint_location
->binary_fd_handle
?
924 fd_handle_get_fd(tracepoint_location
->binary_fd_handle
) : -1;
929 static struct lttng_userspace_probe_location_lookup_method
*
930 lttng_userspace_probe_location_function_get_lookup_method(
931 const struct lttng_userspace_probe_location
*location
)
933 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
935 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
936 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
937 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
941 ret
= location
->lookup_method
;
946 static struct lttng_userspace_probe_location_lookup_method
*
947 lttng_userspace_probe_location_tracepoint_get_lookup_method(
948 const struct lttng_userspace_probe_location
*location
)
950 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
952 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
953 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
954 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
958 ret
= location
->lookup_method
;
963 const struct lttng_userspace_probe_location_lookup_method
*
964 lttng_userspace_probe_location_get_lookup_method(
965 const struct lttng_userspace_probe_location
*location
)
967 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
969 LTTNG_ASSERT(location
);
970 switch (location
->type
) {
971 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
972 ret
= lttng_userspace_probe_location_function_get_lookup_method(
975 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
976 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
980 ERR("Unknowned lookup method.");
987 int lttng_userspace_probe_location_lookup_method_serialize(
988 struct lttng_userspace_probe_location_lookup_method
*method
,
989 struct lttng_payload
*payload
)
992 struct lttng_userspace_probe_location_lookup_method_comm
995 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
996 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
998 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &lookup_method_comm
,
999 sizeof(lookup_method_comm
));
1004 ret
= sizeof(lookup_method_comm
);
1010 int lttng_userspace_probe_location_function_serialize(
1011 const struct lttng_userspace_probe_location
*location
,
1012 struct lttng_payload
*payload
)
1015 size_t function_name_len
, binary_path_len
;
1016 struct lttng_userspace_probe_location_function
*location_function
;
1017 struct lttng_userspace_probe_location_function_comm location_function_comm
;
1019 LTTNG_ASSERT(location
);
1020 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1021 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1023 location_function
= container_of(location
,
1024 struct lttng_userspace_probe_location_function
,
1026 if (!location_function
->function_name
|| !location_function
->binary_path
) {
1027 ret
= -LTTNG_ERR_INVALID
;
1031 if (payload
&& !location_function
->binary_fd_handle
) {
1032 ret
= -LTTNG_ERR_INVALID
;
1036 function_name_len
= strlen(location_function
->function_name
);
1037 if (function_name_len
== 0) {
1038 ret
= -LTTNG_ERR_INVALID
;
1041 binary_path_len
= strlen(location_function
->binary_path
);
1042 if (binary_path_len
== 0) {
1043 ret
= -LTTNG_ERR_INVALID
;
1047 location_function_comm
.function_name_len
= function_name_len
+ 1;
1048 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
1051 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1052 &location_function_comm
,
1053 sizeof(location_function_comm
));
1055 ret
= -LTTNG_ERR_INVALID
;
1058 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1059 location_function
->function_name
,
1060 location_function_comm
.function_name_len
);
1062 ret
= -LTTNG_ERR_INVALID
;
1065 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1066 location_function
->binary_path
,
1067 location_function_comm
.binary_path_len
);
1069 ret
= -LTTNG_ERR_INVALID
;
1072 ret
= lttng_payload_push_fd_handle(
1073 payload
, location_function
->binary_fd_handle
);
1075 ret
= -LTTNG_ERR_INVALID
;
1079 ret
= sizeof(location_function_comm
) +
1080 location_function_comm
.function_name_len
+
1081 location_function_comm
.binary_path_len
;
1087 int lttng_userspace_probe_location_tracepoint_serialize(
1088 const struct lttng_userspace_probe_location
*location
,
1089 struct lttng_payload
*payload
)
1092 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1093 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1094 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1096 LTTNG_ASSERT(location
);
1097 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1098 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1100 location_tracepoint
= container_of(location
,
1101 struct lttng_userspace_probe_location_tracepoint
,
1103 if (!location_tracepoint
->probe_name
||
1104 !location_tracepoint
->provider_name
||
1105 !location_tracepoint
->binary_path
) {
1106 ret
= -LTTNG_ERR_INVALID
;
1110 if (payload
&& !location_tracepoint
->binary_fd_handle
) {
1111 ret
= -LTTNG_ERR_INVALID
;
1115 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1116 if (probe_name_len
== 0) {
1117 ret
= -LTTNG_ERR_INVALID
;
1121 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1122 if (provider_name_len
== 0) {
1123 ret
= -LTTNG_ERR_INVALID
;
1127 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1128 if (binary_path_len
== 0) {
1129 ret
= -LTTNG_ERR_INVALID
;
1133 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1134 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1135 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1138 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1139 &location_tracepoint_comm
,
1140 sizeof(location_tracepoint_comm
));
1142 ret
= -LTTNG_ERR_INVALID
;
1145 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1146 location_tracepoint
->probe_name
,
1147 location_tracepoint_comm
.probe_name_len
);
1149 ret
= -LTTNG_ERR_INVALID
;
1152 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1153 location_tracepoint
->provider_name
,
1154 location_tracepoint_comm
.provider_name_len
);
1156 ret
= -LTTNG_ERR_INVALID
;
1159 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1160 location_tracepoint
->binary_path
,
1161 location_tracepoint_comm
.binary_path_len
);
1163 ret
= -LTTNG_ERR_INVALID
;
1166 ret
= lttng_payload_push_fd_handle(
1167 payload
, location_tracepoint
->binary_fd_handle
);
1169 ret
= -LTTNG_ERR_INVALID
;
1174 ret
= sizeof(location_tracepoint_comm
) +
1175 location_tracepoint_comm
.probe_name_len
+
1176 location_tracepoint_comm
.provider_name_len
+
1177 location_tracepoint_comm
.binary_path_len
;
1183 int lttng_userspace_probe_location_serialize(
1184 const struct lttng_userspace_probe_location
*location
,
1185 struct lttng_payload
*payload
)
1187 int ret
, buffer_use
= 0;
1188 struct lttng_userspace_probe_location_comm location_generic_comm
;
1191 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
1192 ret
= -LTTNG_ERR_INVALID
;
1196 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1198 location_generic_comm
.type
= (int8_t) location
->type
;
1200 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1201 &location_generic_comm
,
1202 sizeof(location_generic_comm
));
1207 buffer_use
+= sizeof(location_generic_comm
);
1209 switch (lttng_userspace_probe_location_get_type(location
)) {
1210 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1211 ret
= lttng_userspace_probe_location_function_serialize(
1214 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1215 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1219 ERR("Unsupported probe location type");
1220 ret
= -LTTNG_ERR_INVALID
;
1228 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1229 location
->lookup_method
, payload
);
1239 int lttng_userspace_probe_location_function_create_from_payload(
1240 struct lttng_payload_view
*view
,
1241 struct lttng_userspace_probe_location
**location
)
1243 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1244 const char *function_name_src
, *binary_path_src
;
1245 char *function_name
= NULL
, *binary_path
= NULL
;
1247 size_t expected_size
;
1248 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1250 LTTNG_ASSERT(location
);
1252 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1253 ret
= -LTTNG_ERR_INVALID
;
1257 location_function_comm
=
1258 (typeof(location_function_comm
)) view
->buffer
.data
;
1260 expected_size
= sizeof(*location_function_comm
) +
1261 location_function_comm
->function_name_len
+
1262 location_function_comm
->binary_path_len
;
1264 if (view
->buffer
.size
< expected_size
) {
1265 ret
= -LTTNG_ERR_INVALID
;
1269 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1270 binary_path_src
= function_name_src
+
1271 location_function_comm
->function_name_len
;
1273 if (!lttng_buffer_view_contains_string(&view
->buffer
, function_name_src
,
1274 location_function_comm
->function_name_len
)) {
1275 ret
= -LTTNG_ERR_INVALID
;
1279 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1280 location_function_comm
->binary_path_len
)) {
1281 ret
= -LTTNG_ERR_INVALID
;
1285 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1286 if (!function_name
) {
1287 PERROR("lttng_strndup");
1288 ret
= -LTTNG_ERR_NOMEM
;
1292 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1294 PERROR("lttng_strndup");
1295 ret
= -LTTNG_ERR_NOMEM
;
1299 *location
= lttng_userspace_probe_location_function_create_no_check(
1300 binary_path
, function_name
, NULL
, false);
1302 ret
= -LTTNG_ERR_INVALID
;
1306 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(
1307 *location
, binary_fd_handle
);
1309 ret
= -LTTNG_ERR_INVALID
;
1313 ret
= (int) expected_size
;
1315 fd_handle_put(binary_fd_handle
);
1316 free(function_name
);
1322 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1323 struct lttng_payload_view
*view
,
1324 struct lttng_userspace_probe_location
**location
)
1326 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1327 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1328 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1330 size_t expected_size
;
1331 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1333 LTTNG_ASSERT(location
);
1335 if (!binary_fd_handle
) {
1336 ret
= -LTTNG_ERR_INVALID
;
1340 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1341 ret
= -LTTNG_ERR_INVALID
;
1345 location_tracepoint_comm
=
1346 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1348 expected_size
= sizeof(*location_tracepoint_comm
) +
1349 location_tracepoint_comm
->probe_name_len
+
1350 location_tracepoint_comm
->provider_name_len
+
1351 location_tracepoint_comm
->binary_path_len
;
1353 if (view
->buffer
.size
< expected_size
) {
1354 ret
= -LTTNG_ERR_INVALID
;
1358 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1359 provider_name_src
= probe_name_src
+
1360 location_tracepoint_comm
->probe_name_len
;
1361 binary_path_src
= provider_name_src
+
1362 location_tracepoint_comm
->provider_name_len
;
1364 if (!lttng_buffer_view_contains_string(&view
->buffer
, probe_name_src
,
1365 location_tracepoint_comm
->probe_name_len
)) {
1366 ret
= -LTTNG_ERR_INVALID
;
1370 if (!lttng_buffer_view_contains_string(&view
->buffer
, provider_name_src
,
1371 location_tracepoint_comm
->provider_name_len
)) {
1372 ret
= -LTTNG_ERR_INVALID
;
1376 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1377 location_tracepoint_comm
->binary_path_len
)) {
1378 ret
= -LTTNG_ERR_INVALID
;
1382 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1384 PERROR("lttng_strndup");
1387 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1388 if (!provider_name
) {
1389 PERROR("lttng_strndup");
1393 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1395 PERROR("lttng_strndup");
1399 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1400 binary_path
, provider_name
, probe_name
, NULL
, false);
1402 ret
= -LTTNG_ERR_INVALID
;
1406 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1407 *location
, binary_fd_handle
);
1409 ret
= -LTTNG_ERR_INVALID
;
1413 ret
= (int) expected_size
;
1415 fd_handle_put(binary_fd_handle
);
1417 free(provider_name
);
1423 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1424 struct lttng_payload_view
*view
,
1425 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1428 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1429 enum lttng_userspace_probe_location_lookup_method_type type
;
1432 LTTNG_ASSERT(lookup_method
);
1434 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1435 ret
= -LTTNG_ERR_INVALID
;
1439 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1440 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1443 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1444 *lookup_method
= NULL
;
1446 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1448 lttng_userspace_probe_location_lookup_method_function_elf_create();
1449 if (!(*lookup_method
)) {
1450 ret
= -LTTNG_ERR_INVALID
;
1454 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1456 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1457 if (!(*lookup_method
)) {
1458 ret
= -LTTNG_ERR_INVALID
;
1463 ret
= -LTTNG_ERR_INVALID
;
1467 ret
= sizeof(*lookup_comm
);
1473 int lttng_userspace_probe_location_create_from_payload(
1474 struct lttng_payload_view
*view
,
1475 struct lttng_userspace_probe_location
**location
)
1477 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1478 enum lttng_userspace_probe_location_type type
;
1481 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1482 struct lttng_payload_view probe_location_comm_view
=
1483 lttng_payload_view_from_view(
1484 view
, 0, sizeof(*probe_location_comm
));
1487 LTTNG_ASSERT(location
);
1489 lookup_method
= NULL
;
1491 if (!lttng_payload_view_is_valid(&probe_location_comm_view
)) {
1492 ret
= -LTTNG_ERR_INVALID
;
1496 probe_location_comm
= (typeof(probe_location_comm
)) probe_location_comm_view
.buffer
.data
;
1497 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1498 consumed
+= sizeof(*probe_location_comm
);
1501 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1503 struct lttng_payload_view location_view
=
1504 lttng_payload_view_from_view(
1505 view
, consumed
, -1);
1507 ret
= lttng_userspace_probe_location_function_create_from_payload(
1508 &location_view
, location
);
1514 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1516 struct lttng_payload_view location_view
=
1517 lttng_payload_view_from_view(view
, consumed
, -1);
1519 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1520 &location_view
, location
);
1527 ret
= -LTTNG_ERR_INVALID
;
1532 if (view
->buffer
.size
<= consumed
) {
1533 ret
= -LTTNG_ERR_INVALID
;
1538 struct lttng_payload_view lookup_method_view
=
1539 lttng_payload_view_from_view(
1540 view
, consumed
, -1);
1542 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1543 &lookup_method_view
, &lookup_method
);
1546 ret
= -LTTNG_ERR_INVALID
;
1550 LTTNG_ASSERT(lookup_method
);
1551 (*location
)->lookup_method
= lookup_method
;
1552 lookup_method
= NULL
;
1559 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1560 struct lttng_userspace_probe_location
*location
,
1561 struct fd_handle
*binary_fd
)
1564 struct lttng_userspace_probe_location_function
*function_location
;
1566 LTTNG_ASSERT(location
);
1567 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1569 function_location
= container_of(location
,
1570 struct lttng_userspace_probe_location_function
, parent
);
1571 fd_handle_put(function_location
->binary_fd_handle
);
1572 fd_handle_get(binary_fd
);
1573 function_location
->binary_fd_handle
= binary_fd
;
1578 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1579 struct lttng_userspace_probe_location
*location
,
1580 struct fd_handle
*binary_fd
)
1583 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1585 LTTNG_ASSERT(location
);
1586 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1588 tracepoint_location
= container_of(location
,
1589 struct lttng_userspace_probe_location_tracepoint
, parent
);
1590 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1591 fd_handle_get(binary_fd
);
1592 tracepoint_location
->binary_fd_handle
= binary_fd
;
1597 int lttng_userspace_probe_location_function_flatten(
1598 const struct lttng_userspace_probe_location
*location
,
1599 struct lttng_dynamic_buffer
*buffer
)
1601 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1602 struct lttng_userspace_probe_location_function
*probe_function
;
1603 struct lttng_userspace_probe_location_function flat_probe
;
1604 size_t function_name_len
, binary_path_len
;
1605 size_t padding_needed
= 0;
1606 char *flat_probe_start
;
1607 int storage_needed
= 0;
1610 LTTNG_ASSERT(location
);
1612 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1613 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1614 ret
= -LTTNG_ERR_INVALID
;
1618 probe_function
= container_of(location
,
1619 struct lttng_userspace_probe_location_function
,
1621 LTTNG_ASSERT(probe_function
->function_name
);
1622 LTTNG_ASSERT(probe_function
->binary_path
);
1625 sizeof(struct lttng_userspace_probe_location_function
);
1626 function_name_len
= strlen(probe_function
->function_name
) + 1;
1627 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1628 storage_needed
+= function_name_len
+ binary_path_len
;
1631 * The lookup method is aligned to 64-bit within the buffer.
1632 * This is needed even if there is no lookup method since
1633 * the next structure in the buffer probably needs to be
1634 * aligned too (depending on the arch).
1636 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1637 storage_needed
+= padding_needed
;
1639 if (location
->lookup_method
) {
1640 /* NOTE: elf look-up method is assumed here. */
1641 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1645 ret
= storage_needed
;
1649 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1650 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1651 buffer
->size
+ storage_needed
);
1657 memset(&flat_probe
, 0, sizeof(flat_probe
));
1659 flat_probe_start
= buffer
->data
+ buffer
->size
;
1660 flat_probe
.parent
.type
= location
->type
;
1662 * The lookup method, if present, is the last element in the flat
1663 * representation of the probe.
1665 if (location
->lookup_method
) {
1666 flat_probe
.parent
.lookup_method
=
1667 (struct lttng_userspace_probe_location_lookup_method
*)
1668 (flat_probe_start
+ sizeof(flat_probe
) +
1669 function_name_len
+ binary_path_len
+ padding_needed
);
1671 flat_probe
.parent
.lookup_method
= NULL
;
1674 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1675 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1676 flat_probe
.binary_fd_handle
= NULL
;
1677 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1678 sizeof(flat_probe
));
1683 ret
= lttng_dynamic_buffer_append(buffer
,
1684 probe_function
->function_name
, function_name_len
);
1688 ret
= lttng_dynamic_buffer_append(buffer
,
1689 probe_function
->binary_path
, binary_path_len
);
1694 /* Insert padding before the lookup method. */
1695 ret
= lttng_dynamic_buffer_set_size(buffer
,
1696 buffer
->size
+ padding_needed
);
1701 if (!location
->lookup_method
) {
1702 /* Not an error, the default method is used. */
1703 ret
= storage_needed
;
1707 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1708 flat_lookup_method
.parent
.type
=
1709 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1710 ret
= lttng_dynamic_buffer_append(buffer
,
1711 &flat_lookup_method
, sizeof(flat_lookup_method
));
1715 ret
= storage_needed
;
1721 int lttng_userspace_probe_location_tracepoint_flatten(
1722 const struct lttng_userspace_probe_location
*location
,
1723 struct lttng_dynamic_buffer
*buffer
)
1725 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1726 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1727 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1728 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1729 size_t padding_needed
= 0;
1730 int storage_needed
= 0;
1731 char *flat_probe_start
;
1734 LTTNG_ASSERT(location
);
1736 /* Only SDT tracepoints are supported at the moment */
1737 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1738 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1739 ret
= -LTTNG_ERR_INVALID
;
1742 probe_tracepoint
= container_of(location
,
1743 struct lttng_userspace_probe_location_tracepoint
,
1745 LTTNG_ASSERT(probe_tracepoint
->probe_name
);
1746 LTTNG_ASSERT(probe_tracepoint
->provider_name
);
1747 LTTNG_ASSERT(probe_tracepoint
->binary_path
);
1749 /* Compute the storage space needed to flatten the probe location */
1750 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1752 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1753 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1754 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1756 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1759 * The lookup method is aligned to 64-bit within the buffer.
1760 * This is needed even if there is no lookup method since
1761 * the next structure in the buffer probably needs to be
1762 * aligned too (depending on the arch).
1764 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1765 storage_needed
+= padding_needed
;
1767 if (location
->lookup_method
) {
1768 /* NOTE: elf look-up method is assumed here. */
1770 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1774 * If the caller set buffer to NULL, return the size of the needed buffer.
1777 ret
= storage_needed
;
1781 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1782 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1783 buffer
->size
+ storage_needed
);
1789 memset(&flat_probe
, 0, sizeof(flat_probe
));
1791 flat_probe_start
= buffer
->data
+ buffer
->size
;
1792 flat_probe
.parent
.type
= location
->type
;
1795 * The lookup method, if present, is the last element in the flat
1796 * representation of the probe.
1798 if (location
->lookup_method
) {
1799 flat_probe
.parent
.lookup_method
=
1800 (struct lttng_userspace_probe_location_lookup_method
*)
1801 (flat_probe_start
+ sizeof(flat_probe
) +
1802 probe_name_len
+ provider_name_len
+
1803 binary_path_len
+ padding_needed
);
1805 flat_probe
.parent
.lookup_method
= NULL
;
1808 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1809 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1810 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1811 flat_probe
.binary_fd_handle
= NULL
;
1812 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1817 /* Append all the fields to the buffer */
1818 ret
= lttng_dynamic_buffer_append(buffer
,
1819 probe_tracepoint
->probe_name
, probe_name_len
);
1823 ret
= lttng_dynamic_buffer_append(buffer
,
1824 probe_tracepoint
->provider_name
, provider_name_len
);
1828 ret
= lttng_dynamic_buffer_append(buffer
,
1829 probe_tracepoint
->binary_path
, binary_path_len
);
1834 /* Insert padding before the lookup method. */
1835 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1840 if (!location
->lookup_method
) {
1841 /* Not an error, the default method is used. */
1842 ret
= storage_needed
;
1846 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1848 flat_lookup_method
.parent
.type
=
1849 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1850 ret
= lttng_dynamic_buffer_append(buffer
,
1851 &flat_lookup_method
, sizeof(flat_lookup_method
));
1855 ret
= storage_needed
;
1861 int lttng_userspace_probe_location_flatten(
1862 const struct lttng_userspace_probe_location
*location
,
1863 struct lttng_dynamic_buffer
*buffer
)
1867 ret
= -LTTNG_ERR_INVALID
;
1871 /* Only types currently supported. */
1872 switch (location
->type
) {
1873 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1874 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1876 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1877 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1880 ret
= -LTTNG_ERR_INVALID
;
1889 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1890 const struct lttng_userspace_probe_location
*location
)
1892 struct lttng_userspace_probe_location
*new_location
= NULL
;
1893 enum lttng_userspace_probe_location_type type
;
1899 type
= lttng_userspace_probe_location_get_type(location
);
1901 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1903 lttng_userspace_probe_location_function_copy(location
);
1904 if (!new_location
) {
1908 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1910 lttng_userspace_probe_location_tracepoint_copy(location
);
1911 if (!new_location
) {
1916 new_location
= NULL
;
1920 return new_location
;
1924 bool lttng_userspace_probe_location_lookup_method_is_equal(
1925 const struct lttng_userspace_probe_location_lookup_method
*a
,
1926 const struct lttng_userspace_probe_location_lookup_method
*b
)
1928 bool is_equal
= false;
1939 if (a
->type
!= b
->type
) {
1949 bool lttng_userspace_probe_location_is_equal(
1950 const struct lttng_userspace_probe_location
*a
,
1951 const struct lttng_userspace_probe_location
*b
)
1953 bool is_equal
= false;
1964 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1965 a
->lookup_method
, b
->lookup_method
)) {
1969 if (a
->type
!= b
->type
) {
1973 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1979 unsigned long lttng_userspace_probe_location_hash(
1980 const struct lttng_userspace_probe_location
*location
)
1982 return location
->hash(location
);
1986 enum lttng_error_code
lttng_userspace_probe_location_mi_serialize(
1987 const struct lttng_userspace_probe_location
*location
,
1988 struct mi_writer
*writer
)
1990 typedef enum lttng_error_code (*mi_fp
)(
1991 const struct lttng_userspace_probe_location
*,
1992 struct mi_writer
*);
1995 enum lttng_error_code ret_code
;
1996 mi_fp mi_function
= NULL
;
1998 LTTNG_ASSERT(location
);
1999 LTTNG_ASSERT(writer
);
2001 switch (lttng_userspace_probe_location_get_type(location
)) {
2002 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
2003 mi_function
= lttng_userspace_probe_location_function_mi_serialize
;
2005 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
2006 mi_function
= lttng_userspace_probe_location_tracepoint_mi_serialize
;
2013 /* Open userspace probe location element. */
2014 ret
= mi_lttng_writer_open_element(
2015 writer
, mi_lttng_element_userspace_probe_location
);
2020 /* Underlying user space probe location. */
2021 ret_code
= mi_function(location
, writer
);
2022 if (ret_code
!= LTTNG_OK
) {
2026 /* Close userspace probe location element. */
2027 ret
= mi_lttng_writer_close_element(writer
);
2032 ret_code
= LTTNG_OK
;
2036 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2041 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
2042 const struct lttng_userspace_probe_location_lookup_method
2044 struct mi_writer
*writer
)
2047 enum lttng_error_code ret_code
;
2048 const char *type_element_str
;
2050 LTTNG_ASSERT(method
);
2051 LTTNG_ASSERT(writer
);
2053 switch (lttng_userspace_probe_location_lookup_method_get_type(method
)) {
2054 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
2056 mi_lttng_element_userspace_probe_location_lookup_method_function_default
;
2058 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
2060 mi_lttng_element_userspace_probe_location_lookup_method_function_elf
;
2062 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
2064 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt
;
2071 /* Open userspace probe location lookup method element. */
2072 ret
= mi_lttng_writer_open_element(writer
,
2073 mi_lttng_element_userspace_probe_location_lookup_method
);
2078 /* User space probe location lookup method empty element. */
2079 ret
= mi_lttng_writer_open_element(writer
, type_element_str
);
2084 /* Close userspace probe location lookup method element. */
2085 ret
= mi_lttng_close_multi_element(writer
, 2);
2090 ret_code
= LTTNG_OK
;
2094 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2099 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
2100 const struct lttng_userspace_probe_location
*location
,
2101 struct mi_writer
*writer
)
2104 enum lttng_error_code ret_code
;
2105 const char *probe_name
= NULL
;
2106 const char *provider_name
= NULL
;
2107 const char *binary_path
= NULL
;
2108 const struct lttng_userspace_probe_location_lookup_method
2109 *lookup_method
= NULL
;
2111 LTTNG_ASSERT(location
);
2112 LTTNG_ASSERT(writer
);
2114 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(
2116 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(
2118 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(
2120 lookup_method
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
2123 /* Open userspace probe location tracepoint element. */
2124 ret
= mi_lttng_writer_open_element(writer
,
2125 mi_lttng_element_userspace_probe_location_tracepoint
);
2131 ret
= mi_lttng_writer_write_element_string(writer
,
2132 mi_lttng_element_userspace_probe_location_tracepoint_probe_name
,
2138 /* Provider name. */
2139 ret
= mi_lttng_writer_write_element_string(writer
,
2140 mi_lttng_element_userspace_probe_location_tracepoint_provider_name
,
2147 ret
= mi_lttng_writer_write_element_string(writer
,
2148 mi_lttng_element_userspace_probe_location_binary_path
,
2154 /* The lookup method. */
2155 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2156 lookup_method
, writer
);
2157 if (ret_code
!= LTTNG_OK
) {
2161 /* Close userspace probe location tracepoint. */
2162 ret
= mi_lttng_writer_close_element(writer
);
2167 ret_code
= LTTNG_OK
;
2171 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2176 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
2177 const struct lttng_userspace_probe_location
*location
,
2178 struct mi_writer
*writer
)
2181 enum lttng_error_code ret_code
;
2182 const char *function_name
= NULL
;
2183 const char *binary_path
= NULL
;
2184 const char *instrumentation_type_str
= NULL
;
2185 enum lttng_userspace_probe_location_function_instrumentation_type
2186 instrumentation_type
;
2187 const struct lttng_userspace_probe_location_lookup_method
2188 *lookup_method
= NULL
;
2190 LTTNG_ASSERT(location
);
2191 LTTNG_ASSERT(writer
);
2193 function_name
= lttng_userspace_probe_location_function_get_function_name(
2195 binary_path
= lttng_userspace_probe_location_function_get_binary_path(
2197 instrumentation_type
=
2198 lttng_userspace_probe_location_function_get_instrumentation_type(
2200 lookup_method
= lttng_userspace_probe_location_function_get_lookup_method(
2203 switch (instrumentation_type
) {
2204 case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
:
2205 instrumentation_type_str
=
2206 mi_lttng_userspace_probe_location_function_instrumentation_type_entry
;
2213 /* Open userspace probe location function element. */
2214 ret
= mi_lttng_writer_open_element(writer
,
2215 mi_lttng_element_userspace_probe_location_function
);
2220 /* Function name. */
2221 ret
= mi_lttng_writer_write_element_string(writer
,
2222 mi_lttng_element_userspace_probe_location_function_name
,
2229 ret
= mi_lttng_writer_write_element_string(writer
,
2230 mi_lttng_element_userspace_probe_location_binary_path
,
2236 /* Instrumentation type. */
2237 ret
= mi_lttng_writer_write_element_string(writer
,
2238 mi_lttng_element_userspace_probe_location_function_instrumentation_type
,
2239 instrumentation_type_str
);
2244 /* The lookup method. */
2245 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2246 lookup_method
, writer
);
2247 if (ret_code
!= LTTNG_OK
) {
2251 /* Close userspace probe location function element. */
2252 ret
= mi_lttng_writer_close_element(writer
);
2257 ret_code
= LTTNG_OK
;
2261 ret_code
= LTTNG_ERR_MI_IO_FAIL
;