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("Failed to allocate probe name");
1385 ret
= -LTTNG_ERR_INVALID
;
1388 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1389 if (!provider_name
) {
1390 PERROR("Failed to allocate provider name");
1391 ret
= -LTTNG_ERR_INVALID
;
1395 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1397 PERROR("Failed to allocate binary path");
1398 ret
= -LTTNG_ERR_INVALID
;
1402 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1403 binary_path
, provider_name
, probe_name
, NULL
, false);
1405 ret
= -LTTNG_ERR_INVALID
;
1409 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1410 *location
, binary_fd_handle
);
1412 ret
= -LTTNG_ERR_INVALID
;
1416 ret
= (int) expected_size
;
1418 fd_handle_put(binary_fd_handle
);
1420 free(provider_name
);
1426 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1427 struct lttng_payload_view
*view
,
1428 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1431 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1432 enum lttng_userspace_probe_location_lookup_method_type type
;
1435 LTTNG_ASSERT(lookup_method
);
1437 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1438 ret
= -LTTNG_ERR_INVALID
;
1442 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1443 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1446 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1447 *lookup_method
= NULL
;
1449 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1451 lttng_userspace_probe_location_lookup_method_function_elf_create();
1452 if (!(*lookup_method
)) {
1453 ret
= -LTTNG_ERR_INVALID
;
1457 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1459 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1460 if (!(*lookup_method
)) {
1461 ret
= -LTTNG_ERR_INVALID
;
1466 ret
= -LTTNG_ERR_INVALID
;
1470 ret
= sizeof(*lookup_comm
);
1476 int lttng_userspace_probe_location_create_from_payload(
1477 struct lttng_payload_view
*view
,
1478 struct lttng_userspace_probe_location
**location
)
1480 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1481 enum lttng_userspace_probe_location_type type
;
1484 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1485 struct lttng_payload_view probe_location_comm_view
=
1486 lttng_payload_view_from_view(
1487 view
, 0, sizeof(*probe_location_comm
));
1490 LTTNG_ASSERT(location
);
1492 lookup_method
= NULL
;
1494 if (!lttng_payload_view_is_valid(&probe_location_comm_view
)) {
1495 ret
= -LTTNG_ERR_INVALID
;
1499 probe_location_comm
= (typeof(probe_location_comm
)) probe_location_comm_view
.buffer
.data
;
1500 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1501 consumed
+= sizeof(*probe_location_comm
);
1504 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1506 struct lttng_payload_view location_view
=
1507 lttng_payload_view_from_view(
1508 view
, consumed
, -1);
1510 ret
= lttng_userspace_probe_location_function_create_from_payload(
1511 &location_view
, location
);
1517 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1519 struct lttng_payload_view location_view
=
1520 lttng_payload_view_from_view(view
, consumed
, -1);
1522 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1523 &location_view
, location
);
1530 ret
= -LTTNG_ERR_INVALID
;
1535 if (view
->buffer
.size
<= consumed
) {
1536 ret
= -LTTNG_ERR_INVALID
;
1541 struct lttng_payload_view lookup_method_view
=
1542 lttng_payload_view_from_view(
1543 view
, consumed
, -1);
1545 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1546 &lookup_method_view
, &lookup_method
);
1549 ret
= -LTTNG_ERR_INVALID
;
1553 LTTNG_ASSERT(lookup_method
);
1554 (*location
)->lookup_method
= lookup_method
;
1555 lookup_method
= NULL
;
1562 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1563 struct lttng_userspace_probe_location
*location
,
1564 struct fd_handle
*binary_fd
)
1567 struct lttng_userspace_probe_location_function
*function_location
;
1569 LTTNG_ASSERT(location
);
1570 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1572 function_location
= container_of(location
,
1573 struct lttng_userspace_probe_location_function
, parent
);
1574 fd_handle_put(function_location
->binary_fd_handle
);
1575 fd_handle_get(binary_fd
);
1576 function_location
->binary_fd_handle
= binary_fd
;
1581 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1582 struct lttng_userspace_probe_location
*location
,
1583 struct fd_handle
*binary_fd
)
1586 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1588 LTTNG_ASSERT(location
);
1589 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1591 tracepoint_location
= container_of(location
,
1592 struct lttng_userspace_probe_location_tracepoint
, parent
);
1593 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1594 fd_handle_get(binary_fd
);
1595 tracepoint_location
->binary_fd_handle
= binary_fd
;
1600 int lttng_userspace_probe_location_function_flatten(
1601 const struct lttng_userspace_probe_location
*location
,
1602 struct lttng_dynamic_buffer
*buffer
)
1604 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1605 struct lttng_userspace_probe_location_function
*probe_function
;
1606 struct lttng_userspace_probe_location_function flat_probe
;
1607 size_t function_name_len
, binary_path_len
;
1608 size_t padding_needed
= 0;
1609 char *flat_probe_start
;
1610 int storage_needed
= 0;
1613 LTTNG_ASSERT(location
);
1615 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1616 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1617 ret
= -LTTNG_ERR_INVALID
;
1621 probe_function
= container_of(location
,
1622 struct lttng_userspace_probe_location_function
,
1624 LTTNG_ASSERT(probe_function
->function_name
);
1625 LTTNG_ASSERT(probe_function
->binary_path
);
1628 sizeof(struct lttng_userspace_probe_location_function
);
1629 function_name_len
= strlen(probe_function
->function_name
) + 1;
1630 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1631 storage_needed
+= function_name_len
+ binary_path_len
;
1634 * The lookup method is aligned to 64-bit within the buffer.
1635 * This is needed even if there is no lookup method since
1636 * the next structure in the buffer probably needs to be
1637 * aligned too (depending on the arch).
1639 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1640 storage_needed
+= padding_needed
;
1642 if (location
->lookup_method
) {
1643 /* NOTE: elf look-up method is assumed here. */
1644 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1648 ret
= storage_needed
;
1652 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1653 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1654 buffer
->size
+ storage_needed
);
1660 memset(&flat_probe
, 0, sizeof(flat_probe
));
1662 flat_probe_start
= buffer
->data
+ buffer
->size
;
1663 flat_probe
.parent
.type
= location
->type
;
1665 * The lookup method, if present, is the last element in the flat
1666 * representation of the probe.
1668 if (location
->lookup_method
) {
1669 flat_probe
.parent
.lookup_method
=
1670 (struct lttng_userspace_probe_location_lookup_method
*)
1671 (flat_probe_start
+ sizeof(flat_probe
) +
1672 function_name_len
+ binary_path_len
+ padding_needed
);
1674 flat_probe
.parent
.lookup_method
= NULL
;
1677 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1678 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1679 flat_probe
.binary_fd_handle
= NULL
;
1680 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1681 sizeof(flat_probe
));
1686 ret
= lttng_dynamic_buffer_append(buffer
,
1687 probe_function
->function_name
, function_name_len
);
1691 ret
= lttng_dynamic_buffer_append(buffer
,
1692 probe_function
->binary_path
, binary_path_len
);
1697 /* Insert padding before the lookup method. */
1698 ret
= lttng_dynamic_buffer_set_size(buffer
,
1699 buffer
->size
+ padding_needed
);
1704 if (!location
->lookup_method
) {
1705 /* Not an error, the default method is used. */
1706 ret
= storage_needed
;
1710 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1711 flat_lookup_method
.parent
.type
=
1712 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1713 ret
= lttng_dynamic_buffer_append(buffer
,
1714 &flat_lookup_method
, sizeof(flat_lookup_method
));
1718 ret
= storage_needed
;
1724 int lttng_userspace_probe_location_tracepoint_flatten(
1725 const struct lttng_userspace_probe_location
*location
,
1726 struct lttng_dynamic_buffer
*buffer
)
1728 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1729 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1730 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1731 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1732 size_t padding_needed
= 0;
1733 int storage_needed
= 0;
1734 char *flat_probe_start
;
1737 LTTNG_ASSERT(location
);
1739 /* Only SDT tracepoints are supported at the moment */
1740 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1741 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1742 ret
= -LTTNG_ERR_INVALID
;
1745 probe_tracepoint
= container_of(location
,
1746 struct lttng_userspace_probe_location_tracepoint
,
1748 LTTNG_ASSERT(probe_tracepoint
->probe_name
);
1749 LTTNG_ASSERT(probe_tracepoint
->provider_name
);
1750 LTTNG_ASSERT(probe_tracepoint
->binary_path
);
1752 /* Compute the storage space needed to flatten the probe location */
1753 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1755 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1756 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1757 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1759 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1762 * The lookup method is aligned to 64-bit within the buffer.
1763 * This is needed even if there is no lookup method since
1764 * the next structure in the buffer probably needs to be
1765 * aligned too (depending on the arch).
1767 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1768 storage_needed
+= padding_needed
;
1770 if (location
->lookup_method
) {
1771 /* NOTE: elf look-up method is assumed here. */
1773 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1777 * If the caller set buffer to NULL, return the size of the needed buffer.
1780 ret
= storage_needed
;
1784 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1785 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1786 buffer
->size
+ storage_needed
);
1792 memset(&flat_probe
, 0, sizeof(flat_probe
));
1794 flat_probe_start
= buffer
->data
+ buffer
->size
;
1795 flat_probe
.parent
.type
= location
->type
;
1798 * The lookup method, if present, is the last element in the flat
1799 * representation of the probe.
1801 if (location
->lookup_method
) {
1802 flat_probe
.parent
.lookup_method
=
1803 (struct lttng_userspace_probe_location_lookup_method
*)
1804 (flat_probe_start
+ sizeof(flat_probe
) +
1805 probe_name_len
+ provider_name_len
+
1806 binary_path_len
+ padding_needed
);
1808 flat_probe
.parent
.lookup_method
= NULL
;
1811 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1812 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1813 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1814 flat_probe
.binary_fd_handle
= NULL
;
1815 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1820 /* Append all the fields to the buffer */
1821 ret
= lttng_dynamic_buffer_append(buffer
,
1822 probe_tracepoint
->probe_name
, probe_name_len
);
1826 ret
= lttng_dynamic_buffer_append(buffer
,
1827 probe_tracepoint
->provider_name
, provider_name_len
);
1831 ret
= lttng_dynamic_buffer_append(buffer
,
1832 probe_tracepoint
->binary_path
, binary_path_len
);
1837 /* Insert padding before the lookup method. */
1838 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1843 if (!location
->lookup_method
) {
1844 /* Not an error, the default method is used. */
1845 ret
= storage_needed
;
1849 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1851 flat_lookup_method
.parent
.type
=
1852 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1853 ret
= lttng_dynamic_buffer_append(buffer
,
1854 &flat_lookup_method
, sizeof(flat_lookup_method
));
1858 ret
= storage_needed
;
1864 int lttng_userspace_probe_location_flatten(
1865 const struct lttng_userspace_probe_location
*location
,
1866 struct lttng_dynamic_buffer
*buffer
)
1870 ret
= -LTTNG_ERR_INVALID
;
1874 /* Only types currently supported. */
1875 switch (location
->type
) {
1876 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1877 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1879 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1880 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1883 ret
= -LTTNG_ERR_INVALID
;
1892 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1893 const struct lttng_userspace_probe_location
*location
)
1895 struct lttng_userspace_probe_location
*new_location
= NULL
;
1896 enum lttng_userspace_probe_location_type type
;
1902 type
= lttng_userspace_probe_location_get_type(location
);
1904 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1906 lttng_userspace_probe_location_function_copy(location
);
1907 if (!new_location
) {
1911 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1913 lttng_userspace_probe_location_tracepoint_copy(location
);
1914 if (!new_location
) {
1919 new_location
= NULL
;
1923 return new_location
;
1927 bool lttng_userspace_probe_location_lookup_method_is_equal(
1928 const struct lttng_userspace_probe_location_lookup_method
*a
,
1929 const struct lttng_userspace_probe_location_lookup_method
*b
)
1931 bool is_equal
= false;
1942 if (a
->type
!= b
->type
) {
1952 bool lttng_userspace_probe_location_is_equal(
1953 const struct lttng_userspace_probe_location
*a
,
1954 const struct lttng_userspace_probe_location
*b
)
1956 bool is_equal
= false;
1967 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1968 a
->lookup_method
, b
->lookup_method
)) {
1972 if (a
->type
!= b
->type
) {
1976 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1982 unsigned long lttng_userspace_probe_location_hash(
1983 const struct lttng_userspace_probe_location
*location
)
1985 return location
->hash(location
);
1989 enum lttng_error_code
lttng_userspace_probe_location_mi_serialize(
1990 const struct lttng_userspace_probe_location
*location
,
1991 struct mi_writer
*writer
)
1993 typedef enum lttng_error_code (*mi_fp
)(
1994 const struct lttng_userspace_probe_location
*,
1995 struct mi_writer
*);
1998 enum lttng_error_code ret_code
;
1999 mi_fp mi_function
= NULL
;
2001 LTTNG_ASSERT(location
);
2002 LTTNG_ASSERT(writer
);
2004 switch (lttng_userspace_probe_location_get_type(location
)) {
2005 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
2006 mi_function
= lttng_userspace_probe_location_function_mi_serialize
;
2008 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
2009 mi_function
= lttng_userspace_probe_location_tracepoint_mi_serialize
;
2016 /* Open userspace probe location element. */
2017 ret
= mi_lttng_writer_open_element(
2018 writer
, mi_lttng_element_userspace_probe_location
);
2023 /* Underlying user space probe location. */
2024 ret_code
= mi_function(location
, writer
);
2025 if (ret_code
!= LTTNG_OK
) {
2029 /* Close userspace probe location element. */
2030 ret
= mi_lttng_writer_close_element(writer
);
2035 ret_code
= LTTNG_OK
;
2039 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2044 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
2045 const struct lttng_userspace_probe_location_lookup_method
2047 struct mi_writer
*writer
)
2050 enum lttng_error_code ret_code
;
2051 const char *type_element_str
;
2053 LTTNG_ASSERT(method
);
2054 LTTNG_ASSERT(writer
);
2056 switch (lttng_userspace_probe_location_lookup_method_get_type(method
)) {
2057 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
2059 mi_lttng_element_userspace_probe_location_lookup_method_function_default
;
2061 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
2063 mi_lttng_element_userspace_probe_location_lookup_method_function_elf
;
2065 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
2067 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt
;
2074 /* Open userspace probe location lookup method element. */
2075 ret
= mi_lttng_writer_open_element(writer
,
2076 mi_lttng_element_userspace_probe_location_lookup_method
);
2081 /* User space probe location lookup method empty element. */
2082 ret
= mi_lttng_writer_open_element(writer
, type_element_str
);
2087 /* Close userspace probe location lookup method element. */
2088 ret
= mi_lttng_close_multi_element(writer
, 2);
2093 ret_code
= LTTNG_OK
;
2097 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2102 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
2103 const struct lttng_userspace_probe_location
*location
,
2104 struct mi_writer
*writer
)
2107 enum lttng_error_code ret_code
;
2108 const char *probe_name
= NULL
;
2109 const char *provider_name
= NULL
;
2110 const char *binary_path
= NULL
;
2111 const struct lttng_userspace_probe_location_lookup_method
2112 *lookup_method
= NULL
;
2114 LTTNG_ASSERT(location
);
2115 LTTNG_ASSERT(writer
);
2117 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(
2119 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(
2121 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(
2123 lookup_method
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
2126 /* Open userspace probe location tracepoint element. */
2127 ret
= mi_lttng_writer_open_element(writer
,
2128 mi_lttng_element_userspace_probe_location_tracepoint
);
2134 ret
= mi_lttng_writer_write_element_string(writer
,
2135 mi_lttng_element_userspace_probe_location_tracepoint_probe_name
,
2141 /* Provider name. */
2142 ret
= mi_lttng_writer_write_element_string(writer
,
2143 mi_lttng_element_userspace_probe_location_tracepoint_provider_name
,
2150 ret
= mi_lttng_writer_write_element_string(writer
,
2151 mi_lttng_element_userspace_probe_location_binary_path
,
2157 /* The lookup method. */
2158 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2159 lookup_method
, writer
);
2160 if (ret_code
!= LTTNG_OK
) {
2164 /* Close userspace probe location tracepoint. */
2165 ret
= mi_lttng_writer_close_element(writer
);
2170 ret_code
= LTTNG_OK
;
2174 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2179 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
2180 const struct lttng_userspace_probe_location
*location
,
2181 struct mi_writer
*writer
)
2184 enum lttng_error_code ret_code
;
2185 const char *function_name
= NULL
;
2186 const char *binary_path
= NULL
;
2187 const char *instrumentation_type_str
= NULL
;
2188 enum lttng_userspace_probe_location_function_instrumentation_type
2189 instrumentation_type
;
2190 const struct lttng_userspace_probe_location_lookup_method
2191 *lookup_method
= NULL
;
2193 LTTNG_ASSERT(location
);
2194 LTTNG_ASSERT(writer
);
2196 function_name
= lttng_userspace_probe_location_function_get_function_name(
2198 binary_path
= lttng_userspace_probe_location_function_get_binary_path(
2200 instrumentation_type
=
2201 lttng_userspace_probe_location_function_get_instrumentation_type(
2203 lookup_method
= lttng_userspace_probe_location_function_get_lookup_method(
2206 switch (instrumentation_type
) {
2207 case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
:
2208 instrumentation_type_str
=
2209 mi_lttng_userspace_probe_location_function_instrumentation_type_entry
;
2216 /* Open userspace probe location function element. */
2217 ret
= mi_lttng_writer_open_element(writer
,
2218 mi_lttng_element_userspace_probe_location_function
);
2223 /* Function name. */
2224 ret
= mi_lttng_writer_write_element_string(writer
,
2225 mi_lttng_element_userspace_probe_location_function_name
,
2232 ret
= mi_lttng_writer_write_element_string(writer
,
2233 mi_lttng_element_userspace_probe_location_binary_path
,
2239 /* Instrumentation type. */
2240 ret
= mi_lttng_writer_write_element_string(writer
,
2241 mi_lttng_element_userspace_probe_location_function_instrumentation_type
,
2242 instrumentation_type_str
);
2247 /* The lookup method. */
2248 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2249 lookup_method
, writer
);
2250 if (ret_code
!= LTTNG_OK
) {
2254 /* Close userspace probe location function element. */
2255 ret
= mi_lttng_writer_close_element(writer
);
2260 ret_code
= LTTNG_OK
;
2264 ret_code
= LTTNG_ERR_MI_IO_FAIL
;