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
);
147 static struct lttng_userspace_probe_location
*
148 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
149 const char *function_name
,
150 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
154 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
155 struct lttng_userspace_probe_location
*ret
= NULL
;
156 struct lttng_userspace_probe_location_function
*location
;
159 binary_fd
= open(binary_path
, O_RDONLY
);
161 PERROR("Error opening the binary");
168 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
169 if (!function_name_copy
) {
170 PERROR("Error duplicating the function name");
174 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
175 if (!binary_path_copy
) {
176 PERROR("Error duplicating the function name");
180 location
= zmalloc(sizeof(*location
));
182 PERROR("Error allocating userspace probe location");
186 location
->function_name
= function_name_copy
;
187 location
->binary_path
= binary_path_copy
;
188 location
->binary_fd
= binary_fd
;
189 location
->instrumentation_type
=
190 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
192 ret
= &location
->parent
;
193 ret
->lookup_method
= lookup_method
;
194 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
198 free(function_name_copy
);
199 free(binary_path_copy
);
200 if (binary_fd
>= 0) {
201 if (close(binary_fd
)) {
202 PERROR("Error closing binary fd in error path");
209 static struct lttng_userspace_probe_location
*
210 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
211 const char *provider_name
, const char *probe_name
,
212 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
216 char *probe_name_copy
= NULL
;
217 char *provider_name_copy
= NULL
;
218 char *binary_path_copy
= NULL
;
219 struct lttng_userspace_probe_location
*ret
= NULL
;
220 struct lttng_userspace_probe_location_tracepoint
*location
;
223 binary_fd
= open(binary_path
, O_RDONLY
);
232 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
233 if (!probe_name_copy
) {
234 PERROR("lttng_strndup");
238 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
239 if (!provider_name_copy
) {
240 PERROR("lttng_strndup");
244 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
245 if (!binary_path_copy
) {
246 PERROR("lttng_strndup");
250 location
= zmalloc(sizeof(*location
));
256 location
->probe_name
= probe_name_copy
;
257 location
->provider_name
= provider_name_copy
;
258 location
->binary_path
= binary_path_copy
;
259 location
->binary_fd
= binary_fd
;
261 ret
= &location
->parent
;
262 ret
->lookup_method
= lookup_method
;
263 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
267 free(probe_name_copy
);
268 free(provider_name_copy
);
269 free(binary_path_copy
);
270 if (binary_fd
>= 0) {
271 if (close(binary_fd
)) {
272 PERROR("Error closing binary fd in error path");
279 struct lttng_userspace_probe_location
*
280 lttng_userspace_probe_location_function_create(const char *binary_path
,
281 const char *function_name
,
282 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
284 struct lttng_userspace_probe_location
*ret
= NULL
;
286 if (!binary_path
|| !function_name
) {
287 ERR("Invalid argument(s)");
291 switch (lttng_userspace_probe_location_lookup_method_get_type(
293 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
294 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
297 /* Invalid probe location lookup method. */
301 ret
= lttng_userspace_probe_location_function_create_no_check(
302 binary_path
, function_name
, lookup_method
, true);
307 struct lttng_userspace_probe_location
*
308 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
309 const char *provider_name
, const char *probe_name
,
310 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
312 struct lttng_userspace_probe_location
*ret
= NULL
;
314 if (!binary_path
|| !probe_name
|| !provider_name
) {
315 ERR("Invalid argument(s)");
319 switch (lttng_userspace_probe_location_lookup_method_get_type(
321 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
324 /* Invalid probe location lookup method. */
328 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
329 binary_path
, provider_name
, probe_name
, lookup_method
, true);
334 static struct lttng_userspace_probe_location_lookup_method
*
335 lttng_userspace_probe_location_lookup_method_function_elf_copy(
336 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
338 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
339 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
341 assert(lookup_method
);
342 assert(lookup_method
->type
==
343 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
345 elf_method
= zmalloc(sizeof(*elf_method
));
347 PERROR("Error allocating ELF userspace probe lookup method");
351 elf_method
->parent
.type
= lookup_method
->type
;
352 parent
= &elf_method
->parent
;
361 static struct lttng_userspace_probe_location_lookup_method
*
362 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
363 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
365 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
366 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
368 assert(lookup_method
);
369 assert(lookup_method
->type
==
370 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
372 sdt_method
= zmalloc(sizeof(*sdt_method
));
378 sdt_method
->parent
.type
= lookup_method
->type
;
379 parent
= &sdt_method
->parent
;
389 static struct lttng_userspace_probe_location
*
390 lttng_userspace_probe_location_function_copy(
391 const struct lttng_userspace_probe_location
*location
)
393 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
394 struct lttng_userspace_probe_location
*new_location
= NULL
;
395 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
396 const char *binary_path
= NULL
;
397 const char *function_name
= NULL
;
401 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
403 /* Get probe location fields */
404 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
406 ERR("Userspace probe binary path is NULL");
410 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
411 if (!function_name
) {
412 ERR("Userspace probe function name is NULL");
417 * Duplicate the binary fd if possible. The binary fd can be -1 on
420 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
424 PERROR("Error duplicating file descriptor to binary");
428 /* The original fd is not set. */
433 * Duplicate probe location method fields
435 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
436 location
->lookup_method
);
437 switch (lookup_type
) {
438 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
440 lttng_userspace_probe_location_lookup_method_function_elf_copy(
441 location
->lookup_method
);
442 if (!lookup_method
) {
447 /* Invalid probe location lookup method. */
451 /* Create the probe_location */
452 new_location
= lttng_userspace_probe_location_function_create_no_check(
453 binary_path
, function_name
, lookup_method
, false);
455 goto destroy_lookup_method
;
458 /* Set the duplicated fd to the new probe_location */
459 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
460 goto destroy_probe_location
;
465 destroy_probe_location
:
466 lttng_userspace_probe_location_destroy(new_location
);
467 destroy_lookup_method
:
468 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
470 if (close(new_fd
) < 0) {
471 PERROR("Error closing duplicated file descriptor in error path");
479 static struct lttng_userspace_probe_location
*
480 lttng_userspace_probe_location_tracepoint_copy(
481 const struct lttng_userspace_probe_location
*location
)
483 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
484 struct lttng_userspace_probe_location
*new_location
= NULL
;
485 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
486 const char *binary_path
= NULL
;
487 const char *probe_name
= NULL
;
488 const char *provider_name
= NULL
;
492 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
494 /* Get probe location fields */
495 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
497 ERR("Userspace probe binary path is NULL");
501 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
503 ERR("Userspace probe probe name is NULL");
507 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
508 if (!provider_name
) {
509 ERR("Userspace probe provider name is NULL");
513 /* Duplicate the binary fd */
514 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
518 PERROR("Error duplicating file descriptor to binary");
522 /* The original fd is not set. */
527 * Duplicate probe location method fields
529 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
530 location
->lookup_method
);
531 switch (lookup_type
) {
532 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
534 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
535 location
->lookup_method
);
536 if (!lookup_method
) {
541 /* Invalid probe location lookup method. */
545 /* Create the probe_location */
546 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
547 binary_path
, provider_name
, probe_name
, lookup_method
, false);
549 goto destroy_lookup_method
;
552 /* Set the duplicated fd to the new probe_location */
553 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
554 goto destroy_probe_location
;
559 destroy_probe_location
:
560 lttng_userspace_probe_location_destroy(new_location
);
561 destroy_lookup_method
:
562 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
564 if (close(new_fd
) < 0) {
565 PERROR("Error closing duplicated file descriptor in error path");
573 const char *lttng_userspace_probe_location_function_get_binary_path(
574 const struct lttng_userspace_probe_location
*location
)
576 const char *ret
= NULL
;
577 struct lttng_userspace_probe_location_function
*function_location
;
579 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
580 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
581 ERR("Invalid argument(s)");
585 function_location
= container_of(location
,
586 struct lttng_userspace_probe_location_function
,
588 ret
= function_location
->binary_path
;
593 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
594 const struct lttng_userspace_probe_location
*location
)
596 const char *ret
= NULL
;
597 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
599 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
600 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
601 ERR("Invalid argument(s)");
605 tracepoint_location
= container_of(location
,
606 struct lttng_userspace_probe_location_tracepoint
,
608 ret
= tracepoint_location
->binary_path
;
613 const char *lttng_userspace_probe_location_function_get_function_name(
614 const struct lttng_userspace_probe_location
*location
)
616 const char *ret
= NULL
;
617 struct lttng_userspace_probe_location_function
*function_location
;
619 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
620 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
621 ERR("Invalid argument(s)");
625 function_location
= container_of(location
,
626 struct lttng_userspace_probe_location_function
, parent
);
627 ret
= function_location
->function_name
;
632 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
633 const struct lttng_userspace_probe_location
*location
)
635 const char *ret
= NULL
;
636 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
638 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
639 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
640 ERR("Invalid argument(s)");
644 tracepoint_location
= container_of(location
,
645 struct lttng_userspace_probe_location_tracepoint
, parent
);
646 ret
= tracepoint_location
->probe_name
;
651 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
652 const struct lttng_userspace_probe_location
*location
)
654 const char *ret
= NULL
;
655 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
657 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
658 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
659 ERR("Invalid argument(s)");
663 tracepoint_location
= container_of(location
,
664 struct lttng_userspace_probe_location_tracepoint
, parent
);
665 ret
= tracepoint_location
->provider_name
;
670 int lttng_userspace_probe_location_function_get_binary_fd(
671 const struct lttng_userspace_probe_location
*location
)
674 struct lttng_userspace_probe_location_function
*function_location
;
676 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
677 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
678 ERR("Invalid argument(s)");
682 function_location
= container_of(location
,
683 struct lttng_userspace_probe_location_function
, parent
);
684 ret
= function_location
->binary_fd
;
689 enum lttng_userspace_probe_location_function_instrumentation_type
690 lttng_userspace_probe_location_function_get_instrumentation_type(
691 const struct lttng_userspace_probe_location
*location
)
693 enum lttng_userspace_probe_location_function_instrumentation_type type
;
694 struct lttng_userspace_probe_location_function
*function_location
;
696 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
697 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
698 ERR("Invalid argument(s)");
699 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
703 function_location
= container_of(location
,
704 struct lttng_userspace_probe_location_function
, parent
);
705 type
= function_location
->instrumentation_type
;
710 enum lttng_userspace_probe_location_status
711 lttng_userspace_probe_location_function_set_instrumentation_type(
712 const struct lttng_userspace_probe_location
*location
,
713 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
715 enum lttng_userspace_probe_location_status status
=
716 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
717 struct lttng_userspace_probe_location_function
*function_location
;
719 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
720 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
721 instrumentation_type
!=
722 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
723 ERR("Invalid argument(s)");
724 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
728 function_location
= container_of(location
,
729 struct lttng_userspace_probe_location_function
, parent
);
730 function_location
->instrumentation_type
= instrumentation_type
;
735 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
736 const struct lttng_userspace_probe_location
*location
)
739 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
741 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
742 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
743 ERR("Invalid argument(s)");
747 tracepoint_location
= container_of(location
,
748 struct lttng_userspace_probe_location_tracepoint
, parent
);
749 ret
= tracepoint_location
->binary_fd
;
754 static struct lttng_userspace_probe_location_lookup_method
*
755 lttng_userspace_probe_location_function_get_lookup_method(
756 const struct lttng_userspace_probe_location
*location
)
758 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
760 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
761 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
762 ERR("Invalid argument(s)");
766 ret
= location
->lookup_method
;
771 static struct lttng_userspace_probe_location_lookup_method
*
772 lttng_userspace_probe_location_tracepoint_get_lookup_method(
773 const struct lttng_userspace_probe_location
*location
)
775 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
777 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
778 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
779 ERR("Invalid argument(s)");
783 ret
= location
->lookup_method
;
788 const struct lttng_userspace_probe_location_lookup_method
*
789 lttng_userspace_probe_location_get_lookup_method(
790 const struct lttng_userspace_probe_location
*location
)
792 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
795 switch (location
->type
) {
796 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
797 ret
= lttng_userspace_probe_location_function_get_lookup_method(
800 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
801 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
805 ERR("Unknowned lookup method.");
812 int lttng_userspace_probe_location_lookup_method_serialize(
813 struct lttng_userspace_probe_location_lookup_method
*method
,
814 struct lttng_dynamic_buffer
*buffer
)
817 struct lttng_userspace_probe_location_lookup_method_comm
820 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
821 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
823 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
824 sizeof(lookup_method_comm
));
829 ret
= sizeof(lookup_method_comm
);
835 int lttng_userspace_probe_location_function_serialize(
836 const struct lttng_userspace_probe_location
*location
,
837 struct lttng_dynamic_buffer
*buffer
,
841 size_t function_name_len
, binary_path_len
;
842 struct lttng_userspace_probe_location_function
*location_function
;
843 struct lttng_userspace_probe_location_function_comm location_function_comm
;
846 assert(lttng_userspace_probe_location_get_type(location
) ==
847 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
849 location_function
= container_of(location
,
850 struct lttng_userspace_probe_location_function
,
852 if (!location_function
->function_name
|| !location_function
->binary_path
) {
853 ret
= -LTTNG_ERR_INVALID
;
857 if (binary_fd
&& location_function
->binary_fd
< 0) {
858 ret
= -LTTNG_ERR_INVALID
;
863 *binary_fd
= location_function
->binary_fd
;
866 function_name_len
= strlen(location_function
->function_name
);
867 if (function_name_len
== 0) {
868 ret
= -LTTNG_ERR_INVALID
;
871 binary_path_len
= strlen(location_function
->binary_path
);
872 if (binary_path_len
== 0) {
873 ret
= -LTTNG_ERR_INVALID
;
877 location_function_comm
.function_name_len
= function_name_len
+ 1;
878 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
881 ret
= lttng_dynamic_buffer_append(buffer
,
882 &location_function_comm
,
883 sizeof(location_function_comm
));
885 ret
= -LTTNG_ERR_INVALID
;
888 ret
= lttng_dynamic_buffer_append(buffer
,
889 location_function
->function_name
,
890 location_function_comm
.function_name_len
);
892 ret
= -LTTNG_ERR_INVALID
;
895 ret
= lttng_dynamic_buffer_append(buffer
,
896 location_function
->binary_path
,
897 location_function_comm
.binary_path_len
);
899 ret
= -LTTNG_ERR_INVALID
;
903 ret
= sizeof(location_function_comm
) +
904 location_function_comm
.function_name_len
+
905 location_function_comm
.binary_path_len
;
911 int lttng_userspace_probe_location_tracepoint_serialize(
912 const struct lttng_userspace_probe_location
*location
,
913 struct lttng_dynamic_buffer
*buffer
,
917 size_t probe_name_len
, provider_name_len
, binary_path_len
;
918 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
919 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
922 assert(lttng_userspace_probe_location_get_type(location
) ==
923 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
925 location_tracepoint
= container_of(location
,
926 struct lttng_userspace_probe_location_tracepoint
,
928 if (!location_tracepoint
->probe_name
||
929 !location_tracepoint
->provider_name
||
930 !location_tracepoint
->binary_path
) {
931 ret
= -LTTNG_ERR_INVALID
;
935 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
936 ret
= -LTTNG_ERR_INVALID
;
941 *binary_fd
= location_tracepoint
->binary_fd
;
944 probe_name_len
= strlen(location_tracepoint
->probe_name
);
945 if (probe_name_len
== 0) {
946 ret
= -LTTNG_ERR_INVALID
;
950 provider_name_len
= strlen(location_tracepoint
->provider_name
);
951 if (provider_name_len
== 0) {
952 ret
= -LTTNG_ERR_INVALID
;
956 binary_path_len
= strlen(location_tracepoint
->binary_path
);
957 if (binary_path_len
== 0) {
958 ret
= -LTTNG_ERR_INVALID
;
962 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
963 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
964 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
967 ret
= lttng_dynamic_buffer_append(buffer
,
968 &location_tracepoint_comm
,
969 sizeof(location_tracepoint_comm
));
971 ret
= -LTTNG_ERR_INVALID
;
974 ret
= lttng_dynamic_buffer_append(buffer
,
975 location_tracepoint
->probe_name
,
976 location_tracepoint_comm
.probe_name_len
);
978 ret
= -LTTNG_ERR_INVALID
;
981 ret
= lttng_dynamic_buffer_append(buffer
,
982 location_tracepoint
->provider_name
,
983 location_tracepoint_comm
.provider_name_len
);
985 ret
= -LTTNG_ERR_INVALID
;
988 ret
= lttng_dynamic_buffer_append(buffer
,
989 location_tracepoint
->binary_path
,
990 location_tracepoint_comm
.binary_path_len
);
992 ret
= -LTTNG_ERR_INVALID
;
996 ret
= sizeof(location_tracepoint_comm
) +
997 location_tracepoint_comm
.probe_name_len
+
998 location_tracepoint_comm
.provider_name_len
+
999 location_tracepoint_comm
.binary_path_len
;
1005 int lttng_userspace_probe_location_serialize(
1006 const struct lttng_userspace_probe_location
*location
,
1007 struct lttng_dynamic_buffer
*buffer
,
1010 int ret
, buffer_use
= 0;
1011 struct lttng_userspace_probe_location_comm location_generic_comm
;
1014 ERR("Invalid argument(s)");
1015 ret
= -LTTNG_ERR_INVALID
;
1019 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1021 location_generic_comm
.type
= (int8_t) location
->type
;
1023 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1024 sizeof(location_generic_comm
));
1029 buffer_use
+= sizeof(location_generic_comm
);
1031 switch (lttng_userspace_probe_location_get_type(location
)) {
1032 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1033 ret
= lttng_userspace_probe_location_function_serialize(
1034 location
, buffer
, binary_fd
);
1036 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1037 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1038 location
, buffer
, binary_fd
);
1041 ERR("Unsupported probe location type");
1042 ret
= -LTTNG_ERR_INVALID
;
1050 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1051 location
->lookup_method
, buffer
);
1061 int lttng_userspace_probe_location_function_create_from_buffer(
1062 const struct lttng_buffer_view
*buffer
,
1063 struct lttng_userspace_probe_location
**location
)
1065 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1066 const char *function_name_src
, *binary_path_src
;
1067 char *function_name
= NULL
, *binary_path
= NULL
;
1071 assert(buffer
->data
);
1074 location_function_comm
=
1075 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1077 const size_t expected_size
= sizeof(*location_function_comm
) +
1078 location_function_comm
->function_name_len
+
1079 location_function_comm
->binary_path_len
;
1081 if (buffer
->size
< expected_size
) {
1082 ret
= -LTTNG_ERR_INVALID
;
1086 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1087 binary_path_src
= function_name_src
+
1088 location_function_comm
->function_name_len
;
1090 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1091 ret
= -LTTNG_ERR_INVALID
;
1094 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1095 ret
= -LTTNG_ERR_INVALID
;
1099 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1100 if (!function_name
) {
1101 PERROR("lttng_strndup");
1102 ret
= -LTTNG_ERR_NOMEM
;
1106 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1108 PERROR("lttng_strndup");
1109 ret
= -LTTNG_ERR_NOMEM
;
1113 *location
= lttng_userspace_probe_location_function_create_no_check(
1114 binary_path
, function_name
, NULL
, false);
1116 ret
= -LTTNG_ERR_INVALID
;
1120 ret
= (int) expected_size
;
1122 free(function_name
);
1128 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1129 const struct lttng_buffer_view
*buffer
,
1130 struct lttng_userspace_probe_location
**location
)
1132 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1133 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1134 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1138 assert(buffer
->data
);
1141 location_tracepoint_comm
=
1142 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1144 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1145 location_tracepoint_comm
->probe_name_len
+
1146 location_tracepoint_comm
->provider_name_len
+
1147 location_tracepoint_comm
->binary_path_len
;
1149 if (buffer
->size
< expected_size
) {
1150 ret
= -LTTNG_ERR_INVALID
;
1154 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1155 provider_name_src
= probe_name_src
+
1156 location_tracepoint_comm
->probe_name_len
;
1157 binary_path_src
= provider_name_src
+
1158 location_tracepoint_comm
->provider_name_len
;
1160 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1161 ret
= -LTTNG_ERR_INVALID
;
1165 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1166 ret
= -LTTNG_ERR_INVALID
;
1170 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1171 ret
= -LTTNG_ERR_INVALID
;
1175 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1177 PERROR("Failed to allocate probe name");
1178 ret
= -LTTNG_ERR_INVALID
;
1181 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1182 if (!provider_name
) {
1183 PERROR("Failed to allocate provider name");
1184 ret
= -LTTNG_ERR_INVALID
;
1188 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1190 PERROR("Failed to allocate binary path");
1191 ret
= -LTTNG_ERR_INVALID
;
1195 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1196 binary_path
, provider_name
, probe_name
, NULL
, false);
1198 ret
= -LTTNG_ERR_INVALID
;
1202 ret
= (int) expected_size
;
1205 free(provider_name
);
1211 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1212 struct lttng_buffer_view
*buffer
,
1213 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1216 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1217 enum lttng_userspace_probe_location_lookup_method_type type
;
1220 assert(buffer
->data
);
1221 assert(lookup_method
);
1223 if (buffer
->size
< sizeof(*lookup_comm
)) {
1224 ret
= -LTTNG_ERR_INVALID
;
1228 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1230 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1233 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1234 *lookup_method
= NULL
;
1236 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1238 lttng_userspace_probe_location_lookup_method_function_elf_create();
1239 if (!(*lookup_method
)) {
1240 ret
= -LTTNG_ERR_INVALID
;
1244 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1246 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1247 if (!(*lookup_method
)) {
1248 ret
= -LTTNG_ERR_INVALID
;
1253 ret
= -LTTNG_ERR_INVALID
;
1257 ret
= sizeof(*lookup_comm
);
1263 int lttng_userspace_probe_location_create_from_buffer(
1264 const struct lttng_buffer_view
*buffer
,
1265 struct lttng_userspace_probe_location
**location
)
1267 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1268 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1269 enum lttng_userspace_probe_location_type type
;
1270 struct lttng_buffer_view lookup_method_view
;
1276 assert(buffer
->data
);
1279 lookup_method
= NULL
;
1281 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1282 ret
= -LTTNG_ERR_INVALID
;
1286 probe_location_comm
=
1287 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1288 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1289 consumed
+= sizeof(*probe_location_comm
);
1292 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1294 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1295 buffer
, consumed
, buffer
->size
- consumed
);
1297 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1304 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1306 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1307 buffer
, consumed
, buffer
->size
- consumed
);
1309 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1317 ret
= -LTTNG_ERR_INVALID
;
1322 if (buffer
->size
<= consumed
) {
1323 ret
= -LTTNG_ERR_INVALID
;
1327 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1328 buffer
->size
- consumed
);
1329 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1330 &lookup_method_view
, &lookup_method
);
1332 ret
= -LTTNG_ERR_INVALID
;
1336 assert(lookup_method
);
1337 (*location
)->lookup_method
= lookup_method
;
1338 lookup_method
= NULL
;
1345 int lttng_userspace_probe_location_function_set_binary_fd(
1346 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1349 struct lttng_userspace_probe_location_function
*function_location
;
1352 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1354 function_location
= container_of(location
,
1355 struct lttng_userspace_probe_location_function
, parent
);
1356 if (function_location
->binary_fd
>= 0) {
1357 ret
= close(function_location
->binary_fd
);
1360 ret
= -LTTNG_ERR_INVALID
;
1365 function_location
->binary_fd
= binary_fd
;
1371 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1372 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1375 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1378 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1380 tracepoint_location
= container_of(location
,
1381 struct lttng_userspace_probe_location_tracepoint
, parent
);
1382 if (tracepoint_location
->binary_fd
>= 0) {
1383 ret
= close(tracepoint_location
->binary_fd
);
1386 ret
= -LTTNG_ERR_INVALID
;
1391 tracepoint_location
->binary_fd
= binary_fd
;
1397 int lttng_userspace_probe_location_function_flatten(
1398 const struct lttng_userspace_probe_location
*location
,
1399 struct lttng_dynamic_buffer
*buffer
)
1401 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1402 struct lttng_userspace_probe_location_function
*probe_function
;
1403 struct lttng_userspace_probe_location_function flat_probe
;
1404 size_t function_name_len
, binary_path_len
;
1405 size_t padding_needed
= 0;
1406 char *flat_probe_start
;
1407 int storage_needed
= 0;
1412 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1413 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1414 ret
= -LTTNG_ERR_INVALID
;
1418 probe_function
= container_of(location
,
1419 struct lttng_userspace_probe_location_function
,
1421 assert(probe_function
->function_name
);
1422 assert(probe_function
->binary_path
);
1425 sizeof(struct lttng_userspace_probe_location_function
);
1426 function_name_len
= strlen(probe_function
->function_name
) + 1;
1427 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1428 storage_needed
+= function_name_len
+ binary_path_len
;
1431 * The lookup method is aligned to 64-bit within the buffer.
1432 * This is needed even if there is no lookup method since
1433 * the next structure in the buffer probably needs to be
1434 * aligned too (depending on the arch).
1436 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1437 storage_needed
+= padding_needed
;
1439 if (location
->lookup_method
) {
1440 /* NOTE: elf look-up method is assumed here. */
1441 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1445 ret
= storage_needed
;
1449 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1450 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1451 buffer
->size
+ storage_needed
);
1457 memset(&flat_probe
, 0, sizeof(flat_probe
));
1459 flat_probe_start
= buffer
->data
+ buffer
->size
;
1460 flat_probe
.parent
.type
= location
->type
;
1462 * The lookup method, if present, is the last element in the flat
1463 * representation of the probe.
1465 if (location
->lookup_method
) {
1466 flat_probe
.parent
.lookup_method
=
1467 (struct lttng_userspace_probe_location_lookup_method
*)
1468 (flat_probe_start
+ sizeof(flat_probe
) +
1469 function_name_len
+ binary_path_len
+ padding_needed
);
1471 flat_probe
.parent
.lookup_method
= NULL
;
1474 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1475 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1476 flat_probe
.binary_fd
= -1;
1477 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1478 sizeof(flat_probe
));
1483 ret
= lttng_dynamic_buffer_append(buffer
,
1484 probe_function
->function_name
, function_name_len
);
1488 ret
= lttng_dynamic_buffer_append(buffer
,
1489 probe_function
->binary_path
, binary_path_len
);
1494 /* Insert padding before the lookup method. */
1495 ret
= lttng_dynamic_buffer_set_size(buffer
,
1496 buffer
->size
+ padding_needed
);
1501 if (!location
->lookup_method
) {
1502 /* Not an error, the default method is used. */
1503 ret
= storage_needed
;
1507 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1508 flat_lookup_method
.parent
.type
=
1509 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1510 ret
= lttng_dynamic_buffer_append(buffer
,
1511 &flat_lookup_method
, sizeof(flat_lookup_method
));
1515 ret
= storage_needed
;
1521 int lttng_userspace_probe_location_tracepoint_flatten(
1522 const struct lttng_userspace_probe_location
*location
,
1523 struct lttng_dynamic_buffer
*buffer
)
1525 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1526 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1527 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1528 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1529 size_t padding_needed
= 0;
1530 int storage_needed
= 0;
1531 char *flat_probe_start
;
1536 /* Only SDT tracepoints are supported at the moment */
1537 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1538 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1539 ret
= -LTTNG_ERR_INVALID
;
1542 probe_tracepoint
= container_of(location
,
1543 struct lttng_userspace_probe_location_tracepoint
,
1545 assert(probe_tracepoint
->probe_name
);
1546 assert(probe_tracepoint
->provider_name
);
1547 assert(probe_tracepoint
->binary_path
);
1549 /* Compute the storage space needed to flatten the probe location */
1550 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1552 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1553 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1554 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1556 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1559 * The lookup method is aligned to 64-bit within the buffer.
1560 * This is needed even if there is no lookup method since
1561 * the next structure in the buffer probably needs to be
1562 * aligned too (depending on the arch).
1564 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1565 storage_needed
+= padding_needed
;
1567 if (location
->lookup_method
) {
1568 /* NOTE: elf look-up method is assumed here. */
1570 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1574 * If the caller set buffer to NULL, return the size of the needed buffer.
1577 ret
= storage_needed
;
1581 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1582 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1583 buffer
->size
+ storage_needed
);
1589 memset(&flat_probe
, 0, sizeof(flat_probe
));
1591 flat_probe_start
= buffer
->data
+ buffer
->size
;
1592 flat_probe
.parent
.type
= location
->type
;
1595 * The lookup method, if present, is the last element in the flat
1596 * representation of the probe.
1598 if (location
->lookup_method
) {
1599 flat_probe
.parent
.lookup_method
=
1600 (struct lttng_userspace_probe_location_lookup_method
*)
1601 (flat_probe_start
+ sizeof(flat_probe
) +
1602 probe_name_len
+ provider_name_len
+
1603 binary_path_len
+ padding_needed
);
1605 flat_probe
.parent
.lookup_method
= NULL
;
1608 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1609 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1610 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1611 flat_probe
.binary_fd
= -1;
1612 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1617 /* Append all the fields to the buffer */
1618 ret
= lttng_dynamic_buffer_append(buffer
,
1619 probe_tracepoint
->probe_name
, probe_name_len
);
1623 ret
= lttng_dynamic_buffer_append(buffer
,
1624 probe_tracepoint
->provider_name
, provider_name_len
);
1628 ret
= lttng_dynamic_buffer_append(buffer
,
1629 probe_tracepoint
->binary_path
, binary_path_len
);
1634 /* Insert padding before the lookup method. */
1635 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1640 if (!location
->lookup_method
) {
1641 /* Not an error, the default method is used. */
1642 ret
= storage_needed
;
1646 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1648 flat_lookup_method
.parent
.type
=
1649 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1650 ret
= lttng_dynamic_buffer_append(buffer
,
1651 &flat_lookup_method
, sizeof(flat_lookup_method
));
1655 ret
= storage_needed
;
1661 int lttng_userspace_probe_location_flatten(
1662 const struct lttng_userspace_probe_location
*location
,
1663 struct lttng_dynamic_buffer
*buffer
)
1667 ret
= -LTTNG_ERR_INVALID
;
1671 /* Only types currently supported. */
1672 switch (location
->type
) {
1673 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1674 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1676 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1677 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1680 ret
= -LTTNG_ERR_INVALID
;
1689 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1690 const struct lttng_userspace_probe_location
*location
)
1692 struct lttng_userspace_probe_location
*new_location
= NULL
;
1693 enum lttng_userspace_probe_location_type type
;
1699 type
= lttng_userspace_probe_location_get_type(location
);
1701 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1703 lttng_userspace_probe_location_function_copy(location
);
1704 if (!new_location
) {
1708 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1710 lttng_userspace_probe_location_tracepoint_copy(location
);
1711 if (!new_location
) {
1716 new_location
= NULL
;
1720 return new_location
;