2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/error.h>
10 #include <common/macros.h>
11 #include <common/compat/string.h>
13 #include <lttng/constant.h>
14 #include <lttng/userspace-probe-internal.h>
16 enum lttng_userspace_probe_location_lookup_method_type
17 lttng_userspace_probe_location_lookup_method_get_type(
18 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
20 return lookup_method
? lookup_method
->type
:
21 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
24 void lttng_userspace_probe_location_lookup_method_destroy(
25 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
34 struct lttng_userspace_probe_location_lookup_method
*
35 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
37 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
38 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
40 elf_method
= zmalloc(sizeof(*elf_method
));
46 ret
= &elf_method
->parent
;
47 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
52 struct lttng_userspace_probe_location_lookup_method
*
53 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
55 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
56 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
58 sdt_method
= zmalloc(sizeof(*sdt_method
));
64 ret
= &sdt_method
->parent
;
65 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
70 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
71 const struct lttng_userspace_probe_location
*location
)
73 return location
? location
->type
:
74 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
78 void lttng_userspace_probe_location_function_destroy(
79 struct lttng_userspace_probe_location
*location
)
81 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
85 location_function
= container_of(location
,
86 struct lttng_userspace_probe_location_function
, parent
);
88 assert(location_function
);
90 free(location_function
->function_name
);
91 free(location_function
->binary_path
);
92 if (location_function
->binary_fd
>= 0) {
93 if (close(location_function
->binary_fd
)) {
101 void lttng_userspace_probe_location_tracepoint_destroy(
102 struct lttng_userspace_probe_location
*location
)
104 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
108 location_tracepoint
= container_of(location
,
109 struct lttng_userspace_probe_location_tracepoint
,
112 assert(location_tracepoint
);
114 free(location_tracepoint
->probe_name
);
115 free(location_tracepoint
->provider_name
);
116 free(location_tracepoint
->binary_path
);
117 if (location_tracepoint
->binary_fd
>= 0) {
118 if (close(location_tracepoint
->binary_fd
)) {
125 void lttng_userspace_probe_location_destroy(
126 struct lttng_userspace_probe_location
*location
)
132 lttng_userspace_probe_location_lookup_method_destroy(
133 location
->lookup_method
);
135 switch (location
->type
) {
136 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
137 lttng_userspace_probe_location_function_destroy(location
);
139 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
140 lttng_userspace_probe_location_tracepoint_destroy(location
);
148 bool lttng_userspace_probe_location_function_is_equal(const struct lttng_userspace_probe_location
*_a
,
149 const struct lttng_userspace_probe_location
*_b
)
151 bool is_equal
= false;
152 struct lttng_userspace_probe_location_function
*a
, *b
;
154 a
= container_of(_a
, struct lttng_userspace_probe_location_function
, parent
);
155 b
= container_of(_b
, struct lttng_userspace_probe_location_function
, parent
);
157 /* The binary_fd is not checked since it does not hold "immutable"
161 if (a
->instrumentation_type
!= b
->instrumentation_type
) {
165 assert(a
->function_name
);
166 assert(b
->function_name
);
167 if (strcmp(a
->function_name
, b
->function_name
)) {
171 assert(a
->binary_path
);
172 assert(b
->binary_path
);
173 if (strcmp(a
->binary_path
, b
->binary_path
)) {
182 static struct lttng_userspace_probe_location
*
183 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
184 const char *function_name
,
185 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
189 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
190 struct lttng_userspace_probe_location
*ret
= NULL
;
191 struct lttng_userspace_probe_location_function
*location
;
194 binary_fd
= open(binary_path
, O_RDONLY
);
196 PERROR("Error opening the binary");
203 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
204 if (!function_name_copy
) {
205 PERROR("Error duplicating the function name");
209 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
210 if (!binary_path_copy
) {
211 PERROR("Error duplicating the function name");
215 location
= zmalloc(sizeof(*location
));
217 PERROR("Error allocating userspace probe location");
221 location
->function_name
= function_name_copy
;
222 location
->binary_path
= binary_path_copy
;
223 location
->binary_fd
= binary_fd
;
224 location
->instrumentation_type
=
225 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
227 ret
= &location
->parent
;
228 ret
->lookup_method
= lookup_method
;
229 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
230 ret
->equal
= lttng_userspace_probe_location_function_is_equal
;
234 free(function_name_copy
);
235 free(binary_path_copy
);
236 if (binary_fd
>= 0) {
237 if (close(binary_fd
)) {
238 PERROR("Error closing binary fd in error path");
246 bool lttng_userspace_probe_location_tracepoint_is_equal(const struct lttng_userspace_probe_location
*_a
,
247 const struct lttng_userspace_probe_location
*_b
)
249 bool is_equal
= false;
250 struct lttng_userspace_probe_location_tracepoint
*a
, *b
;
252 a
= container_of(_a
, struct lttng_userspace_probe_location_tracepoint
, parent
);
253 b
= container_of(_b
, struct lttng_userspace_probe_location_tracepoint
, parent
);
255 /* The binary_fd is not checked since it does not hold "immutable"
259 assert(a
->probe_name
);
260 assert(b
->probe_name
);
261 if (strcmp(a
->probe_name
, b
->probe_name
)) {
265 assert(a
->provider_name
);
266 assert(b
->provider_name
);
267 if (strcmp(a
->provider_name
, b
->provider_name
)) {
271 assert(a
->binary_path
);
272 assert(b
->binary_path
);
273 if (strcmp(a
->binary_path
, b
->binary_path
)) {
282 static struct lttng_userspace_probe_location
*
283 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
284 const char *provider_name
, const char *probe_name
,
285 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
289 char *probe_name_copy
= NULL
;
290 char *provider_name_copy
= NULL
;
291 char *binary_path_copy
= NULL
;
292 struct lttng_userspace_probe_location
*ret
= NULL
;
293 struct lttng_userspace_probe_location_tracepoint
*location
;
296 binary_fd
= open(binary_path
, O_RDONLY
);
305 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
306 if (!probe_name_copy
) {
307 PERROR("lttng_strndup");
311 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
312 if (!provider_name_copy
) {
313 PERROR("lttng_strndup");
317 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
318 if (!binary_path_copy
) {
319 PERROR("lttng_strndup");
323 location
= zmalloc(sizeof(*location
));
329 location
->probe_name
= probe_name_copy
;
330 location
->provider_name
= provider_name_copy
;
331 location
->binary_path
= binary_path_copy
;
332 location
->binary_fd
= binary_fd
;
334 ret
= &location
->parent
;
335 ret
->lookup_method
= lookup_method
;
336 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
337 ret
->equal
= lttng_userspace_probe_location_tracepoint_is_equal
;
341 free(probe_name_copy
);
342 free(provider_name_copy
);
343 free(binary_path_copy
);
344 if (binary_fd
>= 0) {
345 if (close(binary_fd
)) {
346 PERROR("Error closing binary fd in error path");
353 struct lttng_userspace_probe_location
*
354 lttng_userspace_probe_location_function_create(const char *binary_path
,
355 const char *function_name
,
356 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
358 struct lttng_userspace_probe_location
*ret
= NULL
;
360 if (!binary_path
|| !function_name
) {
361 ERR("Invalid argument(s)");
365 switch (lttng_userspace_probe_location_lookup_method_get_type(
367 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
368 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
371 /* Invalid probe location lookup method. */
375 ret
= lttng_userspace_probe_location_function_create_no_check(
376 binary_path
, function_name
, lookup_method
, true);
381 struct lttng_userspace_probe_location
*
382 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
383 const char *provider_name
, const char *probe_name
,
384 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
386 struct lttng_userspace_probe_location
*ret
= NULL
;
388 if (!binary_path
|| !probe_name
|| !provider_name
) {
389 ERR("Invalid argument(s)");
393 switch (lttng_userspace_probe_location_lookup_method_get_type(
395 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
398 /* Invalid probe location lookup method. */
402 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
403 binary_path
, provider_name
, probe_name
, lookup_method
, true);
408 static struct lttng_userspace_probe_location_lookup_method
*
409 lttng_userspace_probe_location_lookup_method_function_elf_copy(
410 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
412 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
413 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
415 assert(lookup_method
);
416 assert(lookup_method
->type
==
417 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
419 elf_method
= zmalloc(sizeof(*elf_method
));
421 PERROR("Error allocating ELF userspace probe lookup method");
425 elf_method
->parent
.type
= lookup_method
->type
;
426 parent
= &elf_method
->parent
;
435 static struct lttng_userspace_probe_location_lookup_method
*
436 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
437 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
439 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
440 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
442 assert(lookup_method
);
443 assert(lookup_method
->type
==
444 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
446 sdt_method
= zmalloc(sizeof(*sdt_method
));
452 sdt_method
->parent
.type
= lookup_method
->type
;
453 parent
= &sdt_method
->parent
;
463 static struct lttng_userspace_probe_location
*
464 lttng_userspace_probe_location_function_copy(
465 const struct lttng_userspace_probe_location
*location
)
467 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
468 struct lttng_userspace_probe_location
*new_location
= NULL
;
469 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
470 const char *binary_path
= NULL
;
471 const char *function_name
= NULL
;
475 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
477 /* Get probe location fields */
478 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
480 ERR("Userspace probe binary path is NULL");
484 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
485 if (!function_name
) {
486 ERR("Userspace probe function name is NULL");
490 /* Duplicate the binary fd */
491 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
493 ERR("Error getting file descriptor to binary");
499 PERROR("Error duplicating file descriptor to binary");
504 * Duplicate probe location method fields
506 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
507 location
->lookup_method
);
508 switch (lookup_type
) {
509 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
511 lttng_userspace_probe_location_lookup_method_function_elf_copy(
512 location
->lookup_method
);
513 if (!lookup_method
) {
518 /* Invalid probe location lookup method. */
522 /* Create the probe_location */
523 new_location
= lttng_userspace_probe_location_function_create_no_check(
524 binary_path
, function_name
, lookup_method
, false);
526 goto destroy_lookup_method
;
529 /* Set the duplicated fd to the new probe_location */
530 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
531 goto destroy_probe_location
;
536 destroy_probe_location
:
537 lttng_userspace_probe_location_destroy(new_location
);
538 destroy_lookup_method
:
539 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
541 if (close(new_fd
) < 0) {
542 PERROR("Error closing duplicated file descriptor in error path");
550 static struct lttng_userspace_probe_location
*
551 lttng_userspace_probe_location_tracepoint_copy(
552 const struct lttng_userspace_probe_location
*location
)
554 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
555 struct lttng_userspace_probe_location
*new_location
= NULL
;
556 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
557 const char *binary_path
= NULL
;
558 const char *probe_name
= NULL
;
559 const char *provider_name
= NULL
;
563 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
565 /* Get probe location fields */
566 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
568 ERR("Userspace probe binary path is NULL");
572 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
574 ERR("Userspace probe probe name is NULL");
578 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
579 if (!provider_name
) {
580 ERR("Userspace probe provider name is NULL");
584 /* Duplicate the binary fd */
585 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
587 ERR("Error getting file descriptor to binary");
593 PERROR("Error duplicating file descriptor to binary");
598 * Duplicate probe location method fields
600 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
601 location
->lookup_method
);
602 switch (lookup_type
) {
603 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
605 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
606 location
->lookup_method
);
607 if (!lookup_method
) {
612 /* Invalid probe location lookup method. */
616 /* Create the probe_location */
617 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
618 binary_path
, provider_name
, probe_name
, lookup_method
, false);
620 goto destroy_lookup_method
;
623 /* Set the duplicated fd to the new probe_location */
624 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
625 goto destroy_probe_location
;
630 destroy_probe_location
:
631 lttng_userspace_probe_location_destroy(new_location
);
632 destroy_lookup_method
:
633 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
635 if (close(new_fd
) < 0) {
636 PERROR("Error closing duplicated file descriptor in error path");
644 const char *lttng_userspace_probe_location_function_get_binary_path(
645 const struct lttng_userspace_probe_location
*location
)
647 const char *ret
= NULL
;
648 struct lttng_userspace_probe_location_function
*function_location
;
650 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
651 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
652 ERR("Invalid argument(s)");
656 function_location
= container_of(location
,
657 struct lttng_userspace_probe_location_function
,
659 ret
= function_location
->binary_path
;
664 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
665 const struct lttng_userspace_probe_location
*location
)
667 const char *ret
= NULL
;
668 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
670 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
671 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
672 ERR("Invalid argument(s)");
676 tracepoint_location
= container_of(location
,
677 struct lttng_userspace_probe_location_tracepoint
,
679 ret
= tracepoint_location
->binary_path
;
684 const char *lttng_userspace_probe_location_function_get_function_name(
685 const struct lttng_userspace_probe_location
*location
)
687 const char *ret
= NULL
;
688 struct lttng_userspace_probe_location_function
*function_location
;
690 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
691 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
692 ERR("Invalid argument(s)");
696 function_location
= container_of(location
,
697 struct lttng_userspace_probe_location_function
, parent
);
698 ret
= function_location
->function_name
;
703 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
704 const struct lttng_userspace_probe_location
*location
)
706 const char *ret
= NULL
;
707 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
709 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
710 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
711 ERR("Invalid argument(s)");
715 tracepoint_location
= container_of(location
,
716 struct lttng_userspace_probe_location_tracepoint
, parent
);
717 ret
= tracepoint_location
->probe_name
;
722 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
723 const struct lttng_userspace_probe_location
*location
)
725 const char *ret
= NULL
;
726 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
728 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
729 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
730 ERR("Invalid argument(s)");
734 tracepoint_location
= container_of(location
,
735 struct lttng_userspace_probe_location_tracepoint
, parent
);
736 ret
= tracepoint_location
->provider_name
;
741 int lttng_userspace_probe_location_function_get_binary_fd(
742 const struct lttng_userspace_probe_location
*location
)
745 struct lttng_userspace_probe_location_function
*function_location
;
747 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
748 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
749 ERR("Invalid argument(s)");
753 function_location
= container_of(location
,
754 struct lttng_userspace_probe_location_function
, parent
);
755 ret
= function_location
->binary_fd
;
760 enum lttng_userspace_probe_location_function_instrumentation_type
761 lttng_userspace_probe_location_function_get_instrumentation_type(
762 const struct lttng_userspace_probe_location
*location
)
764 enum lttng_userspace_probe_location_function_instrumentation_type type
;
765 struct lttng_userspace_probe_location_function
*function_location
;
767 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
768 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
769 ERR("Invalid argument(s)");
770 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
774 function_location
= container_of(location
,
775 struct lttng_userspace_probe_location_function
, parent
);
776 type
= function_location
->instrumentation_type
;
781 enum lttng_userspace_probe_location_status
782 lttng_userspace_probe_location_function_set_instrumentation_type(
783 const struct lttng_userspace_probe_location
*location
,
784 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
786 enum lttng_userspace_probe_location_status status
=
787 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
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 instrumentation_type
!=
793 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
794 ERR("Invalid argument(s)");
795 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
799 function_location
= container_of(location
,
800 struct lttng_userspace_probe_location_function
, parent
);
801 function_location
->instrumentation_type
= instrumentation_type
;
806 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
807 const struct lttng_userspace_probe_location
*location
)
810 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
812 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
813 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
814 ERR("Invalid argument(s)");
818 tracepoint_location
= container_of(location
,
819 struct lttng_userspace_probe_location_tracepoint
, parent
);
820 ret
= tracepoint_location
->binary_fd
;
825 static struct lttng_userspace_probe_location_lookup_method
*
826 lttng_userspace_probe_location_function_get_lookup_method(
827 const struct lttng_userspace_probe_location
*location
)
829 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
831 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
832 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
833 ERR("Invalid argument(s)");
837 ret
= location
->lookup_method
;
842 static struct lttng_userspace_probe_location_lookup_method
*
843 lttng_userspace_probe_location_tracepoint_get_lookup_method(
844 const struct lttng_userspace_probe_location
*location
)
846 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
848 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
849 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
850 ERR("Invalid argument(s)");
854 ret
= location
->lookup_method
;
859 const struct lttng_userspace_probe_location_lookup_method
*
860 lttng_userspace_probe_location_get_lookup_method(
861 const struct lttng_userspace_probe_location
*location
)
863 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
866 switch (location
->type
) {
867 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
868 ret
= lttng_userspace_probe_location_function_get_lookup_method(
871 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
872 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
876 ERR("Unknowned lookup method.");
883 int lttng_userspace_probe_location_lookup_method_serialize(
884 struct lttng_userspace_probe_location_lookup_method
*method
,
885 struct lttng_dynamic_buffer
*buffer
)
888 struct lttng_userspace_probe_location_lookup_method_comm
891 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
892 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
894 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
895 sizeof(lookup_method_comm
));
900 ret
= sizeof(lookup_method_comm
);
906 int lttng_userspace_probe_location_function_serialize(
907 const struct lttng_userspace_probe_location
*location
,
908 struct lttng_dynamic_buffer
*buffer
,
912 size_t function_name_len
, binary_path_len
;
913 struct lttng_userspace_probe_location_function
*location_function
;
914 struct lttng_userspace_probe_location_function_comm location_function_comm
;
917 assert(lttng_userspace_probe_location_get_type(location
) ==
918 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
920 location_function
= container_of(location
,
921 struct lttng_userspace_probe_location_function
,
923 if (!location_function
->function_name
|| !location_function
->binary_path
) {
924 ret
= -LTTNG_ERR_INVALID
;
928 if (binary_fd
&& location_function
->binary_fd
< 0) {
929 ret
= -LTTNG_ERR_INVALID
;
934 *binary_fd
= location_function
->binary_fd
;
937 function_name_len
= strlen(location_function
->function_name
);
938 if (function_name_len
== 0) {
939 ret
= -LTTNG_ERR_INVALID
;
942 binary_path_len
= strlen(location_function
->binary_path
);
943 if (binary_path_len
== 0) {
944 ret
= -LTTNG_ERR_INVALID
;
948 location_function_comm
.function_name_len
= function_name_len
+ 1;
949 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
952 ret
= lttng_dynamic_buffer_append(buffer
,
953 &location_function_comm
,
954 sizeof(location_function_comm
));
956 ret
= -LTTNG_ERR_INVALID
;
959 ret
= lttng_dynamic_buffer_append(buffer
,
960 location_function
->function_name
,
961 location_function_comm
.function_name_len
);
963 ret
= -LTTNG_ERR_INVALID
;
966 ret
= lttng_dynamic_buffer_append(buffer
,
967 location_function
->binary_path
,
968 location_function_comm
.binary_path_len
);
970 ret
= -LTTNG_ERR_INVALID
;
974 ret
= sizeof(location_function_comm
) +
975 location_function_comm
.function_name_len
+
976 location_function_comm
.binary_path_len
;
982 int lttng_userspace_probe_location_tracepoint_serialize(
983 const struct lttng_userspace_probe_location
*location
,
984 struct lttng_dynamic_buffer
*buffer
,
988 size_t probe_name_len
, provider_name_len
, binary_path_len
;
989 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
990 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
993 assert(lttng_userspace_probe_location_get_type(location
) ==
994 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
996 location_tracepoint
= container_of(location
,
997 struct lttng_userspace_probe_location_tracepoint
,
999 if (!location_tracepoint
->probe_name
||
1000 !location_tracepoint
->provider_name
||
1001 !location_tracepoint
->binary_path
) {
1002 ret
= -LTTNG_ERR_INVALID
;
1006 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
1007 ret
= -LTTNG_ERR_INVALID
;
1012 *binary_fd
= location_tracepoint
->binary_fd
;
1015 probe_name_len
= strlen(location_tracepoint
->probe_name
);
1016 if (probe_name_len
== 0) {
1017 ret
= -LTTNG_ERR_INVALID
;
1021 provider_name_len
= strlen(location_tracepoint
->provider_name
);
1022 if (provider_name_len
== 0) {
1023 ret
= -LTTNG_ERR_INVALID
;
1027 binary_path_len
= strlen(location_tracepoint
->binary_path
);
1028 if (binary_path_len
== 0) {
1029 ret
= -LTTNG_ERR_INVALID
;
1033 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
1034 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
1035 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
1038 ret
= lttng_dynamic_buffer_append(buffer
,
1039 &location_tracepoint_comm
,
1040 sizeof(location_tracepoint_comm
));
1042 ret
= -LTTNG_ERR_INVALID
;
1045 ret
= lttng_dynamic_buffer_append(buffer
,
1046 location_tracepoint
->probe_name
,
1047 location_tracepoint_comm
.probe_name_len
);
1049 ret
= -LTTNG_ERR_INVALID
;
1052 ret
= lttng_dynamic_buffer_append(buffer
,
1053 location_tracepoint
->provider_name
,
1054 location_tracepoint_comm
.provider_name_len
);
1056 ret
= -LTTNG_ERR_INVALID
;
1059 ret
= lttng_dynamic_buffer_append(buffer
,
1060 location_tracepoint
->binary_path
,
1061 location_tracepoint_comm
.binary_path_len
);
1063 ret
= -LTTNG_ERR_INVALID
;
1067 ret
= sizeof(location_tracepoint_comm
) +
1068 location_tracepoint_comm
.probe_name_len
+
1069 location_tracepoint_comm
.provider_name_len
+
1070 location_tracepoint_comm
.binary_path_len
;
1076 int lttng_userspace_probe_location_serialize(
1077 const struct lttng_userspace_probe_location
*location
,
1078 struct lttng_dynamic_buffer
*buffer
,
1081 int ret
, buffer_use
= 0;
1082 struct lttng_userspace_probe_location_comm location_generic_comm
;
1085 ERR("Invalid argument(s)");
1086 ret
= -LTTNG_ERR_INVALID
;
1090 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1092 location_generic_comm
.type
= (int8_t) location
->type
;
1094 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1095 sizeof(location_generic_comm
));
1100 buffer_use
+= sizeof(location_generic_comm
);
1102 switch (lttng_userspace_probe_location_get_type(location
)) {
1103 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1104 ret
= lttng_userspace_probe_location_function_serialize(
1105 location
, buffer
, binary_fd
);
1107 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1108 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1109 location
, buffer
, binary_fd
);
1112 ERR("Unsupported probe location type");
1113 ret
= -LTTNG_ERR_INVALID
;
1121 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1122 location
->lookup_method
, buffer
);
1132 int lttng_userspace_probe_location_function_create_from_buffer(
1133 const struct lttng_buffer_view
*buffer
,
1134 struct lttng_userspace_probe_location
**location
)
1136 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1137 const char *function_name_src
, *binary_path_src
;
1138 char *function_name
= NULL
, *binary_path
= NULL
;
1142 assert(buffer
->data
);
1145 location_function_comm
=
1146 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1148 const size_t expected_size
= sizeof(*location_function_comm
) +
1149 location_function_comm
->function_name_len
+
1150 location_function_comm
->binary_path_len
;
1152 if (buffer
->size
< expected_size
) {
1153 ret
= -LTTNG_ERR_INVALID
;
1157 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1158 binary_path_src
= function_name_src
+
1159 location_function_comm
->function_name_len
;
1161 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1162 ret
= -LTTNG_ERR_INVALID
;
1165 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1166 ret
= -LTTNG_ERR_INVALID
;
1170 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1171 if (!function_name
) {
1172 PERROR("lttng_strndup");
1176 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1178 PERROR("lttng_strndup");
1182 *location
= lttng_userspace_probe_location_function_create_no_check(
1183 binary_path
, function_name
, NULL
, false);
1185 ret
= -LTTNG_ERR_INVALID
;
1189 ret
= (int) expected_size
;
1191 free(function_name
);
1197 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1198 const struct lttng_buffer_view
*buffer
,
1199 struct lttng_userspace_probe_location
**location
)
1201 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1202 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1203 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1207 assert(buffer
->data
);
1210 location_tracepoint_comm
=
1211 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1213 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1214 location_tracepoint_comm
->probe_name_len
+
1215 location_tracepoint_comm
->provider_name_len
+
1216 location_tracepoint_comm
->binary_path_len
;
1218 if (buffer
->size
< expected_size
) {
1219 ret
= -LTTNG_ERR_INVALID
;
1223 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1224 provider_name_src
= probe_name_src
+
1225 location_tracepoint_comm
->probe_name_len
;
1226 binary_path_src
= provider_name_src
+
1227 location_tracepoint_comm
->provider_name_len
;
1229 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1230 ret
= -LTTNG_ERR_INVALID
;
1234 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1235 ret
= -LTTNG_ERR_INVALID
;
1239 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1240 ret
= -LTTNG_ERR_INVALID
;
1244 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1246 PERROR("lttng_strndup");
1249 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1250 if (!provider_name
) {
1251 PERROR("lttng_strndup");
1255 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1257 PERROR("lttng_strndup");
1261 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1262 binary_path
, provider_name
, probe_name
, NULL
, false);
1264 ret
= -LTTNG_ERR_INVALID
;
1268 ret
= (int) expected_size
;
1271 free(provider_name
);
1277 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1278 struct lttng_buffer_view
*buffer
,
1279 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1282 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1283 enum lttng_userspace_probe_location_lookup_method_type type
;
1286 assert(buffer
->data
);
1287 assert(lookup_method
);
1289 if (buffer
->size
< sizeof(*lookup_comm
)) {
1290 ret
= -LTTNG_ERR_INVALID
;
1294 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1296 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1299 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1300 *lookup_method
= NULL
;
1302 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1304 lttng_userspace_probe_location_lookup_method_function_elf_create();
1305 if (!(*lookup_method
)) {
1306 ret
= -LTTNG_ERR_INVALID
;
1310 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1312 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1313 if (!(*lookup_method
)) {
1314 ret
= -LTTNG_ERR_INVALID
;
1319 ret
= -LTTNG_ERR_INVALID
;
1323 ret
= sizeof(*lookup_comm
);
1329 int lttng_userspace_probe_location_create_from_buffer(
1330 const struct lttng_buffer_view
*buffer
,
1331 struct lttng_userspace_probe_location
**location
)
1333 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1334 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1335 enum lttng_userspace_probe_location_type type
;
1336 struct lttng_buffer_view lookup_method_view
;
1342 assert(buffer
->data
);
1345 lookup_method
= NULL
;
1347 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1348 ret
= -LTTNG_ERR_INVALID
;
1352 probe_location_comm
=
1353 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1354 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1355 consumed
+= sizeof(*probe_location_comm
);
1358 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1360 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1361 buffer
, consumed
, buffer
->size
- consumed
);
1363 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1370 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1372 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1373 buffer
, consumed
, buffer
->size
- consumed
);
1375 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1383 ret
= -LTTNG_ERR_INVALID
;
1388 if (buffer
->size
<= consumed
) {
1389 ret
= -LTTNG_ERR_INVALID
;
1393 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1394 buffer
->size
- consumed
);
1395 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1396 &lookup_method_view
, &lookup_method
);
1398 ret
= -LTTNG_ERR_INVALID
;
1402 assert(lookup_method
);
1403 (*location
)->lookup_method
= lookup_method
;
1404 lookup_method
= NULL
;
1411 int lttng_userspace_probe_location_function_set_binary_fd(
1412 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1415 struct lttng_userspace_probe_location_function
*function_location
;
1418 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1420 function_location
= container_of(location
,
1421 struct lttng_userspace_probe_location_function
, parent
);
1422 if (function_location
->binary_fd
>= 0) {
1423 ret
= close(function_location
->binary_fd
);
1426 ret
= -LTTNG_ERR_INVALID
;
1431 function_location
->binary_fd
= binary_fd
;
1437 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1438 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1441 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1444 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1446 tracepoint_location
= container_of(location
,
1447 struct lttng_userspace_probe_location_tracepoint
, parent
);
1448 if (tracepoint_location
->binary_fd
>= 0) {
1449 ret
= close(tracepoint_location
->binary_fd
);
1452 ret
= -LTTNG_ERR_INVALID
;
1457 tracepoint_location
->binary_fd
= binary_fd
;
1463 int lttng_userspace_probe_location_function_flatten(
1464 const struct lttng_userspace_probe_location
*location
,
1465 struct lttng_dynamic_buffer
*buffer
)
1467 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1468 struct lttng_userspace_probe_location_function
*probe_function
;
1469 struct lttng_userspace_probe_location_function flat_probe
;
1470 size_t function_name_len
, binary_path_len
;
1471 size_t padding_needed
= 0;
1472 char *flat_probe_start
;
1473 int storage_needed
= 0;
1478 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1479 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1480 ret
= -LTTNG_ERR_INVALID
;
1484 probe_function
= container_of(location
,
1485 struct lttng_userspace_probe_location_function
,
1487 assert(probe_function
->function_name
);
1488 assert(probe_function
->binary_path
);
1491 sizeof(struct lttng_userspace_probe_location_function
);
1492 function_name_len
= strlen(probe_function
->function_name
) + 1;
1493 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1494 storage_needed
+= function_name_len
+ binary_path_len
;
1497 * The lookup method is aligned to 64-bit within the buffer.
1498 * This is needed even if there is no lookup method since
1499 * the next structure in the buffer probably needs to be
1500 * aligned too (depending on the arch).
1502 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1503 storage_needed
+= padding_needed
;
1505 if (location
->lookup_method
) {
1506 /* NOTE: elf look-up method is assumed here. */
1507 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1511 ret
= storage_needed
;
1515 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1516 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1517 buffer
->size
+ storage_needed
);
1523 memset(&flat_probe
, 0, sizeof(flat_probe
));
1525 flat_probe_start
= buffer
->data
+ buffer
->size
;
1526 flat_probe
.parent
.type
= location
->type
;
1528 * The lookup method, if present, is the last element in the flat
1529 * representation of the probe.
1531 if (location
->lookup_method
) {
1532 flat_probe
.parent
.lookup_method
=
1533 (struct lttng_userspace_probe_location_lookup_method
*)
1534 (flat_probe_start
+ sizeof(flat_probe
) +
1535 function_name_len
+ binary_path_len
+ padding_needed
);
1537 flat_probe
.parent
.lookup_method
= NULL
;
1540 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1541 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1542 flat_probe
.binary_fd
= -1;
1543 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1544 sizeof(flat_probe
));
1549 ret
= lttng_dynamic_buffer_append(buffer
,
1550 probe_function
->function_name
, function_name_len
);
1554 ret
= lttng_dynamic_buffer_append(buffer
,
1555 probe_function
->binary_path
, binary_path_len
);
1560 /* Insert padding before the lookup method. */
1561 ret
= lttng_dynamic_buffer_set_size(buffer
,
1562 buffer
->size
+ padding_needed
);
1567 if (!location
->lookup_method
) {
1568 /* Not an error, the default method is used. */
1569 ret
= storage_needed
;
1573 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1574 flat_lookup_method
.parent
.type
=
1575 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1576 ret
= lttng_dynamic_buffer_append(buffer
,
1577 &flat_lookup_method
, sizeof(flat_lookup_method
));
1581 ret
= storage_needed
;
1587 int lttng_userspace_probe_location_tracepoint_flatten(
1588 const struct lttng_userspace_probe_location
*location
,
1589 struct lttng_dynamic_buffer
*buffer
)
1591 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1592 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1593 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1594 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1595 size_t padding_needed
= 0;
1596 int storage_needed
= 0;
1597 char *flat_probe_start
;
1602 /* Only SDT tracepoints are supported at the moment */
1603 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1604 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1605 ret
= -LTTNG_ERR_INVALID
;
1608 probe_tracepoint
= container_of(location
,
1609 struct lttng_userspace_probe_location_tracepoint
,
1611 assert(probe_tracepoint
->probe_name
);
1612 assert(probe_tracepoint
->provider_name
);
1613 assert(probe_tracepoint
->binary_path
);
1615 /* Compute the storage space needed to flatten the probe location */
1616 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1618 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1619 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1620 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1622 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1625 * The lookup method is aligned to 64-bit within the buffer.
1626 * This is needed even if there is no lookup method since
1627 * the next structure in the buffer probably needs to be
1628 * aligned too (depending on the arch).
1630 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1631 storage_needed
+= padding_needed
;
1633 if (location
->lookup_method
) {
1634 /* NOTE: elf look-up method is assumed here. */
1636 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1640 * If the caller set buffer to NULL, return the size of the needed buffer.
1643 ret
= storage_needed
;
1647 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1648 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1649 buffer
->size
+ storage_needed
);
1655 memset(&flat_probe
, 0, sizeof(flat_probe
));
1657 flat_probe_start
= buffer
->data
+ buffer
->size
;
1658 flat_probe
.parent
.type
= location
->type
;
1661 * The lookup method, if present, is the last element in the flat
1662 * representation of the probe.
1664 if (location
->lookup_method
) {
1665 flat_probe
.parent
.lookup_method
=
1666 (struct lttng_userspace_probe_location_lookup_method
*)
1667 (flat_probe_start
+ sizeof(flat_probe
) +
1668 probe_name_len
+ provider_name_len
+
1669 binary_path_len
+ padding_needed
);
1671 flat_probe
.parent
.lookup_method
= NULL
;
1674 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1675 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1676 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1677 flat_probe
.binary_fd
= -1;
1678 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1683 /* Append all the fields to the buffer */
1684 ret
= lttng_dynamic_buffer_append(buffer
,
1685 probe_tracepoint
->probe_name
, probe_name_len
);
1689 ret
= lttng_dynamic_buffer_append(buffer
,
1690 probe_tracepoint
->provider_name
, provider_name_len
);
1694 ret
= lttng_dynamic_buffer_append(buffer
,
1695 probe_tracepoint
->binary_path
, binary_path_len
);
1700 /* Insert padding before the lookup method. */
1701 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1706 if (!location
->lookup_method
) {
1707 /* Not an error, the default method is used. */
1708 ret
= storage_needed
;
1712 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1714 flat_lookup_method
.parent
.type
=
1715 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1716 ret
= lttng_dynamic_buffer_append(buffer
,
1717 &flat_lookup_method
, sizeof(flat_lookup_method
));
1721 ret
= storage_needed
;
1727 int lttng_userspace_probe_location_flatten(
1728 const struct lttng_userspace_probe_location
*location
,
1729 struct lttng_dynamic_buffer
*buffer
)
1733 ret
= -LTTNG_ERR_INVALID
;
1737 /* Only types currently supported. */
1738 switch (location
->type
) {
1739 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1740 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1742 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1743 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1746 ret
= -LTTNG_ERR_INVALID
;
1755 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1756 const struct lttng_userspace_probe_location
*location
)
1758 struct lttng_userspace_probe_location
*new_location
= NULL
;
1759 enum lttng_userspace_probe_location_type type
;
1765 type
= lttng_userspace_probe_location_get_type(location
);
1767 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1769 lttng_userspace_probe_location_function_copy(location
);
1770 if (!new_location
) {
1774 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1776 lttng_userspace_probe_location_tracepoint_copy(location
);
1777 if (!new_location
) {
1782 new_location
= NULL
;
1786 return new_location
;
1790 bool lttng_userspace_probe_location_is_equal(
1791 const struct lttng_userspace_probe_location
*a
,
1792 const struct lttng_userspace_probe_location
*b
)
1794 bool is_equal
= false;
1800 if (a
->type
!= b
->type
) {
1809 is_equal
= a
->equal
? a
->equal(a
, b
) : true;
1815 int lttng_userspace_probe_location_set_binary_fd(
1816 struct lttng_userspace_probe_location
*location
, int fd
)
1819 const struct lttng_userspace_probe_location_lookup_method
*lookup
= NULL
;
1821 * Set the file descriptor received from the client through the unix
1822 * socket in the probe location.
1824 lookup
= lttng_userspace_probe_location_get_lookup_method(location
);
1826 ret
= LTTNG_ERR_PROBE_LOCATION_INVAL
;
1831 * From the kernel tracer's perspective, all userspace probe event types
1832 * are all the same: a file and an offset.
1834 switch (lttng_userspace_probe_location_lookup_method_get_type(lookup
)) {
1835 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1836 ret
= lttng_userspace_probe_location_function_set_binary_fd(
1839 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1840 ret
= lttng_userspace_probe_location_tracepoint_set_binary_fd(
1844 ret
= LTTNG_ERR_PROBE_LOCATION_INVAL
;
1849 ret
= LTTNG_ERR_PROBE_LOCATION_INVAL
;