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.hpp>
10 #include <common/align.hpp>
11 #include <common/error.hpp>
12 #include <common/hashtable/hashtable.hpp>
13 #include <common/hashtable/utils.hpp>
14 #include <common/macros.hpp>
15 #include <common/mi-lttng.hpp>
16 #include <common/payload-view.hpp>
17 #include <common/payload.hpp>
19 #include <lttng/constant.h>
20 #include <lttng/userspace-probe-internal.hpp>
22 #include <sys/types.h>
26 int lttng_userspace_probe_location_function_set_binary_fd_handle(
27 struct lttng_userspace_probe_location
*location
,
28 struct fd_handle
*binary_fd_handle
);
31 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
32 struct lttng_userspace_probe_location
*location
,
33 struct fd_handle
*binary_fd_handle
);
36 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
37 const struct lttng_userspace_probe_location_lookup_method
39 struct mi_writer
*writer
);
42 enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
43 const struct lttng_userspace_probe_location
*location
,
44 struct mi_writer
*writer
);
47 enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
48 const struct lttng_userspace_probe_location
*location
,
49 struct mi_writer
*writer
);
51 enum lttng_userspace_probe_location_lookup_method_type
52 lttng_userspace_probe_location_lookup_method_get_type(
53 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
55 return lookup_method
? lookup_method
->type
:
56 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
59 void lttng_userspace_probe_location_lookup_method_destroy(
60 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
69 struct lttng_userspace_probe_location_lookup_method
*
70 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
72 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
73 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
75 elf_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_elf
>();
81 ret
= &elf_method
->parent
;
82 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
87 struct lttng_userspace_probe_location_lookup_method
*
88 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
90 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
91 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
93 sdt_method
= zmalloc
<lttng_userspace_probe_location_lookup_method_sdt
>();
99 ret
= &sdt_method
->parent
;
100 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
105 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
106 const struct lttng_userspace_probe_location
*location
)
108 return location
? location
->type
:
109 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
113 void lttng_userspace_probe_location_function_destroy(
114 struct lttng_userspace_probe_location
*location
)
116 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
118 LTTNG_ASSERT(location
);
120 location_function
= lttng::utils::container_of(location
,
121 <tng_userspace_probe_location_function::parent
);
123 LTTNG_ASSERT(location_function
);
125 free(location_function
->function_name
);
126 free(location_function
->binary_path
);
127 fd_handle_put(location_function
->binary_fd_handle
);
132 void lttng_userspace_probe_location_tracepoint_destroy(
133 struct lttng_userspace_probe_location
*location
)
135 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
137 LTTNG_ASSERT(location
);
139 location_tracepoint
= lttng::utils::container_of(location
,
140 <tng_userspace_probe_location_tracepoint::parent
);
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 lttng::utils::container_of(
228 location
, <tng_userspace_probe_location_function::parent
);
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
= lttng::utils::container_of(_a
,
247 <tng_userspace_probe_location_function::parent
);
248 b
= lttng::utils::container_of(_b
,
249 <tng_userspace_probe_location_function::parent
);
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
<lttng_userspace_probe_location_function
>();
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
= lttng::utils::container_of(
353 location
, <tng_userspace_probe_location_tracepoint::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
= lttng::utils::container_of(_a
,
373 <tng_userspace_probe_location_tracepoint::parent
);
374 b
= lttng::utils::container_of(_b
,
375 <tng_userspace_probe_location_tracepoint::parent
);
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
<lttng_userspace_probe_location_tracepoint
>();
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
<lttng_userspace_probe_location_lookup_method_elf
>();
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
<lttng_userspace_probe_location_lookup_method_sdt
>();
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
= lttng::utils::container_of(
607 location
, <tng_userspace_probe_location_function::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
= lttng::utils::container_of(
681 location
, <tng_userspace_probe_location_tracepoint::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
= lttng::utils::container_of(location
,
759 <tng_userspace_probe_location_function::parent
);
760 ret
= function_location
->binary_path
;
765 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
766 const struct lttng_userspace_probe_location
*location
)
768 const char *ret
= NULL
;
769 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
771 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
772 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
773 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
777 tracepoint_location
= lttng::utils::container_of(location
,
778 <tng_userspace_probe_location_tracepoint::parent
);
779 ret
= tracepoint_location
->binary_path
;
784 const char *lttng_userspace_probe_location_function_get_function_name(
785 const struct lttng_userspace_probe_location
*location
)
787 const char *ret
= NULL
;
788 struct lttng_userspace_probe_location_function
*function_location
;
790 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
791 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
792 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
796 function_location
= lttng::utils::container_of(location
,
797 <tng_userspace_probe_location_function::parent
);
798 ret
= function_location
->function_name
;
803 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
804 const struct lttng_userspace_probe_location
*location
)
806 const char *ret
= NULL
;
807 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
809 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
810 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
811 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
815 tracepoint_location
= lttng::utils::container_of(location
,
816 <tng_userspace_probe_location_tracepoint::parent
);
817 ret
= tracepoint_location
->probe_name
;
822 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
823 const struct lttng_userspace_probe_location
*location
)
825 const char *ret
= NULL
;
826 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
828 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
829 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
830 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
834 tracepoint_location
= lttng::utils::container_of(location
,
835 <tng_userspace_probe_location_tracepoint::parent
);
836 ret
= tracepoint_location
->provider_name
;
841 int lttng_userspace_probe_location_function_get_binary_fd(
842 const struct lttng_userspace_probe_location
*location
)
845 struct lttng_userspace_probe_location_function
*function_location
;
847 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
848 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
849 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
853 function_location
= lttng::utils::container_of(location
,
854 <tng_userspace_probe_location_function::parent
);
855 ret
= function_location
->binary_fd_handle
?
856 fd_handle_get_fd(function_location
->binary_fd_handle
) : -1;
861 enum lttng_userspace_probe_location_function_instrumentation_type
862 lttng_userspace_probe_location_function_get_instrumentation_type(
863 const struct lttng_userspace_probe_location
*location
)
865 enum lttng_userspace_probe_location_function_instrumentation_type type
;
866 struct lttng_userspace_probe_location_function
*function_location
;
868 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
869 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
870 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
871 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
875 function_location
= lttng::utils::container_of(location
,
876 <tng_userspace_probe_location_function::parent
);
877 type
= function_location
->instrumentation_type
;
882 enum lttng_userspace_probe_location_status
883 lttng_userspace_probe_location_function_set_instrumentation_type(
884 const struct lttng_userspace_probe_location
*location
,
885 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
887 enum lttng_userspace_probe_location_status status
=
888 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
889 struct lttng_userspace_probe_location_function
*function_location
;
891 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
892 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
893 instrumentation_type
!=
894 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
895 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
896 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
900 function_location
= lttng::utils::container_of(location
,
901 <tng_userspace_probe_location_function::parent
);
902 function_location
->instrumentation_type
= instrumentation_type
;
907 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
908 const struct lttng_userspace_probe_location
*location
)
911 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
913 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
914 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
915 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
919 tracepoint_location
= lttng::utils::container_of(location
,
920 <tng_userspace_probe_location_tracepoint::parent
);
921 ret
= tracepoint_location
->binary_fd_handle
?
922 fd_handle_get_fd(tracepoint_location
->binary_fd_handle
) : -1;
927 static struct lttng_userspace_probe_location_lookup_method
*
928 lttng_userspace_probe_location_function_get_lookup_method(
929 const struct lttng_userspace_probe_location
*location
)
931 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
933 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
934 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
935 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
939 ret
= location
->lookup_method
;
944 static struct lttng_userspace_probe_location_lookup_method
*
945 lttng_userspace_probe_location_tracepoint_get_lookup_method(
946 const struct lttng_userspace_probe_location
*location
)
948 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
950 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
951 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
952 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
956 ret
= location
->lookup_method
;
961 const struct lttng_userspace_probe_location_lookup_method
*
962 lttng_userspace_probe_location_get_lookup_method(
963 const struct lttng_userspace_probe_location
*location
)
965 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
967 LTTNG_ASSERT(location
);
968 switch (location
->type
) {
969 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
970 ret
= lttng_userspace_probe_location_function_get_lookup_method(
973 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
974 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
978 ERR("Unknowned lookup method.");
985 int lttng_userspace_probe_location_lookup_method_serialize(
986 struct lttng_userspace_probe_location_lookup_method
*method
,
987 struct lttng_payload
*payload
)
990 struct lttng_userspace_probe_location_lookup_method_comm
993 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
994 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
996 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &lookup_method_comm
,
997 sizeof(lookup_method_comm
));
1002 ret
= sizeof(lookup_method_comm
);
1008 int lttng_userspace_probe_location_function_serialize(
1009 const struct lttng_userspace_probe_location
*location
,
1010 struct lttng_payload
*payload
)
1013 size_t function_name_len
, binary_path_len
;
1014 struct lttng_userspace_probe_location_function
*location_function
;
1015 struct lttng_userspace_probe_location_function_comm location_function_comm
;
1017 LTTNG_ASSERT(location
);
1018 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1019 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1021 location_function
= lttng::utils::container_of(location
,
1022 <tng_userspace_probe_location_function::parent
);
1023 if (!location_function
->function_name
|| !location_function
->binary_path
) {
1024 ret
= -LTTNG_ERR_INVALID
;
1028 if (payload
&& !location_function
->binary_fd_handle
) {
1029 ret
= -LTTNG_ERR_INVALID
;
1033 function_name_len
= strlen(location_function
->function_name
);
1034 if (function_name_len
== 0) {
1035 ret
= -LTTNG_ERR_INVALID
;
1038 binary_path_len
= strlen(location_function
->binary_path
);
1039 if (binary_path_len
== 0) {
1040 ret
= -LTTNG_ERR_INVALID
;
1044 location_function_comm
.function_name_len
= function_name_len
+ 1;
1045 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
1048 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1049 &location_function_comm
,
1050 sizeof(location_function_comm
));
1052 ret
= -LTTNG_ERR_INVALID
;
1055 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1056 location_function
->function_name
,
1057 location_function_comm
.function_name_len
);
1059 ret
= -LTTNG_ERR_INVALID
;
1062 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1063 location_function
->binary_path
,
1064 location_function_comm
.binary_path_len
);
1066 ret
= -LTTNG_ERR_INVALID
;
1069 ret
= lttng_payload_push_fd_handle(
1070 payload
, location_function
->binary_fd_handle
);
1072 ret
= -LTTNG_ERR_INVALID
;
1076 ret
= sizeof(location_function_comm
) +
1077 location_function_comm
.function_name_len
+
1078 location_function_comm
.binary_path_len
;
1084 int lttng_userspace_probe_location_tracepoint_serialize(
1085 const struct lttng_userspace_probe_location
*location
,
1086 struct lttng_payload
*payload
)
1089 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1090 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
1091 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
1093 LTTNG_ASSERT(location
);
1094 LTTNG_ASSERT(lttng_userspace_probe_location_get_type(location
) ==
1095 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1097 location_tracepoint
= lttng::utils::container_of(location
,
1098 <tng_userspace_probe_location_tracepoint::parent
);
1099 if (!location_tracepoint
->probe_name
||
1100 !location_tracepoint
->provider_name
||
1101 !location_tracepoint
->binary_path
) {
1102 ret
= -LTTNG_ERR_INVALID
;
1106 if (payload
&& !location_tracepoint
->binary_fd_handle
) {
1107 ret
= -LTTNG_ERR_INVALID
;
1111 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1112 if (probe_name_len
== 0) {
1113 ret
= -LTTNG_ERR_INVALID
;
1117 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1118 if (provider_name_len
== 0) {
1119 ret
= -LTTNG_ERR_INVALID
;
1123 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1124 if (binary_path_len
== 0) {
1125 ret
= -LTTNG_ERR_INVALID
;
1129 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1130 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1131 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1134 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1135 &location_tracepoint_comm
,
1136 sizeof(location_tracepoint_comm
));
1138 ret
= -LTTNG_ERR_INVALID
;
1141 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1142 location_tracepoint
->probe_name
,
1143 location_tracepoint_comm
.probe_name_len
);
1145 ret
= -LTTNG_ERR_INVALID
;
1148 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1149 location_tracepoint
->provider_name
,
1150 location_tracepoint_comm
.provider_name_len
);
1152 ret
= -LTTNG_ERR_INVALID
;
1155 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1156 location_tracepoint
->binary_path
,
1157 location_tracepoint_comm
.binary_path_len
);
1159 ret
= -LTTNG_ERR_INVALID
;
1162 ret
= lttng_payload_push_fd_handle(
1163 payload
, location_tracepoint
->binary_fd_handle
);
1165 ret
= -LTTNG_ERR_INVALID
;
1170 ret
= sizeof(location_tracepoint_comm
) +
1171 location_tracepoint_comm
.probe_name_len
+
1172 location_tracepoint_comm
.provider_name_len
+
1173 location_tracepoint_comm
.binary_path_len
;
1178 int lttng_userspace_probe_location_serialize(
1179 const struct lttng_userspace_probe_location
*location
,
1180 struct lttng_payload
*payload
)
1182 int ret
, buffer_use
= 0;
1183 struct lttng_userspace_probe_location_comm location_generic_comm
;
1186 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__
);
1187 ret
= -LTTNG_ERR_INVALID
;
1191 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1193 location_generic_comm
.type
= (int8_t) location
->type
;
1195 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
1196 &location_generic_comm
,
1197 sizeof(location_generic_comm
));
1202 buffer_use
+= sizeof(location_generic_comm
);
1204 switch (lttng_userspace_probe_location_get_type(location
)) {
1205 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1206 ret
= lttng_userspace_probe_location_function_serialize(
1209 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1210 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1214 ERR("Unsupported probe location type");
1215 ret
= -LTTNG_ERR_INVALID
;
1223 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1224 location
->lookup_method
, payload
);
1234 int lttng_userspace_probe_location_function_create_from_payload(
1235 struct lttng_payload_view
*view
,
1236 struct lttng_userspace_probe_location
**location
)
1238 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1239 const char *function_name_src
, *binary_path_src
;
1240 char *function_name
= NULL
, *binary_path
= NULL
;
1242 size_t expected_size
;
1243 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1245 LTTNG_ASSERT(location
);
1247 if (view
->buffer
.size
< sizeof(*location_function_comm
)) {
1248 ret
= -LTTNG_ERR_INVALID
;
1252 location_function_comm
=
1253 (typeof(location_function_comm
)) view
->buffer
.data
;
1255 expected_size
= sizeof(*location_function_comm
) +
1256 location_function_comm
->function_name_len
+
1257 location_function_comm
->binary_path_len
;
1259 if (view
->buffer
.size
< expected_size
) {
1260 ret
= -LTTNG_ERR_INVALID
;
1264 function_name_src
= view
->buffer
.data
+ sizeof(*location_function_comm
);
1265 binary_path_src
= function_name_src
+
1266 location_function_comm
->function_name_len
;
1268 if (!lttng_buffer_view_contains_string(&view
->buffer
, function_name_src
,
1269 location_function_comm
->function_name_len
)) {
1270 ret
= -LTTNG_ERR_INVALID
;
1274 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1275 location_function_comm
->binary_path_len
)) {
1276 ret
= -LTTNG_ERR_INVALID
;
1280 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1281 if (!function_name
) {
1282 PERROR("lttng_strndup");
1283 ret
= -LTTNG_ERR_NOMEM
;
1287 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1289 PERROR("lttng_strndup");
1290 ret
= -LTTNG_ERR_NOMEM
;
1294 *location
= lttng_userspace_probe_location_function_create_no_check(
1295 binary_path
, function_name
, NULL
, false);
1297 ret
= -LTTNG_ERR_INVALID
;
1301 ret
= lttng_userspace_probe_location_function_set_binary_fd_handle(
1302 *location
, binary_fd_handle
);
1304 ret
= -LTTNG_ERR_INVALID
;
1308 ret
= (int) expected_size
;
1310 fd_handle_put(binary_fd_handle
);
1311 free(function_name
);
1317 int lttng_userspace_probe_location_tracepoint_create_from_payload(
1318 struct lttng_payload_view
*view
,
1319 struct lttng_userspace_probe_location
**location
)
1321 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1322 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1323 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1325 size_t expected_size
;
1326 struct fd_handle
*binary_fd_handle
= lttng_payload_view_pop_fd_handle(view
);
1328 LTTNG_ASSERT(location
);
1330 if (!binary_fd_handle
) {
1331 ret
= -LTTNG_ERR_INVALID
;
1335 if (view
->buffer
.size
< sizeof(*location_tracepoint_comm
)) {
1336 ret
= -LTTNG_ERR_INVALID
;
1340 location_tracepoint_comm
=
1341 (typeof(location_tracepoint_comm
)) view
->buffer
.data
;
1343 expected_size
= sizeof(*location_tracepoint_comm
) +
1344 location_tracepoint_comm
->probe_name_len
+
1345 location_tracepoint_comm
->provider_name_len
+
1346 location_tracepoint_comm
->binary_path_len
;
1348 if (view
->buffer
.size
< expected_size
) {
1349 ret
= -LTTNG_ERR_INVALID
;
1353 probe_name_src
= view
->buffer
.data
+ sizeof(*location_tracepoint_comm
);
1354 provider_name_src
= probe_name_src
+
1355 location_tracepoint_comm
->probe_name_len
;
1356 binary_path_src
= provider_name_src
+
1357 location_tracepoint_comm
->provider_name_len
;
1359 if (!lttng_buffer_view_contains_string(&view
->buffer
, probe_name_src
,
1360 location_tracepoint_comm
->probe_name_len
)) {
1361 ret
= -LTTNG_ERR_INVALID
;
1365 if (!lttng_buffer_view_contains_string(&view
->buffer
, provider_name_src
,
1366 location_tracepoint_comm
->provider_name_len
)) {
1367 ret
= -LTTNG_ERR_INVALID
;
1371 if (!lttng_buffer_view_contains_string(&view
->buffer
, binary_path_src
,
1372 location_tracepoint_comm
->binary_path_len
)) {
1373 ret
= -LTTNG_ERR_INVALID
;
1377 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1379 PERROR("Failed to allocate probe name");
1380 ret
= -LTTNG_ERR_INVALID
;
1383 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1384 if (!provider_name
) {
1385 PERROR("Failed to allocate provider name");
1386 ret
= -LTTNG_ERR_INVALID
;
1390 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1392 PERROR("Failed to allocate binary path");
1393 ret
= -LTTNG_ERR_INVALID
;
1397 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1398 binary_path
, provider_name
, probe_name
, NULL
, false);
1400 ret
= -LTTNG_ERR_INVALID
;
1404 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1405 *location
, binary_fd_handle
);
1407 ret
= -LTTNG_ERR_INVALID
;
1411 ret
= (int) expected_size
;
1413 fd_handle_put(binary_fd_handle
);
1415 free(provider_name
);
1421 int lttng_userspace_probe_location_lookup_method_create_from_payload(
1422 struct lttng_payload_view
*view
,
1423 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1426 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1427 enum lttng_userspace_probe_location_lookup_method_type type
;
1430 LTTNG_ASSERT(lookup_method
);
1432 if (view
->buffer
.size
< sizeof(*lookup_comm
)) {
1433 ret
= -LTTNG_ERR_INVALID
;
1437 lookup_comm
= (typeof(lookup_comm
)) view
->buffer
.data
;
1438 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1441 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1442 *lookup_method
= NULL
;
1444 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1446 lttng_userspace_probe_location_lookup_method_function_elf_create();
1447 if (!(*lookup_method
)) {
1448 ret
= -LTTNG_ERR_INVALID
;
1452 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1454 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1455 if (!(*lookup_method
)) {
1456 ret
= -LTTNG_ERR_INVALID
;
1461 ret
= -LTTNG_ERR_INVALID
;
1465 ret
= sizeof(*lookup_comm
);
1470 int lttng_userspace_probe_location_create_from_payload(
1471 struct lttng_payload_view
*view
,
1472 struct lttng_userspace_probe_location
**location
)
1474 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1475 enum lttng_userspace_probe_location_type type
;
1478 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1479 struct lttng_payload_view probe_location_comm_view
=
1480 lttng_payload_view_from_view(
1481 view
, 0, sizeof(*probe_location_comm
));
1484 LTTNG_ASSERT(location
);
1486 lookup_method
= NULL
;
1488 if (!lttng_payload_view_is_valid(&probe_location_comm_view
)) {
1489 ret
= -LTTNG_ERR_INVALID
;
1493 probe_location_comm
= (typeof(probe_location_comm
)) probe_location_comm_view
.buffer
.data
;
1494 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1495 consumed
+= sizeof(*probe_location_comm
);
1498 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1500 struct lttng_payload_view location_view
=
1501 lttng_payload_view_from_view(
1502 view
, consumed
, -1);
1504 ret
= lttng_userspace_probe_location_function_create_from_payload(
1505 &location_view
, location
);
1511 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1513 struct lttng_payload_view location_view
=
1514 lttng_payload_view_from_view(view
, consumed
, -1);
1516 ret
= lttng_userspace_probe_location_tracepoint_create_from_payload(
1517 &location_view
, location
);
1524 ret
= -LTTNG_ERR_INVALID
;
1529 if (view
->buffer
.size
<= consumed
) {
1530 ret
= -LTTNG_ERR_INVALID
;
1535 struct lttng_payload_view lookup_method_view
=
1536 lttng_payload_view_from_view(
1537 view
, consumed
, -1);
1539 ret
= lttng_userspace_probe_location_lookup_method_create_from_payload(
1540 &lookup_method_view
, &lookup_method
);
1543 ret
= -LTTNG_ERR_INVALID
;
1547 LTTNG_ASSERT(lookup_method
);
1548 (*location
)->lookup_method
= lookup_method
;
1549 lookup_method
= NULL
;
1556 int lttng_userspace_probe_location_function_set_binary_fd_handle(
1557 struct lttng_userspace_probe_location
*location
,
1558 struct fd_handle
*binary_fd
)
1561 struct lttng_userspace_probe_location_function
*function_location
;
1563 LTTNG_ASSERT(location
);
1564 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1566 function_location
= lttng::utils::container_of(location
,
1567 <tng_userspace_probe_location_function::parent
);
1568 fd_handle_put(function_location
->binary_fd_handle
);
1569 fd_handle_get(binary_fd
);
1570 function_location
->binary_fd_handle
= binary_fd
;
1575 int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1576 struct lttng_userspace_probe_location
*location
,
1577 struct fd_handle
*binary_fd
)
1580 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1582 LTTNG_ASSERT(location
);
1583 LTTNG_ASSERT(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1585 tracepoint_location
= lttng::utils::container_of(location
,
1586 <tng_userspace_probe_location_tracepoint::parent
);
1587 fd_handle_put(tracepoint_location
->binary_fd_handle
);
1588 fd_handle_get(binary_fd
);
1589 tracepoint_location
->binary_fd_handle
= binary_fd
;
1594 int lttng_userspace_probe_location_function_flatten(
1595 const struct lttng_userspace_probe_location
*location
,
1596 struct lttng_dynamic_buffer
*buffer
)
1598 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1599 struct lttng_userspace_probe_location_function
*probe_function
;
1600 struct lttng_userspace_probe_location_function flat_probe
;
1601 size_t function_name_len
, binary_path_len
;
1602 size_t padding_needed
= 0;
1603 char *flat_probe_start
;
1604 int storage_needed
= 0;
1607 LTTNG_ASSERT(location
);
1609 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1610 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1611 ret
= -LTTNG_ERR_INVALID
;
1615 probe_function
= lttng::utils::container_of(location
,
1616 <tng_userspace_probe_location_function::parent
);
1617 LTTNG_ASSERT(probe_function
->function_name
);
1618 LTTNG_ASSERT(probe_function
->binary_path
);
1621 sizeof(struct lttng_userspace_probe_location_function
);
1622 function_name_len
= strlen(probe_function
->function_name
) + 1;
1623 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1624 storage_needed
+= function_name_len
+ binary_path_len
;
1627 * The lookup method is aligned to 64-bit within the buffer.
1628 * This is needed even if there is no lookup method since
1629 * the next structure in the buffer probably needs to be
1630 * aligned too (depending on the arch).
1632 padding_needed
= lttng_align_ceil(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1633 storage_needed
+= padding_needed
;
1635 if (location
->lookup_method
) {
1636 /* NOTE: elf look-up method is assumed here. */
1637 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1641 ret
= storage_needed
;
1645 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1646 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1647 buffer
->size
+ storage_needed
);
1653 memset(&flat_probe
, 0, sizeof(flat_probe
));
1655 flat_probe_start
= buffer
->data
+ buffer
->size
;
1656 flat_probe
.parent
.type
= location
->type
;
1658 * The lookup method, if present, is the last element in the flat
1659 * representation of the probe.
1661 if (location
->lookup_method
) {
1662 flat_probe
.parent
.lookup_method
=
1663 (struct lttng_userspace_probe_location_lookup_method
*)
1664 (flat_probe_start
+ sizeof(flat_probe
) +
1665 function_name_len
+ binary_path_len
+ padding_needed
);
1667 flat_probe
.parent
.lookup_method
= NULL
;
1670 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1671 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1672 flat_probe
.binary_fd_handle
= NULL
;
1673 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1674 sizeof(flat_probe
));
1679 ret
= lttng_dynamic_buffer_append(buffer
,
1680 probe_function
->function_name
, function_name_len
);
1684 ret
= lttng_dynamic_buffer_append(buffer
,
1685 probe_function
->binary_path
, binary_path_len
);
1690 /* Insert padding before the lookup method. */
1691 ret
= lttng_dynamic_buffer_set_size(buffer
,
1692 buffer
->size
+ padding_needed
);
1697 if (!location
->lookup_method
) {
1698 /* Not an error, the default method is used. */
1699 ret
= storage_needed
;
1703 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1704 flat_lookup_method
.parent
.type
=
1705 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1706 ret
= lttng_dynamic_buffer_append(buffer
,
1707 &flat_lookup_method
, sizeof(flat_lookup_method
));
1711 ret
= storage_needed
;
1717 int lttng_userspace_probe_location_tracepoint_flatten(
1718 const struct lttng_userspace_probe_location
*location
,
1719 struct lttng_dynamic_buffer
*buffer
)
1721 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1722 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1723 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1724 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1725 size_t padding_needed
= 0;
1726 int storage_needed
= 0;
1727 char *flat_probe_start
;
1730 LTTNG_ASSERT(location
);
1732 /* Only SDT tracepoints are supported at the moment */
1733 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1734 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1735 ret
= -LTTNG_ERR_INVALID
;
1738 probe_tracepoint
= lttng::utils::container_of(location
,
1739 <tng_userspace_probe_location_tracepoint::parent
);
1740 LTTNG_ASSERT(probe_tracepoint
->probe_name
);
1741 LTTNG_ASSERT(probe_tracepoint
->provider_name
);
1742 LTTNG_ASSERT(probe_tracepoint
->binary_path
);
1744 /* Compute the storage space needed to flatten the probe location */
1745 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1747 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1748 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1749 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1751 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1754 * The lookup method is aligned to 64-bit within the buffer.
1755 * This is needed even if there is no lookup method since
1756 * the next structure in the buffer probably needs to be
1757 * aligned too (depending on the arch).
1759 padding_needed
= lttng_align_ceil(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1760 storage_needed
+= padding_needed
;
1762 if (location
->lookup_method
) {
1763 /* NOTE: elf look-up method is assumed here. */
1765 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1769 * If the caller set buffer to NULL, return the size of the needed buffer.
1772 ret
= storage_needed
;
1776 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1777 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1778 buffer
->size
+ storage_needed
);
1784 memset(&flat_probe
, 0, sizeof(flat_probe
));
1786 flat_probe_start
= buffer
->data
+ buffer
->size
;
1787 flat_probe
.parent
.type
= location
->type
;
1790 * The lookup method, if present, is the last element in the flat
1791 * representation of the probe.
1793 if (location
->lookup_method
) {
1794 flat_probe
.parent
.lookup_method
=
1795 (struct lttng_userspace_probe_location_lookup_method
*)
1796 (flat_probe_start
+ sizeof(flat_probe
) +
1797 probe_name_len
+ provider_name_len
+
1798 binary_path_len
+ padding_needed
);
1800 flat_probe
.parent
.lookup_method
= NULL
;
1803 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1804 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1805 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1806 flat_probe
.binary_fd_handle
= NULL
;
1807 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1812 /* Append all the fields to the buffer */
1813 ret
= lttng_dynamic_buffer_append(buffer
,
1814 probe_tracepoint
->probe_name
, probe_name_len
);
1818 ret
= lttng_dynamic_buffer_append(buffer
,
1819 probe_tracepoint
->provider_name
, provider_name_len
);
1823 ret
= lttng_dynamic_buffer_append(buffer
,
1824 probe_tracepoint
->binary_path
, binary_path_len
);
1829 /* Insert padding before the lookup method. */
1830 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1835 if (!location
->lookup_method
) {
1836 /* Not an error, the default method is used. */
1837 ret
= storage_needed
;
1841 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1843 flat_lookup_method
.parent
.type
=
1844 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1845 ret
= lttng_dynamic_buffer_append(buffer
,
1846 &flat_lookup_method
, sizeof(flat_lookup_method
));
1850 ret
= storage_needed
;
1855 int lttng_userspace_probe_location_flatten(
1856 const struct lttng_userspace_probe_location
*location
,
1857 struct lttng_dynamic_buffer
*buffer
)
1861 ret
= -LTTNG_ERR_INVALID
;
1865 /* Only types currently supported. */
1866 switch (location
->type
) {
1867 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1868 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1870 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1871 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1874 ret
= -LTTNG_ERR_INVALID
;
1882 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1883 const struct lttng_userspace_probe_location
*location
)
1885 struct lttng_userspace_probe_location
*new_location
= NULL
;
1886 enum lttng_userspace_probe_location_type type
;
1892 type
= lttng_userspace_probe_location_get_type(location
);
1894 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1896 lttng_userspace_probe_location_function_copy(location
);
1897 if (!new_location
) {
1901 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1903 lttng_userspace_probe_location_tracepoint_copy(location
);
1904 if (!new_location
) {
1909 new_location
= NULL
;
1913 return new_location
;
1916 bool lttng_userspace_probe_location_lookup_method_is_equal(
1917 const struct lttng_userspace_probe_location_lookup_method
*a
,
1918 const struct lttng_userspace_probe_location_lookup_method
*b
)
1920 bool is_equal
= false;
1931 if (a
->type
!= b
->type
) {
1940 bool lttng_userspace_probe_location_is_equal(
1941 const struct lttng_userspace_probe_location
*a
,
1942 const struct lttng_userspace_probe_location
*b
)
1944 bool is_equal
= false;
1955 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1956 a
->lookup_method
, b
->lookup_method
)) {
1960 if (a
->type
!= b
->type
) {
1964 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1969 unsigned long lttng_userspace_probe_location_hash(
1970 const struct lttng_userspace_probe_location
*location
)
1972 return location
->hash(location
);
1975 enum lttng_error_code
lttng_userspace_probe_location_mi_serialize(
1976 const struct lttng_userspace_probe_location
*location
,
1977 struct mi_writer
*writer
)
1979 typedef enum lttng_error_code (*mi_fp
)(
1980 const struct lttng_userspace_probe_location
*,
1981 struct mi_writer
*);
1984 enum lttng_error_code ret_code
;
1985 mi_fp mi_function
= NULL
;
1987 LTTNG_ASSERT(location
);
1988 LTTNG_ASSERT(writer
);
1990 switch (lttng_userspace_probe_location_get_type(location
)) {
1991 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1992 mi_function
= lttng_userspace_probe_location_function_mi_serialize
;
1994 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1995 mi_function
= lttng_userspace_probe_location_tracepoint_mi_serialize
;
2002 /* Open userspace probe location element. */
2003 ret
= mi_lttng_writer_open_element(
2004 writer
, mi_lttng_element_userspace_probe_location
);
2009 /* Underlying user space probe location. */
2010 ret_code
= mi_function(location
, writer
);
2011 if (ret_code
!= LTTNG_OK
) {
2015 /* Close userspace probe location element. */
2016 ret
= mi_lttng_writer_close_element(writer
);
2021 ret_code
= LTTNG_OK
;
2025 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2030 enum lttng_error_code
lttng_userspace_probe_location_lookup_method_mi_serialize(
2031 const struct lttng_userspace_probe_location_lookup_method
2033 struct mi_writer
*writer
)
2036 enum lttng_error_code ret_code
;
2037 const char *type_element_str
;
2039 LTTNG_ASSERT(method
);
2040 LTTNG_ASSERT(writer
);
2042 switch (lttng_userspace_probe_location_lookup_method_get_type(method
)) {
2043 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
2045 mi_lttng_element_userspace_probe_location_lookup_method_function_default
;
2047 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
2049 mi_lttng_element_userspace_probe_location_lookup_method_function_elf
;
2051 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
2053 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt
;
2060 /* Open userspace probe location lookup method element. */
2061 ret
= mi_lttng_writer_open_element(writer
,
2062 mi_lttng_element_userspace_probe_location_lookup_method
);
2067 /* User space probe location lookup method empty element. */
2068 ret
= mi_lttng_writer_open_element(writer
, type_element_str
);
2073 /* Close userspace probe location lookup method element. */
2074 ret
= mi_lttng_close_multi_element(writer
, 2);
2079 ret_code
= LTTNG_OK
;
2083 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2088 static enum lttng_error_code
lttng_userspace_probe_location_tracepoint_mi_serialize(
2089 const struct lttng_userspace_probe_location
*location
,
2090 struct mi_writer
*writer
)
2093 enum lttng_error_code ret_code
;
2094 const char *probe_name
= NULL
;
2095 const char *provider_name
= NULL
;
2096 const char *binary_path
= NULL
;
2097 const struct lttng_userspace_probe_location_lookup_method
2098 *lookup_method
= NULL
;
2100 LTTNG_ASSERT(location
);
2101 LTTNG_ASSERT(writer
);
2103 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(
2105 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(
2107 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(
2109 lookup_method
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
2112 /* Open userspace probe location tracepoint element. */
2113 ret
= mi_lttng_writer_open_element(writer
,
2114 mi_lttng_element_userspace_probe_location_tracepoint
);
2120 ret
= mi_lttng_writer_write_element_string(writer
,
2121 mi_lttng_element_userspace_probe_location_tracepoint_probe_name
,
2127 /* Provider name. */
2128 ret
= mi_lttng_writer_write_element_string(writer
,
2129 mi_lttng_element_userspace_probe_location_tracepoint_provider_name
,
2136 ret
= mi_lttng_writer_write_element_string(writer
,
2137 mi_lttng_element_userspace_probe_location_binary_path
,
2143 /* The lookup method. */
2144 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2145 lookup_method
, writer
);
2146 if (ret_code
!= LTTNG_OK
) {
2150 /* Close userspace probe location tracepoint. */
2151 ret
= mi_lttng_writer_close_element(writer
);
2156 ret_code
= LTTNG_OK
;
2160 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
2165 static enum lttng_error_code
lttng_userspace_probe_location_function_mi_serialize(
2166 const struct lttng_userspace_probe_location
*location
,
2167 struct mi_writer
*writer
)
2170 enum lttng_error_code ret_code
;
2171 const char *function_name
= NULL
;
2172 const char *binary_path
= NULL
;
2173 const char *instrumentation_type_str
= NULL
;
2174 enum lttng_userspace_probe_location_function_instrumentation_type
2175 instrumentation_type
;
2176 const struct lttng_userspace_probe_location_lookup_method
2177 *lookup_method
= NULL
;
2179 LTTNG_ASSERT(location
);
2180 LTTNG_ASSERT(writer
);
2182 function_name
= lttng_userspace_probe_location_function_get_function_name(
2184 binary_path
= lttng_userspace_probe_location_function_get_binary_path(
2186 instrumentation_type
=
2187 lttng_userspace_probe_location_function_get_instrumentation_type(
2189 lookup_method
= lttng_userspace_probe_location_function_get_lookup_method(
2192 switch (instrumentation_type
) {
2193 case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
:
2194 instrumentation_type_str
=
2195 mi_lttng_userspace_probe_location_function_instrumentation_type_entry
;
2202 /* Open userspace probe location function element. */
2203 ret
= mi_lttng_writer_open_element(writer
,
2204 mi_lttng_element_userspace_probe_location_function
);
2209 /* Function name. */
2210 ret
= mi_lttng_writer_write_element_string(writer
,
2211 mi_lttng_element_userspace_probe_location_function_name
,
2218 ret
= mi_lttng_writer_write_element_string(writer
,
2219 mi_lttng_element_userspace_probe_location_binary_path
,
2225 /* Instrumentation type. */
2226 ret
= mi_lttng_writer_write_element_string(writer
,
2227 mi_lttng_element_userspace_probe_location_function_instrumentation_type
,
2228 instrumentation_type_str
);
2233 /* The lookup method. */
2234 ret_code
= lttng_userspace_probe_location_lookup_method_mi_serialize(
2235 lookup_method
, writer
);
2236 if (ret_code
!= LTTNG_OK
) {
2240 /* Close userspace probe location function element. */
2241 ret
= mi_lttng_writer_close_element(writer
);
2246 ret_code
= LTTNG_OK
;
2250 ret_code
= LTTNG_ERR_MI_IO_FAIL
;