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
;
1182 int lttng_userspace_probe_location_serialize(
1183 const struct lttng_userspace_probe_location
*location
,
1184 struct lttng_payload
*payload
)
1186 int ret
, buffer_use
= 0;
1187 struct lttng_userspace_probe_location_comm location_generic_comm
;
1190 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
1191 ret
= -LTTNG_ERR_INVALID
;
1195 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1197 location_generic_comm
.type
= (int8_t) location
->type
;
1199 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1200 &location_generic_comm
,
1201 sizeof(location_generic_comm
));
1206 buffer_use
+= sizeof(location_generic_comm
);
1208 switch (lttng_userspace_probe_location_get_type(location
)) {
1209 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1210 ret
= lttng_userspace_probe_location_function_serialize(
1213 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1214 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1218 ERR("Unsupported probe location type");
1219 ret
= -LTTNG_ERR_INVALID
;
1227 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1228 location
->lookup_method
, payload
);
1238 int lttng_userspace_probe_location_function_create_from_payload(
1239 struct lttng_payload_view
*view
,
1240 struct lttng_userspace_probe_location
**location
)
1242 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1243 const char *function_name_src
, *binary_path_src
;
1244 char *function_name
= NULL
, *binary_path
= NULL
;
1246 size_t expected_size
;
1247 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1249 LTTNG_ASSERT(location
);
1251 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1252 ret
= -LTTNG_ERR_INVALID
;
1256 location_function_comm
=
1257 (typeof(location_function_comm
)) view
->buffer
.data
;
1259 expected_size
= sizeof(*location_function_comm
) +
1260 location_function_comm
->function_name_len
+
1261 location_function_comm
->binary_path_len
;
1263 if (view
->buffer
.size
< expected_size
) {
1264 ret
= -LTTNG_ERR_INVALID
;
1268 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1269 binary_path_src
= function_name_src
+
1270 location_function_comm
->function_name_len
;
1272 if (!lttng_buffer_view_contains_string(&view
->buffer
, function_name_src
,
1273 location_function_comm
->function_name_len
)) {
1274 ret
= -LTTNG_ERR_INVALID
;
1278 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1279 location_function_comm
->binary_path_len
)) {
1280 ret
= -LTTNG_ERR_INVALID
;
1284 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1285 if (!function_name
) {
1286 PERROR("lttng_strndup");
1287 ret
= -LTTNG_ERR_NOMEM
;
1291 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1293 PERROR("lttng_strndup");
1294 ret
= -LTTNG_ERR_NOMEM
;
1298 *location
= lttng_userspace_probe_location_function_create_no_check(
1299 binary_path
, function_name
, NULL
, false);
1301 ret
= -LTTNG_ERR_INVALID
;
1305 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(
1306 *location
, binary_fd_handle
);
1308 ret
= -LTTNG_ERR_INVALID
;
1312 ret
= (int) expected_size
;
1314 fd_handle_put(binary_fd_handle
);
1315 free(function_name
);
1321 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1322 struct lttng_payload_view
*view
,
1323 struct lttng_userspace_probe_location
**location
)
1325 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1326 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1327 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1329 size_t expected_size
;
1330 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1332 LTTNG_ASSERT(location
);
1334 if (!binary_fd_handle
) {
1335 ret
= -LTTNG_ERR_INVALID
;
1339 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1340 ret
= -LTTNG_ERR_INVALID
;
1344 location_tracepoint_comm
=
1345 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1347 expected_size
= sizeof(*location_tracepoint_comm
) +
1348 location_tracepoint_comm
->probe_name_len
+
1349 location_tracepoint_comm
->provider_name_len
+
1350 location_tracepoint_comm
->binary_path_len
;
1352 if (view
->buffer
.size
< expected_size
) {
1353 ret
= -LTTNG_ERR_INVALID
;
1357 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1358 provider_name_src
= probe_name_src
+
1359 location_tracepoint_comm
->probe_name_len
;
1360 binary_path_src
= provider_name_src
+
1361 location_tracepoint_comm
->provider_name_len
;
1363 if (!lttng_buffer_view_contains_string(&view
->buffer
, probe_name_src
,
1364 location_tracepoint_comm
->probe_name_len
)) {
1365 ret
= -LTTNG_ERR_INVALID
;
1369 if (!lttng_buffer_view_contains_string(&view
->buffer
, provider_name_src
,
1370 location_tracepoint_comm
->provider_name_len
)) {
1371 ret
= -LTTNG_ERR_INVALID
;
1375 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1376 location_tracepoint_comm
->binary_path_len
)) {
1377 ret
= -LTTNG_ERR_INVALID
;
1381 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1383 PERROR("Failed to allocate probe name");
1384 ret
= -LTTNG_ERR_INVALID
;
1387 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1388 if (!provider_name
) {
1389 PERROR("Failed to allocate provider name");
1390 ret
= -LTTNG_ERR_INVALID
;
1394 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1396 PERROR("Failed to allocate binary path");
1397 ret
= -LTTNG_ERR_INVALID
;
1401 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1402 binary_path
, provider_name
, probe_name
, NULL
, false);
1404 ret
= -LTTNG_ERR_INVALID
;
1408 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1409 *location
, binary_fd_handle
);
1411 ret
= -LTTNG_ERR_INVALID
;
1415 ret
= (int) expected_size
;
1417 fd_handle_put(binary_fd_handle
);
1419 free(provider_name
);
1425 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1426 struct lttng_payload_view
*view
,
1427 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1430 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1431 enum lttng_userspace_probe_location_lookup_method_type type
;
1434 LTTNG_ASSERT(lookup_method
);
1436 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1437 ret
= -LTTNG_ERR_INVALID
;
1441 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1442 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1445 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1446 *lookup_method
= NULL
;
1448 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1450 lttng_userspace_probe_location_lookup_method_function_elf_create();
1451 if (!(*lookup_method
)) {
1452 ret
= -LTTNG_ERR_INVALID
;
1456 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1458 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1459 if (!(*lookup_method
)) {
1460 ret
= -LTTNG_ERR_INVALID
;
1465 ret
= -LTTNG_ERR_INVALID
;
1469 ret
= sizeof(*lookup_comm
);
1474 int lttng_userspace_probe_location_create_from_payload(
1475 struct lttng_payload_view
*view
,
1476 struct lttng_userspace_probe_location
**location
)
1478 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1479 enum lttng_userspace_probe_location_type type
;
1482 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1483 struct lttng_payload_view probe_location_comm_view
=
1484 lttng_payload_view_from_view(
1485 view
, 0, sizeof(*probe_location_comm
));
1488 LTTNG_ASSERT(location
);
1490 lookup_method
= NULL
;
1492 if (!lttng_payload_view_is_valid(&probe_location_comm_view
)) {
1493 ret
= -LTTNG_ERR_INVALID
;
1497 probe_location_comm
= (typeof(probe_location_comm
)) probe_location_comm_view
.buffer
.data
;
1498 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1499 consumed
+= sizeof(*probe_location_comm
);
1502 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1504 struct lttng_payload_view location_view
=
1505 lttng_payload_view_from_view(
1506 view
, consumed
, -1);
1508 ret
= lttng_userspace_probe_location_function_create_from_payload(
1509 &location_view
, location
);
1515 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1517 struct lttng_payload_view location_view
=
1518 lttng_payload_view_from_view(view
, consumed
, -1);
1520 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1521 &location_view
, location
);
1528 ret
= -LTTNG_ERR_INVALID
;
1533 if (view
->buffer
.size
<= consumed
) {
1534 ret
= -LTTNG_ERR_INVALID
;
1539 struct lttng_payload_view lookup_method_view
=
1540 lttng_payload_view_from_view(
1541 view
, consumed
, -1);
1543 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1544 &lookup_method_view
, &lookup_method
);
1547 ret
= -LTTNG_ERR_INVALID
;
1551 LTTNG_ASSERT(lookup_method
);
1552 (*location
)->lookup_method
= lookup_method
;
1553 lookup_method
= NULL
;
1560 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1561 struct lttng_userspace_probe_location
*location
,
1562 struct fd_handle
*binary_fd
)
1565 struct lttng_userspace_probe_location_function
*function_location
;
1567 LTTNG_ASSERT(location
);
1568 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1570 function_location
= container_of(location
,
1571 struct lttng_userspace_probe_location_function
, parent
);
1572 fd_handle_put(function_location
->binary_fd_handle
);
1573 fd_handle_get(binary_fd
);
1574 function_location
->binary_fd_handle
= binary_fd
;
1579 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1580 struct lttng_userspace_probe_location
*location
,
1581 struct fd_handle
*binary_fd
)
1584 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1586 LTTNG_ASSERT(location
);
1587 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1589 tracepoint_location
= container_of(location
,
1590 struct lttng_userspace_probe_location_tracepoint
, parent
);
1591 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1592 fd_handle_get(binary_fd
);
1593 tracepoint_location
->binary_fd_handle
= binary_fd
;
1598 int lttng_userspace_probe_location_function_flatten(
1599 const struct lttng_userspace_probe_location
*location
,
1600 struct lttng_dynamic_buffer
*buffer
)
1602 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1603 struct lttng_userspace_probe_location_function
*probe_function
;
1604 struct lttng_userspace_probe_location_function flat_probe
;
1605 size_t function_name_len
, binary_path_len
;
1606 size_t padding_needed
= 0;
1607 char *flat_probe_start
;
1608 int storage_needed
= 0;
1611 LTTNG_ASSERT(location
);
1613 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1614 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1615 ret
= -LTTNG_ERR_INVALID
;
1619 probe_function
= container_of(location
,
1620 struct lttng_userspace_probe_location_function
,
1622 LTTNG_ASSERT(probe_function
->function_name
);
1623 LTTNG_ASSERT(probe_function
->binary_path
);
1626 sizeof(struct lttng_userspace_probe_location_function
);
1627 function_name_len
= strlen(probe_function
->function_name
) + 1;
1628 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1629 storage_needed
+= function_name_len
+ binary_path_len
;
1632 * The lookup method is aligned to 64-bit within the buffer.
1633 * This is needed even if there is no lookup method since
1634 * the next structure in the buffer probably needs to be
1635 * aligned too (depending on the arch).
1637 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1638 storage_needed
+= padding_needed
;
1640 if (location
->lookup_method
) {
1641 /* NOTE: elf look-up method is assumed here. */
1642 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1646 ret
= storage_needed
;
1650 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1651 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1652 buffer
->size
+ storage_needed
);
1658 memset(&flat_probe
, 0, sizeof(flat_probe
));
1660 flat_probe_start
= buffer
->data
+ buffer
->size
;
1661 flat_probe
.parent
.type
= location
->type
;
1663 * The lookup method, if present, is the last element in the flat
1664 * representation of the probe.
1666 if (location
->lookup_method
) {
1667 flat_probe
.parent
.lookup_method
=
1668 (struct lttng_userspace_probe_location_lookup_method
*)
1669 (flat_probe_start
+ sizeof(flat_probe
) +
1670 function_name_len
+ binary_path_len
+ padding_needed
);
1672 flat_probe
.parent
.lookup_method
= NULL
;
1675 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1676 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1677 flat_probe
.binary_fd_handle
= NULL
;
1678 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1679 sizeof(flat_probe
));
1684 ret
= lttng_dynamic_buffer_append(buffer
,
1685 probe_function
->function_name
, function_name_len
);
1689 ret
= lttng_dynamic_buffer_append(buffer
,
1690 probe_function
->binary_path
, binary_path_len
);
1695 /* Insert padding before the lookup method. */
1696 ret
= lttng_dynamic_buffer_set_size(buffer
,
1697 buffer
->size
+ padding_needed
);
1702 if (!location
->lookup_method
) {
1703 /* Not an error, the default method is used. */
1704 ret
= storage_needed
;
1708 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1709 flat_lookup_method
.parent
.type
=
1710 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1711 ret
= lttng_dynamic_buffer_append(buffer
,
1712 &flat_lookup_method
, sizeof(flat_lookup_method
));
1716 ret
= storage_needed
;
1722 int lttng_userspace_probe_location_tracepoint_flatten(
1723 const struct lttng_userspace_probe_location
*location
,
1724 struct lttng_dynamic_buffer
*buffer
)
1726 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1727 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1728 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1729 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1730 size_t padding_needed
= 0;
1731 int storage_needed
= 0;
1732 char *flat_probe_start
;
1735 LTTNG_ASSERT(location
);
1737 /* Only SDT tracepoints are supported at the moment */
1738 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1739 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1740 ret
= -LTTNG_ERR_INVALID
;
1743 probe_tracepoint
= container_of(location
,
1744 struct lttng_userspace_probe_location_tracepoint
,
1746 LTTNG_ASSERT(probe_tracepoint
->probe_name
);
1747 LTTNG_ASSERT(probe_tracepoint
->provider_name
);
1748 LTTNG_ASSERT(probe_tracepoint
->binary_path
);
1750 /* Compute the storage space needed to flatten the probe location */
1751 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1753 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1754 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1755 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1757 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1760 * The lookup method is aligned to 64-bit within the buffer.
1761 * This is needed even if there is no lookup method since
1762 * the next structure in the buffer probably needs to be
1763 * aligned too (depending on the arch).
1765 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1766 storage_needed
+= padding_needed
;
1768 if (location
->lookup_method
) {
1769 /* NOTE: elf look-up method is assumed here. */
1771 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1775 * If the caller set buffer to NULL, return the size of the needed buffer.
1778 ret
= storage_needed
;
1782 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1783 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1784 buffer
->size
+ storage_needed
);
1790 memset(&flat_probe
, 0, sizeof(flat_probe
));
1792 flat_probe_start
= buffer
->data
+ buffer
->size
;
1793 flat_probe
.parent
.type
= location
->type
;
1796 * The lookup method, if present, is the last element in the flat
1797 * representation of the probe.
1799 if (location
->lookup_method
) {
1800 flat_probe
.parent
.lookup_method
=
1801 (struct lttng_userspace_probe_location_lookup_method
*)
1802 (flat_probe_start
+ sizeof(flat_probe
) +
1803 probe_name_len
+ provider_name_len
+
1804 binary_path_len
+ padding_needed
);
1806 flat_probe
.parent
.lookup_method
= NULL
;
1809 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1810 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1811 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1812 flat_probe
.binary_fd_handle
= NULL
;
1813 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1818 /* Append all the fields to the buffer */
1819 ret
= lttng_dynamic_buffer_append(buffer
,
1820 probe_tracepoint
->probe_name
, probe_name_len
);
1824 ret
= lttng_dynamic_buffer_append(buffer
,
1825 probe_tracepoint
->provider_name
, provider_name_len
);
1829 ret
= lttng_dynamic_buffer_append(buffer
,
1830 probe_tracepoint
->binary_path
, binary_path_len
);
1835 /* Insert padding before the lookup method. */
1836 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1841 if (!location
->lookup_method
) {
1842 /* Not an error, the default method is used. */
1843 ret
= storage_needed
;
1847 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1849 flat_lookup_method
.parent
.type
=
1850 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1851 ret
= lttng_dynamic_buffer_append(buffer
,
1852 &flat_lookup_method
, sizeof(flat_lookup_method
));
1856 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
;
1888 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1889 const struct lttng_userspace_probe_location
*location
)
1891 struct lttng_userspace_probe_location
*new_location
= NULL
;
1892 enum lttng_userspace_probe_location_type type
;
1898 type
= lttng_userspace_probe_location_get_type(location
);
1900 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1902 lttng_userspace_probe_location_function_copy(location
);
1903 if (!new_location
) {
1907 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1909 lttng_userspace_probe_location_tracepoint_copy(location
);
1910 if (!new_location
) {
1915 new_location
= NULL
;
1919 return new_location
;
1922 bool lttng_userspace_probe_location_lookup_method_is_equal(
1923 const struct lttng_userspace_probe_location_lookup_method
*a
,
1924 const struct lttng_userspace_probe_location_lookup_method
*b
)
1926 bool is_equal
= false;
1937 if (a
->type
!= b
->type
) {
1946 bool lttng_userspace_probe_location_is_equal(
1947 const struct lttng_userspace_probe_location
*a
,
1948 const struct lttng_userspace_probe_location
*b
)
1950 bool is_equal
= false;
1961 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1962 a
->lookup_method
, b
->lookup_method
)) {
1966 if (a
->type
!= b
->type
) {
1970 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1975 unsigned long lttng_userspace_probe_location_hash(
1976 const struct lttng_userspace_probe_location
*location
)
1978 return location
->hash(location
);
1981 enum lttng_error_code
lttng_userspace_probe_location_mi_serialize(
1982 const struct lttng_userspace_probe_location
*location
,
1983 struct mi_writer
*writer
)
1985 typedef enum lttng_error_code (*mi_fp
)(
1986 const struct lttng_userspace_probe_location
*,
1987 struct mi_writer
*);
1990 enum lttng_error_code ret_code
;
1991 mi_fp mi_function
= NULL
;
1993 LTTNG_ASSERT(location
);
1994 LTTNG_ASSERT(writer
);
1996 switch (lttng_userspace_probe_location_get_type(location
)) {
1997 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1998 mi_function
= lttng_userspace_probe_location_function_mi_serialize
;
2000 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
2001 mi_function
= lttng_userspace_probe_location_tracepoint_mi_serialize
;
2008 /* Open userspace probe location element. */
2009 ret
= mi_lttng_writer_open_element(
2010 writer
, mi_lttng_element_userspace_probe_location
);
2015 /* Underlying user space probe location. */
2016 ret_code
= mi_function(location
, writer
);
2017 if (ret_code
!= LTTNG_OK
) {
2021 /* Close userspace probe location element. */
2022 ret
= mi_lttng_writer_close_element(writer
);
2027 ret_code
= LTTNG_OK
;
2031 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2036 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
2037 const struct lttng_userspace_probe_location_lookup_method
2039 struct mi_writer
*writer
)
2042 enum lttng_error_code ret_code
;
2043 const char *type_element_str
;
2045 LTTNG_ASSERT(method
);
2046 LTTNG_ASSERT(writer
);
2048 switch (lttng_userspace_probe_location_lookup_method_get_type(method
)) {
2049 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
2051 mi_lttng_element_userspace_probe_location_lookup_method_function_default
;
2053 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
2055 mi_lttng_element_userspace_probe_location_lookup_method_function_elf
;
2057 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
2059 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt
;
2066 /* Open userspace probe location lookup method element. */
2067 ret
= mi_lttng_writer_open_element(writer
,
2068 mi_lttng_element_userspace_probe_location_lookup_method
);
2073 /* User space probe location lookup method empty element. */
2074 ret
= mi_lttng_writer_open_element(writer
, type_element_str
);
2079 /* Close userspace probe location lookup method element. */
2080 ret
= mi_lttng_close_multi_element(writer
, 2);
2085 ret_code
= LTTNG_OK
;
2089 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2094 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
2095 const struct lttng_userspace_probe_location
*location
,
2096 struct mi_writer
*writer
)
2099 enum lttng_error_code ret_code
;
2100 const char *probe_name
= NULL
;
2101 const char *provider_name
= NULL
;
2102 const char *binary_path
= NULL
;
2103 const struct lttng_userspace_probe_location_lookup_method
2104 *lookup_method
= NULL
;
2106 LTTNG_ASSERT(location
);
2107 LTTNG_ASSERT(writer
);
2109 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(
2111 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(
2113 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(
2115 lookup_method
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
2118 /* Open userspace probe location tracepoint element. */
2119 ret
= mi_lttng_writer_open_element(writer
,
2120 mi_lttng_element_userspace_probe_location_tracepoint
);
2126 ret
= mi_lttng_writer_write_element_string(writer
,
2127 mi_lttng_element_userspace_probe_location_tracepoint_probe_name
,
2133 /* Provider name. */
2134 ret
= mi_lttng_writer_write_element_string(writer
,
2135 mi_lttng_element_userspace_probe_location_tracepoint_provider_name
,
2142 ret
= mi_lttng_writer_write_element_string(writer
,
2143 mi_lttng_element_userspace_probe_location_binary_path
,
2149 /* The lookup method. */
2150 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2151 lookup_method
, writer
);
2152 if (ret_code
!= LTTNG_OK
) {
2156 /* Close userspace probe location tracepoint. */
2157 ret
= mi_lttng_writer_close_element(writer
);
2162 ret_code
= LTTNG_OK
;
2166 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2171 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
2172 const struct lttng_userspace_probe_location
*location
,
2173 struct mi_writer
*writer
)
2176 enum lttng_error_code ret_code
;
2177 const char *function_name
= NULL
;
2178 const char *binary_path
= NULL
;
2179 const char *instrumentation_type_str
= NULL
;
2180 enum lttng_userspace_probe_location_function_instrumentation_type
2181 instrumentation_type
;
2182 const struct lttng_userspace_probe_location_lookup_method
2183 *lookup_method
= NULL
;
2185 LTTNG_ASSERT(location
);
2186 LTTNG_ASSERT(writer
);
2188 function_name
= lttng_userspace_probe_location_function_get_function_name(
2190 binary_path
= lttng_userspace_probe_location_function_get_binary_path(
2192 instrumentation_type
=
2193 lttng_userspace_probe_location_function_get_instrumentation_type(
2195 lookup_method
= lttng_userspace_probe_location_function_get_lookup_method(
2198 switch (instrumentation_type
) {
2199 case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
:
2200 instrumentation_type_str
=
2201 mi_lttng_userspace_probe_location_function_instrumentation_type_entry
;
2208 /* Open userspace probe location function element. */
2209 ret
= mi_lttng_writer_open_element(writer
,
2210 mi_lttng_element_userspace_probe_location_function
);
2215 /* Function name. */
2216 ret
= mi_lttng_writer_write_element_string(writer
,
2217 mi_lttng_element_userspace_probe_location_function_name
,
2224 ret
= mi_lttng_writer_write_element_string(writer
,
2225 mi_lttng_element_userspace_probe_location_binary_path
,
2231 /* Instrumentation type. */
2232 ret
= mi_lttng_writer_write_element_string(writer
,
2233 mi_lttng_element_userspace_probe_location_function_instrumentation_type
,
2234 instrumentation_type_str
);
2239 /* The lookup method. */
2240 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2241 lookup_method
, writer
);
2242 if (ret_code
!= LTTNG_OK
) {
2246 /* Close userspace probe location function element. */
2247 ret
= mi_lttng_writer_close_element(writer
);
2252 ret_code
= LTTNG_OK
;
2256 ret_code
= LTTNG_ERR_MI_IO_FAIL
;