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");
416 /* Duplicate the binary fd */
417 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
419 ERR("Error getting file descriptor to binary");
425 PERROR("Error duplicating file descriptor to binary");
430 * Duplicate probe location method fields
432 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
433 location
->lookup_method
);
434 switch (lookup_type
) {
435 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
437 lttng_userspace_probe_location_lookup_method_function_elf_copy(
438 location
->lookup_method
);
439 if (!lookup_method
) {
444 /* Invalid probe location lookup method. */
448 /* Create the probe_location */
449 new_location
= lttng_userspace_probe_location_function_create_no_check(
450 binary_path
, function_name
, lookup_method
, false);
452 goto destroy_lookup_method
;
455 /* Set the duplicated fd to the new probe_location */
456 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
457 goto destroy_probe_location
;
462 destroy_probe_location
:
463 lttng_userspace_probe_location_destroy(new_location
);
464 destroy_lookup_method
:
465 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
467 if (close(new_fd
) < 0) {
468 PERROR("Error closing duplicated file descriptor in error path");
476 static struct lttng_userspace_probe_location
*
477 lttng_userspace_probe_location_tracepoint_copy(
478 const struct lttng_userspace_probe_location
*location
)
480 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
481 struct lttng_userspace_probe_location
*new_location
= NULL
;
482 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
483 const char *binary_path
= NULL
;
484 const char *probe_name
= NULL
;
485 const char *provider_name
= NULL
;
489 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
491 /* Get probe location fields */
492 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
494 ERR("Userspace probe binary path is NULL");
498 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
500 ERR("Userspace probe probe name is NULL");
504 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
505 if (!provider_name
) {
506 ERR("Userspace probe provider name is NULL");
510 /* Duplicate the binary fd */
511 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
513 ERR("Error getting file descriptor to binary");
519 PERROR("Error duplicating file descriptor to binary");
524 * Duplicate probe location method fields
526 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
527 location
->lookup_method
);
528 switch (lookup_type
) {
529 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
531 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
532 location
->lookup_method
);
533 if (!lookup_method
) {
538 /* Invalid probe location lookup method. */
542 /* Create the probe_location */
543 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
544 binary_path
, provider_name
, probe_name
, lookup_method
, false);
546 goto destroy_lookup_method
;
549 /* Set the duplicated fd to the new probe_location */
550 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
551 goto destroy_probe_location
;
556 destroy_probe_location
:
557 lttng_userspace_probe_location_destroy(new_location
);
558 destroy_lookup_method
:
559 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
561 if (close(new_fd
) < 0) {
562 PERROR("Error closing duplicated file descriptor in error path");
570 const char *lttng_userspace_probe_location_function_get_binary_path(
571 const struct lttng_userspace_probe_location
*location
)
573 const char *ret
= NULL
;
574 struct lttng_userspace_probe_location_function
*function_location
;
576 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
577 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
578 ERR("Invalid argument(s)");
582 function_location
= container_of(location
,
583 struct lttng_userspace_probe_location_function
,
585 ret
= function_location
->binary_path
;
590 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
591 const struct lttng_userspace_probe_location
*location
)
593 const char *ret
= NULL
;
594 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
596 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
597 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
598 ERR("Invalid argument(s)");
602 tracepoint_location
= container_of(location
,
603 struct lttng_userspace_probe_location_tracepoint
,
605 ret
= tracepoint_location
->binary_path
;
610 const char *lttng_userspace_probe_location_function_get_function_name(
611 const struct lttng_userspace_probe_location
*location
)
613 const char *ret
= NULL
;
614 struct lttng_userspace_probe_location_function
*function_location
;
616 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
617 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
618 ERR("Invalid argument(s)");
622 function_location
= container_of(location
,
623 struct lttng_userspace_probe_location_function
, parent
);
624 ret
= function_location
->function_name
;
629 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
630 const struct lttng_userspace_probe_location
*location
)
632 const char *ret
= NULL
;
633 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
635 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
636 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
637 ERR("Invalid argument(s)");
641 tracepoint_location
= container_of(location
,
642 struct lttng_userspace_probe_location_tracepoint
, parent
);
643 ret
= tracepoint_location
->probe_name
;
648 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
649 const struct lttng_userspace_probe_location
*location
)
651 const char *ret
= NULL
;
652 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
654 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
655 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
656 ERR("Invalid argument(s)");
660 tracepoint_location
= container_of(location
,
661 struct lttng_userspace_probe_location_tracepoint
, parent
);
662 ret
= tracepoint_location
->provider_name
;
667 int lttng_userspace_probe_location_function_get_binary_fd(
668 const struct lttng_userspace_probe_location
*location
)
671 struct lttng_userspace_probe_location_function
*function_location
;
673 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
674 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
675 ERR("Invalid argument(s)");
679 function_location
= container_of(location
,
680 struct lttng_userspace_probe_location_function
, parent
);
681 ret
= function_location
->binary_fd
;
686 enum lttng_userspace_probe_location_function_instrumentation_type
687 lttng_userspace_probe_location_function_get_instrumentation_type(
688 const struct lttng_userspace_probe_location
*location
)
690 enum lttng_userspace_probe_location_function_instrumentation_type type
;
691 struct lttng_userspace_probe_location_function
*function_location
;
693 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
694 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
695 ERR("Invalid argument(s)");
696 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
700 function_location
= container_of(location
,
701 struct lttng_userspace_probe_location_function
, parent
);
702 type
= function_location
->instrumentation_type
;
707 enum lttng_userspace_probe_location_status
708 lttng_userspace_probe_location_function_set_instrumentation_type(
709 const struct lttng_userspace_probe_location
*location
,
710 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
712 enum lttng_userspace_probe_location_status status
=
713 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
714 struct lttng_userspace_probe_location_function
*function_location
;
716 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
717 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
718 instrumentation_type
!=
719 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
720 ERR("Invalid argument(s)");
721 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
725 function_location
= container_of(location
,
726 struct lttng_userspace_probe_location_function
, parent
);
727 function_location
->instrumentation_type
= instrumentation_type
;
732 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
733 const struct lttng_userspace_probe_location
*location
)
736 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
738 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
739 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
740 ERR("Invalid argument(s)");
744 tracepoint_location
= container_of(location
,
745 struct lttng_userspace_probe_location_tracepoint
, parent
);
746 ret
= tracepoint_location
->binary_fd
;
751 static struct lttng_userspace_probe_location_lookup_method
*
752 lttng_userspace_probe_location_function_get_lookup_method(
753 const struct lttng_userspace_probe_location
*location
)
755 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
757 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
758 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
759 ERR("Invalid argument(s)");
763 ret
= location
->lookup_method
;
768 static struct lttng_userspace_probe_location_lookup_method
*
769 lttng_userspace_probe_location_tracepoint_get_lookup_method(
770 const struct lttng_userspace_probe_location
*location
)
772 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
774 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
775 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
776 ERR("Invalid argument(s)");
780 ret
= location
->lookup_method
;
785 const struct lttng_userspace_probe_location_lookup_method
*
786 lttng_userspace_probe_location_get_lookup_method(
787 const struct lttng_userspace_probe_location
*location
)
789 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
792 switch (location
->type
) {
793 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
794 ret
= lttng_userspace_probe_location_function_get_lookup_method(
797 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
798 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
802 ERR("Unknowned lookup method.");
809 int lttng_userspace_probe_location_lookup_method_serialize(
810 struct lttng_userspace_probe_location_lookup_method
*method
,
811 struct lttng_dynamic_buffer
*buffer
)
814 struct lttng_userspace_probe_location_lookup_method_comm
817 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
818 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
820 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
821 sizeof(lookup_method_comm
));
826 ret
= sizeof(lookup_method_comm
);
832 int lttng_userspace_probe_location_function_serialize(
833 const struct lttng_userspace_probe_location
*location
,
834 struct lttng_dynamic_buffer
*buffer
,
838 size_t function_name_len
, binary_path_len
;
839 struct lttng_userspace_probe_location_function
*location_function
;
840 struct lttng_userspace_probe_location_function_comm location_function_comm
;
843 assert(lttng_userspace_probe_location_get_type(location
) ==
844 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
846 location_function
= container_of(location
,
847 struct lttng_userspace_probe_location_function
,
849 if (!location_function
->function_name
|| !location_function
->binary_path
) {
850 ret
= -LTTNG_ERR_INVALID
;
854 if (binary_fd
&& location_function
->binary_fd
< 0) {
855 ret
= -LTTNG_ERR_INVALID
;
860 *binary_fd
= location_function
->binary_fd
;
863 function_name_len
= strlen(location_function
->function_name
);
864 if (function_name_len
== 0) {
865 ret
= -LTTNG_ERR_INVALID
;
868 binary_path_len
= strlen(location_function
->binary_path
);
869 if (binary_path_len
== 0) {
870 ret
= -LTTNG_ERR_INVALID
;
874 location_function_comm
.function_name_len
= function_name_len
+ 1;
875 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
878 ret
= lttng_dynamic_buffer_append(buffer
,
879 &location_function_comm
,
880 sizeof(location_function_comm
));
882 ret
= -LTTNG_ERR_INVALID
;
885 ret
= lttng_dynamic_buffer_append(buffer
,
886 location_function
->function_name
,
887 location_function_comm
.function_name_len
);
889 ret
= -LTTNG_ERR_INVALID
;
892 ret
= lttng_dynamic_buffer_append(buffer
,
893 location_function
->binary_path
,
894 location_function_comm
.binary_path_len
);
896 ret
= -LTTNG_ERR_INVALID
;
900 ret
= sizeof(location_function_comm
) +
901 location_function_comm
.function_name_len
+
902 location_function_comm
.binary_path_len
;
908 int lttng_userspace_probe_location_tracepoint_serialize(
909 const struct lttng_userspace_probe_location
*location
,
910 struct lttng_dynamic_buffer
*buffer
,
914 size_t probe_name_len
, provider_name_len
, binary_path_len
;
915 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
916 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
919 assert(lttng_userspace_probe_location_get_type(location
) ==
920 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
922 location_tracepoint
= container_of(location
,
923 struct lttng_userspace_probe_location_tracepoint
,
925 if (!location_tracepoint
->probe_name
||
926 !location_tracepoint
->provider_name
||
927 !location_tracepoint
->binary_path
) {
928 ret
= -LTTNG_ERR_INVALID
;
932 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
933 ret
= -LTTNG_ERR_INVALID
;
938 *binary_fd
= location_tracepoint
->binary_fd
;
941 probe_name_len
= strlen(location_tracepoint
->probe_name
);
942 if (probe_name_len
== 0) {
943 ret
= -LTTNG_ERR_INVALID
;
947 provider_name_len
= strlen(location_tracepoint
->provider_name
);
948 if (provider_name_len
== 0) {
949 ret
= -LTTNG_ERR_INVALID
;
953 binary_path_len
= strlen(location_tracepoint
->binary_path
);
954 if (binary_path_len
== 0) {
955 ret
= -LTTNG_ERR_INVALID
;
959 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
960 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
961 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
964 ret
= lttng_dynamic_buffer_append(buffer
,
965 &location_tracepoint_comm
,
966 sizeof(location_tracepoint_comm
));
968 ret
= -LTTNG_ERR_INVALID
;
971 ret
= lttng_dynamic_buffer_append(buffer
,
972 location_tracepoint
->probe_name
,
973 location_tracepoint_comm
.probe_name_len
);
975 ret
= -LTTNG_ERR_INVALID
;
978 ret
= lttng_dynamic_buffer_append(buffer
,
979 location_tracepoint
->provider_name
,
980 location_tracepoint_comm
.provider_name_len
);
982 ret
= -LTTNG_ERR_INVALID
;
985 ret
= lttng_dynamic_buffer_append(buffer
,
986 location_tracepoint
->binary_path
,
987 location_tracepoint_comm
.binary_path_len
);
989 ret
= -LTTNG_ERR_INVALID
;
993 ret
= sizeof(location_tracepoint_comm
) +
994 location_tracepoint_comm
.probe_name_len
+
995 location_tracepoint_comm
.provider_name_len
+
996 location_tracepoint_comm
.binary_path_len
;
1002 int lttng_userspace_probe_location_serialize(
1003 const struct lttng_userspace_probe_location
*location
,
1004 struct lttng_dynamic_buffer
*buffer
,
1007 int ret
, buffer_use
= 0;
1008 struct lttng_userspace_probe_location_comm location_generic_comm
;
1011 ERR("Invalid argument(s)");
1012 ret
= -LTTNG_ERR_INVALID
;
1016 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1018 location_generic_comm
.type
= (int8_t) location
->type
;
1020 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1021 sizeof(location_generic_comm
));
1026 buffer_use
+= sizeof(location_generic_comm
);
1028 switch (lttng_userspace_probe_location_get_type(location
)) {
1029 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1030 ret
= lttng_userspace_probe_location_function_serialize(
1031 location
, buffer
, binary_fd
);
1033 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1034 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1035 location
, buffer
, binary_fd
);
1038 ERR("Unsupported probe location type");
1039 ret
= -LTTNG_ERR_INVALID
;
1047 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1048 location
->lookup_method
, buffer
);
1058 int lttng_userspace_probe_location_function_create_from_buffer(
1059 const struct lttng_buffer_view
*buffer
,
1060 struct lttng_userspace_probe_location
**location
)
1062 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1063 const char *function_name_src
, *binary_path_src
;
1064 char *function_name
= NULL
, *binary_path
= NULL
;
1068 assert(buffer
->data
);
1071 location_function_comm
=
1072 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1074 const size_t expected_size
= sizeof(*location_function_comm
) +
1075 location_function_comm
->function_name_len
+
1076 location_function_comm
->binary_path_len
;
1078 if (buffer
->size
< expected_size
) {
1079 ret
= -LTTNG_ERR_INVALID
;
1083 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1084 binary_path_src
= function_name_src
+
1085 location_function_comm
->function_name_len
;
1087 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1088 ret
= -LTTNG_ERR_INVALID
;
1091 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1092 ret
= -LTTNG_ERR_INVALID
;
1096 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1097 if (!function_name
) {
1098 PERROR("lttng_strndup");
1099 ret
= -LTTNG_ERR_NOMEM
;
1103 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1105 PERROR("lttng_strndup");
1106 ret
= -LTTNG_ERR_NOMEM
;
1110 *location
= lttng_userspace_probe_location_function_create_no_check(
1111 binary_path
, function_name
, NULL
, false);
1113 ret
= -LTTNG_ERR_INVALID
;
1117 ret
= (int) expected_size
;
1119 free(function_name
);
1125 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1126 const struct lttng_buffer_view
*buffer
,
1127 struct lttng_userspace_probe_location
**location
)
1129 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1130 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1131 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1135 assert(buffer
->data
);
1138 location_tracepoint_comm
=
1139 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1141 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1142 location_tracepoint_comm
->probe_name_len
+
1143 location_tracepoint_comm
->provider_name_len
+
1144 location_tracepoint_comm
->binary_path_len
;
1146 if (buffer
->size
< expected_size
) {
1147 ret
= -LTTNG_ERR_INVALID
;
1151 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1152 provider_name_src
= probe_name_src
+
1153 location_tracepoint_comm
->probe_name_len
;
1154 binary_path_src
= provider_name_src
+
1155 location_tracepoint_comm
->provider_name_len
;
1157 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1158 ret
= -LTTNG_ERR_INVALID
;
1162 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1163 ret
= -LTTNG_ERR_INVALID
;
1167 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1168 ret
= -LTTNG_ERR_INVALID
;
1172 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1174 PERROR("Failed to allocate probe name");
1175 ret
= -LTTNG_ERR_INVALID
;
1178 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1179 if (!provider_name
) {
1180 PERROR("Failed to allocate provider name");
1181 ret
= -LTTNG_ERR_INVALID
;
1185 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1187 PERROR("Failed to allocate binary path");
1188 ret
= -LTTNG_ERR_INVALID
;
1192 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1193 binary_path
, provider_name
, probe_name
, NULL
, false);
1195 ret
= -LTTNG_ERR_INVALID
;
1199 ret
= (int) expected_size
;
1202 free(provider_name
);
1208 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1209 struct lttng_buffer_view
*buffer
,
1210 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1213 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1214 enum lttng_userspace_probe_location_lookup_method_type type
;
1217 assert(buffer
->data
);
1218 assert(lookup_method
);
1220 if (buffer
->size
< sizeof(*lookup_comm
)) {
1221 ret
= -LTTNG_ERR_INVALID
;
1225 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1227 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1230 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1231 *lookup_method
= NULL
;
1233 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1235 lttng_userspace_probe_location_lookup_method_function_elf_create();
1236 if (!(*lookup_method
)) {
1237 ret
= -LTTNG_ERR_INVALID
;
1241 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1243 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1244 if (!(*lookup_method
)) {
1245 ret
= -LTTNG_ERR_INVALID
;
1250 ret
= -LTTNG_ERR_INVALID
;
1254 ret
= sizeof(*lookup_comm
);
1260 int lttng_userspace_probe_location_create_from_buffer(
1261 const struct lttng_buffer_view
*buffer
,
1262 struct lttng_userspace_probe_location
**location
)
1264 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1265 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1266 enum lttng_userspace_probe_location_type type
;
1267 struct lttng_buffer_view lookup_method_view
;
1273 assert(buffer
->data
);
1276 lookup_method
= NULL
;
1278 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1279 ret
= -LTTNG_ERR_INVALID
;
1283 probe_location_comm
=
1284 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1285 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1286 consumed
+= sizeof(*probe_location_comm
);
1289 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1291 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1292 buffer
, consumed
, buffer
->size
- consumed
);
1294 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1301 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1303 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1304 buffer
, consumed
, buffer
->size
- consumed
);
1306 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1314 ret
= -LTTNG_ERR_INVALID
;
1319 if (buffer
->size
<= consumed
) {
1320 ret
= -LTTNG_ERR_INVALID
;
1324 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1325 buffer
->size
- consumed
);
1326 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1327 &lookup_method_view
, &lookup_method
);
1329 ret
= -LTTNG_ERR_INVALID
;
1333 assert(lookup_method
);
1334 (*location
)->lookup_method
= lookup_method
;
1335 lookup_method
= NULL
;
1342 int lttng_userspace_probe_location_function_set_binary_fd(
1343 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1346 struct lttng_userspace_probe_location_function
*function_location
;
1349 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1351 function_location
= container_of(location
,
1352 struct lttng_userspace_probe_location_function
, parent
);
1353 if (function_location
->binary_fd
>= 0) {
1354 ret
= close(function_location
->binary_fd
);
1357 ret
= -LTTNG_ERR_INVALID
;
1362 function_location
->binary_fd
= binary_fd
;
1368 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1369 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1372 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1375 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1377 tracepoint_location
= container_of(location
,
1378 struct lttng_userspace_probe_location_tracepoint
, parent
);
1379 if (tracepoint_location
->binary_fd
>= 0) {
1380 ret
= close(tracepoint_location
->binary_fd
);
1383 ret
= -LTTNG_ERR_INVALID
;
1388 tracepoint_location
->binary_fd
= binary_fd
;
1394 int lttng_userspace_probe_location_function_flatten(
1395 const struct lttng_userspace_probe_location
*location
,
1396 struct lttng_dynamic_buffer
*buffer
)
1398 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1399 struct lttng_userspace_probe_location_function
*probe_function
;
1400 struct lttng_userspace_probe_location_function flat_probe
;
1401 size_t function_name_len
, binary_path_len
;
1402 size_t padding_needed
= 0;
1403 char *flat_probe_start
;
1404 int storage_needed
= 0;
1409 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1410 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1411 ret
= -LTTNG_ERR_INVALID
;
1415 probe_function
= container_of(location
,
1416 struct lttng_userspace_probe_location_function
,
1418 assert(probe_function
->function_name
);
1419 assert(probe_function
->binary_path
);
1422 sizeof(struct lttng_userspace_probe_location_function
);
1423 function_name_len
= strlen(probe_function
->function_name
) + 1;
1424 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1425 storage_needed
+= function_name_len
+ binary_path_len
;
1428 * The lookup method is aligned to 64-bit within the buffer.
1429 * This is needed even if there is no lookup method since
1430 * the next structure in the buffer probably needs to be
1431 * aligned too (depending on the arch).
1433 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1434 storage_needed
+= padding_needed
;
1436 if (location
->lookup_method
) {
1437 /* NOTE: elf look-up method is assumed here. */
1438 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1442 ret
= storage_needed
;
1446 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1447 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1448 buffer
->size
+ storage_needed
);
1454 memset(&flat_probe
, 0, sizeof(flat_probe
));
1456 flat_probe_start
= buffer
->data
+ buffer
->size
;
1457 flat_probe
.parent
.type
= location
->type
;
1459 * The lookup method, if present, is the last element in the flat
1460 * representation of the probe.
1462 if (location
->lookup_method
) {
1463 flat_probe
.parent
.lookup_method
=
1464 (struct lttng_userspace_probe_location_lookup_method
*)
1465 (flat_probe_start
+ sizeof(flat_probe
) +
1466 function_name_len
+ binary_path_len
+ padding_needed
);
1468 flat_probe
.parent
.lookup_method
= NULL
;
1471 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1472 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1473 flat_probe
.binary_fd
= -1;
1474 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1475 sizeof(flat_probe
));
1480 ret
= lttng_dynamic_buffer_append(buffer
,
1481 probe_function
->function_name
, function_name_len
);
1485 ret
= lttng_dynamic_buffer_append(buffer
,
1486 probe_function
->binary_path
, binary_path_len
);
1491 /* Insert padding before the lookup method. */
1492 ret
= lttng_dynamic_buffer_set_size(buffer
,
1493 buffer
->size
+ padding_needed
);
1498 if (!location
->lookup_method
) {
1499 /* Not an error, the default method is used. */
1500 ret
= storage_needed
;
1504 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1505 flat_lookup_method
.parent
.type
=
1506 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1507 ret
= lttng_dynamic_buffer_append(buffer
,
1508 &flat_lookup_method
, sizeof(flat_lookup_method
));
1512 ret
= storage_needed
;
1518 int lttng_userspace_probe_location_tracepoint_flatten(
1519 const struct lttng_userspace_probe_location
*location
,
1520 struct lttng_dynamic_buffer
*buffer
)
1522 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1523 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1524 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1525 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1526 size_t padding_needed
= 0;
1527 int storage_needed
= 0;
1528 char *flat_probe_start
;
1533 /* Only SDT tracepoints are supported at the moment */
1534 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1535 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1536 ret
= -LTTNG_ERR_INVALID
;
1539 probe_tracepoint
= container_of(location
,
1540 struct lttng_userspace_probe_location_tracepoint
,
1542 assert(probe_tracepoint
->probe_name
);
1543 assert(probe_tracepoint
->provider_name
);
1544 assert(probe_tracepoint
->binary_path
);
1546 /* Compute the storage space needed to flatten the probe location */
1547 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1549 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1550 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1551 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1553 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1556 * The lookup method is aligned to 64-bit within the buffer.
1557 * This is needed even if there is no lookup method since
1558 * the next structure in the buffer probably needs to be
1559 * aligned too (depending on the arch).
1561 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1562 storage_needed
+= padding_needed
;
1564 if (location
->lookup_method
) {
1565 /* NOTE: elf look-up method is assumed here. */
1567 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1571 * If the caller set buffer to NULL, return the size of the needed buffer.
1574 ret
= storage_needed
;
1578 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1579 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1580 buffer
->size
+ storage_needed
);
1586 memset(&flat_probe
, 0, sizeof(flat_probe
));
1588 flat_probe_start
= buffer
->data
+ buffer
->size
;
1589 flat_probe
.parent
.type
= location
->type
;
1592 * The lookup method, if present, is the last element in the flat
1593 * representation of the probe.
1595 if (location
->lookup_method
) {
1596 flat_probe
.parent
.lookup_method
=
1597 (struct lttng_userspace_probe_location_lookup_method
*)
1598 (flat_probe_start
+ sizeof(flat_probe
) +
1599 probe_name_len
+ provider_name_len
+
1600 binary_path_len
+ padding_needed
);
1602 flat_probe
.parent
.lookup_method
= NULL
;
1605 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1606 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1607 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1608 flat_probe
.binary_fd
= -1;
1609 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1614 /* Append all the fields to the buffer */
1615 ret
= lttng_dynamic_buffer_append(buffer
,
1616 probe_tracepoint
->probe_name
, probe_name_len
);
1620 ret
= lttng_dynamic_buffer_append(buffer
,
1621 probe_tracepoint
->provider_name
, provider_name_len
);
1625 ret
= lttng_dynamic_buffer_append(buffer
,
1626 probe_tracepoint
->binary_path
, binary_path_len
);
1631 /* Insert padding before the lookup method. */
1632 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1637 if (!location
->lookup_method
) {
1638 /* Not an error, the default method is used. */
1639 ret
= storage_needed
;
1643 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1645 flat_lookup_method
.parent
.type
=
1646 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1647 ret
= lttng_dynamic_buffer_append(buffer
,
1648 &flat_lookup_method
, sizeof(flat_lookup_method
));
1652 ret
= storage_needed
;
1658 int lttng_userspace_probe_location_flatten(
1659 const struct lttng_userspace_probe_location
*location
,
1660 struct lttng_dynamic_buffer
*buffer
)
1664 ret
= -LTTNG_ERR_INVALID
;
1668 /* Only types currently supported. */
1669 switch (location
->type
) {
1670 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1671 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1673 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1674 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1677 ret
= -LTTNG_ERR_INVALID
;
1686 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1687 const struct lttng_userspace_probe_location
*location
)
1689 struct lttng_userspace_probe_location
*new_location
= NULL
;
1690 enum lttng_userspace_probe_location_type type
;
1696 type
= lttng_userspace_probe_location_get_type(location
);
1698 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1700 lttng_userspace_probe_location_function_copy(location
);
1701 if (!new_location
) {
1705 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1707 lttng_userspace_probe_location_tracepoint_copy(location
);
1708 if (!new_location
) {
1713 new_location
= NULL
;
1717 return new_location
;