2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <common/error.h>
20 #include <common/macros.h>
21 #include <common/compat/string.h>
23 #include <lttng/constant.h>
24 #include <lttng/userspace-probe-internal.h>
26 enum lttng_userspace_probe_location_lookup_method_type
27 lttng_userspace_probe_location_lookup_method_get_type(
28 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
30 return lookup_method
? lookup_method
->type
:
31 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
34 void lttng_userspace_probe_location_lookup_method_destroy(
35 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
41 switch (lookup_method
->type
) {
42 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
44 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
=
45 container_of(lookup_method
,
46 struct lttng_userspace_probe_location_lookup_method_elf
, parent
);
50 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
52 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
=
53 container_of(lookup_method
,
54 struct lttng_userspace_probe_location_lookup_method_sdt
, parent
);
63 struct lttng_userspace_probe_location_lookup_method
*
64 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
66 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
67 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
69 elf_method
= zmalloc(sizeof(*elf_method
));
75 ret
= &elf_method
->parent
;
76 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
81 struct lttng_userspace_probe_location_lookup_method
*
82 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
84 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
85 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
87 sdt_method
= zmalloc(sizeof(*sdt_method
));
93 ret
= &sdt_method
->parent
;
94 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
99 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
100 const struct lttng_userspace_probe_location
*location
)
102 return location
? location
->type
:
103 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
107 void lttng_userspace_probe_location_function_destroy(
108 struct lttng_userspace_probe_location
*location
)
110 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
114 location_function
= container_of(location
,
115 struct lttng_userspace_probe_location_function
, parent
);
117 assert(location_function
);
119 free(location_function
->function_name
);
120 free(location_function
->binary_path
);
121 if (location_function
->binary_fd
>= 0) {
122 if (close(location_function
->binary_fd
)) {
130 void lttng_userspace_probe_location_tracepoint_destroy(
131 struct lttng_userspace_probe_location
*location
)
133 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
137 location_tracepoint
= container_of(location
,
138 struct lttng_userspace_probe_location_tracepoint
,
141 assert(location_tracepoint
);
143 free(location_tracepoint
->probe_name
);
144 free(location_tracepoint
->provider_name
);
145 free(location_tracepoint
->binary_path
);
146 if (location_tracepoint
->binary_fd
>= 0) {
147 if (close(location_tracepoint
->binary_fd
)) {
154 void lttng_userspace_probe_location_destroy(
155 struct lttng_userspace_probe_location
*location
)
161 lttng_userspace_probe_location_lookup_method_destroy(
162 location
->lookup_method
);
164 switch (location
->type
) {
165 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
166 lttng_userspace_probe_location_function_destroy(location
);
168 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
169 lttng_userspace_probe_location_tracepoint_destroy(location
);
176 static struct lttng_userspace_probe_location
*
177 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
178 const char *function_name
,
179 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
183 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
184 struct lttng_userspace_probe_location
*ret
= NULL
;
185 struct lttng_userspace_probe_location_function
*location
;
188 binary_fd
= open(binary_path
, O_RDONLY
);
190 PERROR("Error opening the binary");
197 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
198 if (!function_name_copy
) {
199 PERROR("Error duplicating the function name");
203 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
204 if (!binary_path_copy
) {
205 PERROR("Error duplicating the function name");
209 location
= zmalloc(sizeof(*location
));
211 PERROR("Error allocating userspace probe location");
215 location
->function_name
= function_name_copy
;
216 location
->binary_path
= binary_path_copy
;
217 location
->binary_fd
= binary_fd
;
219 ret
= &location
->parent
;
220 ret
->lookup_method
= lookup_method
;
221 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
225 free(function_name_copy
);
226 free(binary_path_copy
);
227 if (binary_fd
>= 0) {
228 if (close(binary_fd
)) {
229 PERROR("Error closing binary fd in error path");
236 static struct lttng_userspace_probe_location
*
237 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
238 const char *provider_name
, const char *probe_name
,
239 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
243 char *probe_name_copy
= NULL
;
244 char *provider_name_copy
= NULL
;
245 char *binary_path_copy
= NULL
;
246 struct lttng_userspace_probe_location
*ret
= NULL
;
247 struct lttng_userspace_probe_location_tracepoint
*location
;
250 binary_fd
= open(binary_path
, O_RDONLY
);
259 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
260 if (!probe_name_copy
) {
261 PERROR("lttng_strndup");
265 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
266 if (!provider_name_copy
) {
267 PERROR("lttng_strndup");
271 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
272 if (!binary_path_copy
) {
273 PERROR("lttng_strndup");
277 location
= zmalloc(sizeof(*location
));
283 location
->probe_name
= probe_name_copy
;
284 location
->provider_name
= provider_name_copy
;
285 location
->binary_path
= binary_path_copy
;
286 location
->binary_fd
= binary_fd
;
288 ret
= &location
->parent
;
289 ret
->lookup_method
= lookup_method
;
290 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
294 free(probe_name_copy
);
295 free(provider_name_copy
);
296 if (binary_fd
>= 0) {
297 if (close(binary_fd
)) {
298 PERROR("Error closing binary fd in error path");
305 struct lttng_userspace_probe_location
*
306 lttng_userspace_probe_location_function_create(const char *binary_path
,
307 const char *function_name
,
308 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
310 struct lttng_userspace_probe_location
*ret
= NULL
;
312 if (!binary_path
|| !function_name
) {
313 ERR("Invalid argument(s)");
317 switch (lttng_userspace_probe_location_lookup_method_get_type(
319 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
320 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
323 /* Invalid probe location lookup method. */
327 ret
= lttng_userspace_probe_location_function_create_no_check(
328 binary_path
, function_name
, lookup_method
, true);
333 struct lttng_userspace_probe_location
*
334 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
335 const char *provider_name
, const char *probe_name
,
336 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
338 struct lttng_userspace_probe_location
*ret
= NULL
;
340 if (!binary_path
|| !probe_name
|| !provider_name
) {
341 ERR("Invalid argument(s)");
345 switch (lttng_userspace_probe_location_lookup_method_get_type(
347 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
350 /* Invalid probe location lookup method. */
354 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
355 binary_path
, provider_name
, probe_name
, lookup_method
, true);
360 static struct lttng_userspace_probe_location_lookup_method
*
361 lttng_userspace_probe_location_lookup_method_function_elf_copy(
362 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
364 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
365 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
367 assert(lookup_method
);
368 assert(lookup_method
->type
==
369 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
371 elf_method
= zmalloc(sizeof(*elf_method
));
373 PERROR("Error allocating ELF userspace probe lookup method");
377 elf_method
->parent
.type
= lookup_method
->type
;
378 parent
= &elf_method
->parent
;
387 static struct lttng_userspace_probe_location_lookup_method
*
388 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
389 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
391 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
392 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
394 assert(lookup_method
);
395 assert(lookup_method
->type
==
396 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
398 sdt_method
= zmalloc(sizeof(*sdt_method
));
404 sdt_method
->parent
.type
= lookup_method
->type
;
405 parent
= &sdt_method
->parent
;
415 static struct lttng_userspace_probe_location
*
416 lttng_userspace_probe_location_function_copy(
417 const struct lttng_userspace_probe_location
*location
)
419 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
420 struct lttng_userspace_probe_location
*new_location
= NULL
;
421 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
422 char *binary_path
= NULL
;
423 char *function_name
= NULL
;
427 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
429 /* Duplicate probe location fields */
431 lttng_strndup(lttng_userspace_probe_location_function_get_binary_path(location
),
438 lttng_strndup(lttng_userspace_probe_location_function_get_function_name(location
),
439 LTTNG_SYMBOL_NAME_LEN
);
440 if (!function_name
) {
441 PERROR("Error duplicating function name string");
445 /* Duplicate the binary fd */
446 fd
= dup(lttng_userspace_probe_location_function_get_binary_fd(location
));
448 PERROR("Error duplicating file descriptor to binary");
453 * Duplicate probe location method fields
455 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
456 location
->lookup_method
);
457 switch (lookup_type
) {
458 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
460 lttng_userspace_probe_location_lookup_method_function_elf_copy(
461 location
->lookup_method
);
462 if (!lookup_method
) {
467 /* Invalid probe location lookup method. */
471 /* Create the probe_location */
472 new_location
= lttng_userspace_probe_location_function_create_no_check(
473 binary_path
, function_name
, lookup_method
, true);
475 goto destroy_lookup_method
;
478 /* Set the duplicated fd to the new probe_location */
479 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, fd
) < 0) {
480 goto destroy_probe_location
;
485 destroy_probe_location
:
486 lttng_userspace_probe_location_destroy(new_location
);
487 destroy_lookup_method
:
488 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
491 PERROR("Error closing duplicated file descriptor in error path");
501 static struct lttng_userspace_probe_location
*
502 lttng_userspace_probe_location_tracepoint_copy(
503 const struct lttng_userspace_probe_location
*location
)
505 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
506 struct lttng_userspace_probe_location
*new_location
= NULL
;
507 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
508 char *binary_path
= NULL
;
509 char *probe_name
= NULL
;
510 char *provider_name
= NULL
;
514 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
516 /* Duplicate probe location fields */
518 lttng_strndup(lttng_userspace_probe_location_tracepoint_get_binary_path(location
),
521 PERROR("lttng_strndup");
526 lttng_strndup(lttng_userspace_probe_location_tracepoint_get_probe_name(location
),
527 LTTNG_SYMBOL_NAME_LEN
);
529 PERROR("lttng_strndup");
534 lttng_strndup(lttng_userspace_probe_location_tracepoint_get_provider_name(location
),
535 LTTNG_SYMBOL_NAME_LEN
);
536 if (!provider_name
) {
537 PERROR("lttng_strndup");
541 /* Duplicate the binary fd */
542 fd
= dup(lttng_userspace_probe_location_tracepoint_get_binary_fd(location
));
549 * Duplicate probe location method fields
551 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
552 location
->lookup_method
);
553 switch (lookup_type
) {
554 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
556 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
557 location
->lookup_method
);
558 if (!lookup_method
) {
563 /* Invalid probe location lookup method. */
567 /* Create the probe_location */
568 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
569 binary_path
, provider_name
, probe_name
, lookup_method
, true);
571 goto destroy_lookup_method
;
574 /* Set the duplicated fd to the new probe_location */
575 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, fd
) < 0) {
576 goto destroy_probe_location
;
581 destroy_probe_location
:
582 lttng_userspace_probe_location_destroy(new_location
);
583 destroy_lookup_method
:
584 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
598 const char *lttng_userspace_probe_location_function_get_binary_path(
599 const struct lttng_userspace_probe_location
*location
)
601 const char *ret
= NULL
;
602 struct lttng_userspace_probe_location_function
*function_location
;
604 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
605 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
606 ERR("Invalid argument(s)");
610 function_location
= container_of(location
,
611 struct lttng_userspace_probe_location_function
,
613 ret
= function_location
->binary_path
;
618 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
619 const struct lttng_userspace_probe_location
*location
)
621 const char *ret
= NULL
;
622 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
624 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
625 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
626 ERR("Invalid argument(s)");
630 tracepoint_location
= container_of(location
,
631 struct lttng_userspace_probe_location_tracepoint
,
633 ret
= tracepoint_location
->binary_path
;
638 const char *lttng_userspace_probe_location_function_get_function_name(
639 const struct lttng_userspace_probe_location
*location
)
641 const char *ret
= NULL
;
642 struct lttng_userspace_probe_location_function
*function_location
;
644 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
645 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
646 ERR("Invalid argument(s)");
650 function_location
= container_of(location
,
651 struct lttng_userspace_probe_location_function
, parent
);
652 ret
= function_location
->function_name
;
657 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
658 const struct lttng_userspace_probe_location
*location
)
660 const char *ret
= NULL
;
661 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
663 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
664 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
665 ERR("Invalid argument(s)");
669 tracepoint_location
= container_of(location
,
670 struct lttng_userspace_probe_location_tracepoint
, parent
);
671 ret
= tracepoint_location
->probe_name
;
676 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
677 const struct lttng_userspace_probe_location
*location
)
679 const char *ret
= NULL
;
680 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
682 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
683 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
684 ERR("Invalid argument(s)");
688 tracepoint_location
= container_of(location
,
689 struct lttng_userspace_probe_location_tracepoint
, parent
);
690 ret
= tracepoint_location
->provider_name
;
695 int lttng_userspace_probe_location_function_get_binary_fd(
696 const struct lttng_userspace_probe_location
*location
)
699 struct lttng_userspace_probe_location_function
*function_location
;
701 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
702 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
703 ERR("Invalid argument(s)");
707 function_location
= container_of(location
,
708 struct lttng_userspace_probe_location_function
, parent
);
709 ret
= function_location
->binary_fd
;
714 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
715 const struct lttng_userspace_probe_location
*location
)
718 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
720 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
721 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
722 ERR("Invalid argument(s)");
726 tracepoint_location
= container_of(location
,
727 struct lttng_userspace_probe_location_tracepoint
, parent
);
728 ret
= tracepoint_location
->binary_fd
;
733 static struct lttng_userspace_probe_location_lookup_method
*
734 lttng_userspace_probe_location_function_get_lookup_method(
735 const struct lttng_userspace_probe_location
*location
)
737 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
739 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
740 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
741 ERR("Invalid argument(s)");
745 ret
= location
->lookup_method
;
750 static struct lttng_userspace_probe_location_lookup_method
*
751 lttng_userspace_probe_location_tracepoint_get_lookup_method(
752 const struct lttng_userspace_probe_location
*location
)
754 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
756 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
757 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
758 ERR("Invalid argument(s)");
762 ret
= location
->lookup_method
;
767 struct lttng_userspace_probe_location_lookup_method
*
768 lttng_userspace_probe_location_get_lookup_method(
769 const struct lttng_userspace_probe_location
*location
)
771 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
774 switch (location
->type
) {
775 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
776 ret
= lttng_userspace_probe_location_function_get_lookup_method(
779 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
780 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
784 ERR("Unknowned lookup method.");
791 int lttng_userspace_probe_location_lookup_method_serialize(
792 struct lttng_userspace_probe_location_lookup_method
*method
,
793 struct lttng_dynamic_buffer
*buffer
)
796 struct lttng_userspace_probe_location_lookup_method_comm
799 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
800 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
802 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
803 sizeof(lookup_method_comm
));
808 ret
= sizeof(lookup_method_comm
);
814 int lttng_userspace_probe_location_function_serialize(
815 const struct lttng_userspace_probe_location
*location
,
816 struct lttng_dynamic_buffer
*buffer
,
820 size_t function_name_len
, binary_path_len
;
821 struct lttng_userspace_probe_location_function
*location_function
;
822 struct lttng_userspace_probe_location_function_comm location_function_comm
;
825 assert(lttng_userspace_probe_location_get_type(location
) ==
826 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
828 location_function
= container_of(location
,
829 struct lttng_userspace_probe_location_function
,
831 if (!location_function
->function_name
|| !location_function
->binary_path
) {
832 ret
= -LTTNG_ERR_INVALID
;
836 if (binary_fd
&& location_function
->binary_fd
< 0) {
837 ret
= -LTTNG_ERR_INVALID
;
842 *binary_fd
= location_function
->binary_fd
;
845 function_name_len
= strlen(location_function
->function_name
);
846 if (function_name_len
== 0) {
847 ret
= -LTTNG_ERR_INVALID
;
850 binary_path_len
= strlen(location_function
->binary_path
);
851 if (binary_path_len
== 0) {
852 ret
= -LTTNG_ERR_INVALID
;
856 location_function_comm
.function_name_len
= function_name_len
+ 1;
857 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
860 ret
= lttng_dynamic_buffer_append(buffer
,
861 &location_function_comm
,
862 sizeof(location_function_comm
));
864 ret
= -LTTNG_ERR_INVALID
;
867 ret
= lttng_dynamic_buffer_append(buffer
,
868 location_function
->function_name
,
869 location_function_comm
.function_name_len
);
871 ret
= -LTTNG_ERR_INVALID
;
874 ret
= lttng_dynamic_buffer_append(buffer
,
875 location_function
->binary_path
,
876 location_function_comm
.binary_path_len
);
878 ret
= -LTTNG_ERR_INVALID
;
882 ret
= sizeof(location_function_comm
) +
883 location_function_comm
.function_name_len
+
884 location_function_comm
.binary_path_len
;
890 int lttng_userspace_probe_location_tracepoint_serialize(
891 const struct lttng_userspace_probe_location
*location
,
892 struct lttng_dynamic_buffer
*buffer
,
896 size_t probe_name_len
, provider_name_len
, binary_path_len
;
897 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
898 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
901 assert(lttng_userspace_probe_location_get_type(location
) ==
902 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
904 location_tracepoint
= container_of(location
,
905 struct lttng_userspace_probe_location_tracepoint
,
907 if (!location_tracepoint
->probe_name
||
908 !location_tracepoint
->provider_name
||
909 !location_tracepoint
->binary_path
) {
910 ret
= -LTTNG_ERR_INVALID
;
914 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
915 ret
= -LTTNG_ERR_INVALID
;
920 *binary_fd
= location_tracepoint
->binary_fd
;
923 probe_name_len
= strlen(location_tracepoint
->probe_name
);
924 if (probe_name_len
== 0) {
925 ret
= -LTTNG_ERR_INVALID
;
929 provider_name_len
= strlen(location_tracepoint
->provider_name
);
930 if (provider_name_len
== 0) {
931 ret
= -LTTNG_ERR_INVALID
;
935 binary_path_len
= strlen(location_tracepoint
->binary_path
);
936 if (binary_path_len
== 0) {
937 ret
= -LTTNG_ERR_INVALID
;
941 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
942 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
943 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
946 ret
= lttng_dynamic_buffer_append(buffer
,
947 &location_tracepoint_comm
,
948 sizeof(location_tracepoint_comm
));
950 ret
= -LTTNG_ERR_INVALID
;
953 ret
= lttng_dynamic_buffer_append(buffer
,
954 location_tracepoint
->probe_name
,
955 location_tracepoint_comm
.probe_name_len
);
957 ret
= -LTTNG_ERR_INVALID
;
960 ret
= lttng_dynamic_buffer_append(buffer
,
961 location_tracepoint
->provider_name
,
962 location_tracepoint_comm
.provider_name_len
);
964 ret
= -LTTNG_ERR_INVALID
;
967 ret
= lttng_dynamic_buffer_append(buffer
,
968 location_tracepoint
->binary_path
,
969 location_tracepoint_comm
.binary_path_len
);
971 ret
= -LTTNG_ERR_INVALID
;
975 ret
= sizeof(location_tracepoint_comm
) +
976 location_tracepoint_comm
.probe_name_len
+
977 location_tracepoint_comm
.provider_name_len
+
978 location_tracepoint_comm
.binary_path_len
;
984 int lttng_userspace_probe_location_serialize(
985 const struct lttng_userspace_probe_location
*location
,
986 struct lttng_dynamic_buffer
*buffer
,
989 int ret
, buffer_use
= 0;
990 struct lttng_userspace_probe_location_comm location_generic_comm
;
993 ERR("Invalid argument(s)");
994 ret
= -LTTNG_ERR_INVALID
;
998 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1000 location_generic_comm
.type
= (int8_t) location
->type
;
1002 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1003 sizeof(location_generic_comm
));
1008 buffer_use
+= sizeof(location_generic_comm
);
1010 switch (lttng_userspace_probe_location_get_type(location
)) {
1011 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1012 ret
= lttng_userspace_probe_location_function_serialize(
1013 location
, buffer
, binary_fd
);
1015 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1016 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1017 location
, buffer
, binary_fd
);
1020 ERR("Unsupported probe location type");
1021 ret
= -LTTNG_ERR_INVALID
;
1029 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1030 location
->lookup_method
, buffer
);
1040 int lttng_userspace_probe_location_function_create_from_buffer(
1041 const struct lttng_buffer_view
*buffer
,
1042 struct lttng_userspace_probe_location
**location
)
1044 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1045 const char *function_name_src
, *binary_path_src
;
1046 char *function_name
= NULL
, *binary_path
= NULL
;
1050 assert(buffer
->data
);
1053 location_function_comm
=
1054 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1056 const size_t expected_size
= sizeof(*location_function_comm
) +
1057 location_function_comm
->function_name_len
+
1058 location_function_comm
->binary_path_len
;
1060 if (buffer
->size
< expected_size
) {
1061 ret
= -LTTNG_ERR_INVALID
;
1065 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1066 binary_path_src
= function_name_src
+
1067 location_function_comm
->function_name_len
;
1069 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1070 ret
= -LTTNG_ERR_INVALID
;
1073 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1074 ret
= -LTTNG_ERR_INVALID
;
1078 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1079 if (!function_name
) {
1080 PERROR("lttng_strndup");
1084 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1086 PERROR("lttng_strndup");
1090 *location
= lttng_userspace_probe_location_function_create_no_check(
1091 binary_path
, function_name
, NULL
, false);
1093 ret
= -LTTNG_ERR_INVALID
;
1097 ret
= (int) expected_size
;
1099 free(function_name
);
1105 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1106 const struct lttng_buffer_view
*buffer
,
1107 struct lttng_userspace_probe_location
**location
)
1109 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1110 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1111 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1115 assert(buffer
->data
);
1118 location_tracepoint_comm
=
1119 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1121 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1122 location_tracepoint_comm
->probe_name_len
+
1123 location_tracepoint_comm
->provider_name_len
+
1124 location_tracepoint_comm
->binary_path_len
;
1126 if (buffer
->size
< expected_size
) {
1127 ret
= -LTTNG_ERR_INVALID
;
1131 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1132 provider_name_src
= probe_name_src
+
1133 location_tracepoint_comm
->probe_name_len
;
1134 binary_path_src
= provider_name_src
+
1135 location_tracepoint_comm
->provider_name_len
;
1137 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1138 ret
= -LTTNG_ERR_INVALID
;
1142 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1143 ret
= -LTTNG_ERR_INVALID
;
1147 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1148 ret
= -LTTNG_ERR_INVALID
;
1152 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1154 PERROR("lttng_strndup");
1157 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1158 if (!provider_name
) {
1159 PERROR("lttng_strndup");
1163 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1165 PERROR("lttng_strndup");
1169 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1170 binary_path
, provider_name
, probe_name
, NULL
, false);
1172 ret
= -LTTNG_ERR_INVALID
;
1176 ret
= (int) expected_size
;
1179 free(provider_name
);
1185 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1186 struct lttng_buffer_view
*buffer
,
1187 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1190 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1191 enum lttng_userspace_probe_location_lookup_method_type type
;
1194 assert(buffer
->data
);
1195 assert(lookup_method
);
1197 if (buffer
->size
< sizeof(*lookup_comm
)) {
1198 ret
= -LTTNG_ERR_INVALID
;
1202 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1204 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1207 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1208 *lookup_method
= NULL
;
1210 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1212 lttng_userspace_probe_location_lookup_method_function_elf_create();
1213 if (!(*lookup_method
)) {
1214 ret
= -LTTNG_ERR_INVALID
;
1218 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1220 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1221 if (!(*lookup_method
)) {
1222 ret
= -LTTNG_ERR_INVALID
;
1227 ret
= -LTTNG_ERR_INVALID
;
1231 ret
= sizeof(*lookup_comm
);
1237 int lttng_userspace_probe_location_create_from_buffer(
1238 const struct lttng_buffer_view
*buffer
,
1239 struct lttng_userspace_probe_location
**location
)
1241 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1242 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1243 enum lttng_userspace_probe_location_type type
;
1244 struct lttng_buffer_view lookup_method_view
;
1250 assert(buffer
->data
);
1253 lookup_method
= NULL
;
1255 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1256 ret
= -LTTNG_ERR_INVALID
;
1260 probe_location_comm
=
1261 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1262 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1263 consumed
+= sizeof(*probe_location_comm
);
1266 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1268 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1269 buffer
, consumed
, buffer
->size
- consumed
);
1271 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1278 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1280 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1281 buffer
, consumed
, buffer
->size
- consumed
);
1283 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1291 ret
= -LTTNG_ERR_INVALID
;
1296 if (buffer
->size
<= consumed
) {
1297 ret
= -LTTNG_ERR_INVALID
;
1301 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1302 buffer
->size
- consumed
);
1303 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1304 &lookup_method_view
, &lookup_method
);
1306 ret
= -LTTNG_ERR_INVALID
;
1310 assert(lookup_method
);
1311 (*location
)->lookup_method
= lookup_method
;
1312 lookup_method
= NULL
;
1319 int lttng_userspace_probe_location_function_set_binary_fd(
1320 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1323 struct lttng_userspace_probe_location_function
*function_location
;
1326 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1328 function_location
= container_of(location
,
1329 struct lttng_userspace_probe_location_function
, parent
);
1330 if (function_location
->binary_fd
>= 0) {
1331 ret
= close(function_location
->binary_fd
);
1334 ret
= -LTTNG_ERR_INVALID
;
1339 function_location
->binary_fd
= binary_fd
;
1345 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1346 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1349 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1352 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1354 tracepoint_location
= container_of(location
,
1355 struct lttng_userspace_probe_location_tracepoint
, parent
);
1356 if (tracepoint_location
->binary_fd
>= 0) {
1357 ret
= close(tracepoint_location
->binary_fd
);
1360 ret
= -LTTNG_ERR_INVALID
;
1365 tracepoint_location
->binary_fd
= binary_fd
;
1371 int lttng_userspace_probe_location_function_flatten(
1372 const struct lttng_userspace_probe_location
*location
,
1373 struct lttng_dynamic_buffer
*buffer
)
1375 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1376 struct lttng_userspace_probe_location_function
*probe_function
;
1377 struct lttng_userspace_probe_location_function flat_probe
;
1378 size_t function_name_len
, binary_path_len
;
1379 size_t padding_needed
= 0;
1380 char *flat_probe_start
;
1381 int storage_needed
= 0;
1386 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1387 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1388 ret
= -LTTNG_ERR_INVALID
;
1392 probe_function
= container_of(location
,
1393 struct lttng_userspace_probe_location_function
,
1395 assert(probe_function
->function_name
);
1396 assert(probe_function
->binary_path
);
1399 sizeof(struct lttng_userspace_probe_location_function
);
1400 function_name_len
= strlen(probe_function
->function_name
) + 1;
1401 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1402 storage_needed
+= function_name_len
+ binary_path_len
;
1405 * The lookup method is aligned to 64-bit within the buffer.
1406 * This is needed even if there is no lookup method since
1407 * the next structure in the buffer probably needs to be
1408 * aligned too (depending on the arch).
1410 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1411 storage_needed
+= padding_needed
;
1413 if (location
->lookup_method
) {
1414 /* NOTE: elf look-up method is assumed here. */
1415 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1419 ret
= storage_needed
;
1423 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1424 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1425 buffer
->size
+ storage_needed
);
1431 memset(&flat_probe
, 0, sizeof(flat_probe
));
1433 flat_probe_start
= buffer
->data
+ buffer
->size
;
1434 flat_probe
.parent
.type
= location
->type
;
1436 * The lookup method, if present, is the last element in the flat
1437 * representation of the probe.
1439 if (location
->lookup_method
) {
1440 flat_probe
.parent
.lookup_method
=
1441 (struct lttng_userspace_probe_location_lookup_method
*)
1442 (flat_probe_start
+ sizeof(flat_probe
) +
1443 function_name_len
+ binary_path_len
+ padding_needed
);
1445 flat_probe
.parent
.lookup_method
= NULL
;
1448 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1449 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1450 flat_probe
.binary_fd
= -1;
1451 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1452 sizeof(flat_probe
));
1457 ret
= lttng_dynamic_buffer_append(buffer
,
1458 probe_function
->function_name
, function_name_len
);
1462 ret
= lttng_dynamic_buffer_append(buffer
,
1463 probe_function
->binary_path
, binary_path_len
);
1468 /* Insert padding before the lookup method. */
1469 ret
= lttng_dynamic_buffer_set_size(buffer
,
1470 buffer
->size
+ padding_needed
);
1475 if (!location
->lookup_method
) {
1476 /* Not an error, the default method is used. */
1477 ret
= storage_needed
;
1481 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1482 flat_lookup_method
.parent
.type
=
1483 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1484 ret
= lttng_dynamic_buffer_append(buffer
,
1485 &flat_lookup_method
, sizeof(flat_lookup_method
));
1489 ret
= storage_needed
;
1495 int lttng_userspace_probe_location_tracepoint_flatten(
1496 const struct lttng_userspace_probe_location
*location
,
1497 struct lttng_dynamic_buffer
*buffer
)
1499 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1500 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1501 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1502 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1503 size_t padding_needed
= 0;
1504 int storage_needed
= 0;
1505 char *flat_probe_start
;
1510 /* Only SDT tracepoints are supported at the moment */
1511 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1512 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1513 ret
= -LTTNG_ERR_INVALID
;
1516 probe_tracepoint
= container_of(location
,
1517 struct lttng_userspace_probe_location_tracepoint
,
1519 assert(probe_tracepoint
->probe_name
);
1520 assert(probe_tracepoint
->provider_name
);
1521 assert(probe_tracepoint
->binary_path
);
1523 /* Compute the storage space needed to flatten the probe location */
1524 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1526 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1527 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1528 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1530 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1533 * The lookup method is aligned to 64-bit within the buffer.
1534 * This is needed even if there is no lookup method since
1535 * the next structure in the buffer probably needs to be
1536 * aligned too (depending on the arch).
1538 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1539 storage_needed
+= padding_needed
;
1541 if (location
->lookup_method
) {
1542 /* NOTE: elf look-up method is assumed here. */
1544 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1548 * If the caller set buffer to NULL, return the size of the needed buffer.
1551 ret
= storage_needed
;
1555 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1556 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1557 buffer
->size
+ storage_needed
);
1563 memset(&flat_probe
, 0, sizeof(flat_probe
));
1565 flat_probe_start
= buffer
->data
+ buffer
->size
;
1566 flat_probe
.parent
.type
= location
->type
;
1569 * The lookup method, if present, is the last element in the flat
1570 * representation of the probe.
1572 if (location
->lookup_method
) {
1573 flat_probe
.parent
.lookup_method
=
1574 (struct lttng_userspace_probe_location_lookup_method
*)
1575 (flat_probe_start
+ sizeof(flat_probe
) +
1576 probe_name_len
+ provider_name_len
+
1577 binary_path_len
+ padding_needed
);
1579 flat_probe
.parent
.lookup_method
= NULL
;
1582 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1583 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1584 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1585 flat_probe
.binary_fd
= -1;
1586 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1591 /* Append all the fields to the buffer */
1592 ret
= lttng_dynamic_buffer_append(buffer
,
1593 probe_tracepoint
->probe_name
, probe_name_len
);
1597 ret
= lttng_dynamic_buffer_append(buffer
,
1598 probe_tracepoint
->provider_name
, provider_name_len
);
1602 ret
= lttng_dynamic_buffer_append(buffer
,
1603 probe_tracepoint
->binary_path
, binary_path_len
);
1608 /* Insert padding before the lookup method. */
1609 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1614 if (!location
->lookup_method
) {
1615 /* Not an error, the default method is used. */
1616 ret
= storage_needed
;
1620 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1622 flat_lookup_method
.parent
.type
=
1623 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1624 ret
= lttng_dynamic_buffer_append(buffer
,
1625 &flat_lookup_method
, sizeof(flat_lookup_method
));
1629 ret
= storage_needed
;
1635 int lttng_userspace_probe_location_flatten(
1636 const struct lttng_userspace_probe_location
*location
,
1637 struct lttng_dynamic_buffer
*buffer
)
1641 ret
= -LTTNG_ERR_INVALID
;
1645 /* Only types currently supported. */
1646 switch (location
->type
) {
1647 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1648 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1650 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1651 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1654 ret
= -LTTNG_ERR_INVALID
;
1663 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1664 const struct lttng_userspace_probe_location
*location
)
1666 struct lttng_userspace_probe_location
*new_location
= NULL
;
1667 enum lttng_userspace_probe_location_type type
;
1673 type
= lttng_userspace_probe_location_get_type(location
);
1675 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1677 lttng_userspace_probe_location_function_copy(location
);
1678 if (!new_location
) {
1682 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1684 lttng_userspace_probe_location_tracepoint_copy(location
);
1685 if (!new_location
) {
1690 new_location
= NULL
;
1694 return new_location
;