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
)
44 struct lttng_userspace_probe_location_lookup_method
*
45 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
47 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
48 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
50 elf_method
= zmalloc(sizeof(*elf_method
));
56 ret
= &elf_method
->parent
;
57 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
62 struct lttng_userspace_probe_location_lookup_method
*
63 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
65 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
66 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
68 sdt_method
= zmalloc(sizeof(*sdt_method
));
74 ret
= &sdt_method
->parent
;
75 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
80 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
81 const struct lttng_userspace_probe_location
*location
)
83 return location
? location
->type
:
84 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
88 void lttng_userspace_probe_location_function_destroy(
89 struct lttng_userspace_probe_location
*location
)
91 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
95 location_function
= container_of(location
,
96 struct lttng_userspace_probe_location_function
, parent
);
98 assert(location_function
);
100 free(location_function
->function_name
);
101 free(location_function
->binary_path
);
102 if (location_function
->binary_fd
>= 0) {
103 if (close(location_function
->binary_fd
)) {
111 void lttng_userspace_probe_location_tracepoint_destroy(
112 struct lttng_userspace_probe_location
*location
)
114 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
= NULL
;
118 location_tracepoint
= container_of(location
,
119 struct lttng_userspace_probe_location_tracepoint
,
122 assert(location_tracepoint
);
124 free(location_tracepoint
->probe_name
);
125 free(location_tracepoint
->provider_name
);
126 free(location_tracepoint
->binary_path
);
127 if (location_tracepoint
->binary_fd
>= 0) {
128 if (close(location_tracepoint
->binary_fd
)) {
135 void lttng_userspace_probe_location_destroy(
136 struct lttng_userspace_probe_location
*location
)
142 lttng_userspace_probe_location_lookup_method_destroy(
143 location
->lookup_method
);
145 switch (location
->type
) {
146 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
147 lttng_userspace_probe_location_function_destroy(location
);
149 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
150 lttng_userspace_probe_location_tracepoint_destroy(location
);
157 static struct lttng_userspace_probe_location
*
158 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
159 const char *function_name
,
160 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
164 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
165 struct lttng_userspace_probe_location
*ret
= NULL
;
166 struct lttng_userspace_probe_location_function
*location
;
169 binary_fd
= open(binary_path
, O_RDONLY
);
171 PERROR("Error opening the binary");
178 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
179 if (!function_name_copy
) {
180 PERROR("Error duplicating the function name");
184 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
185 if (!binary_path_copy
) {
186 PERROR("Error duplicating the function name");
190 location
= zmalloc(sizeof(*location
));
192 PERROR("Error allocating userspace probe location");
196 location
->function_name
= function_name_copy
;
197 location
->binary_path
= binary_path_copy
;
198 location
->binary_fd
= binary_fd
;
199 location
->instrumentation_type
=
200 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
;
202 ret
= &location
->parent
;
203 ret
->lookup_method
= lookup_method
;
204 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
208 free(function_name_copy
);
209 free(binary_path_copy
);
210 if (binary_fd
>= 0) {
211 if (close(binary_fd
)) {
212 PERROR("Error closing binary fd in error path");
219 static struct lttng_userspace_probe_location
*
220 lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path
,
221 const char *provider_name
, const char *probe_name
,
222 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
226 char *probe_name_copy
= NULL
;
227 char *provider_name_copy
= NULL
;
228 char *binary_path_copy
= NULL
;
229 struct lttng_userspace_probe_location
*ret
= NULL
;
230 struct lttng_userspace_probe_location_tracepoint
*location
;
233 binary_fd
= open(binary_path
, O_RDONLY
);
242 probe_name_copy
= lttng_strndup(probe_name
, LTTNG_SYMBOL_NAME_LEN
);
243 if (!probe_name_copy
) {
244 PERROR("lttng_strndup");
248 provider_name_copy
= lttng_strndup(provider_name
, LTTNG_SYMBOL_NAME_LEN
);
249 if (!provider_name_copy
) {
250 PERROR("lttng_strndup");
254 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
255 if (!binary_path_copy
) {
256 PERROR("lttng_strndup");
260 location
= zmalloc(sizeof(*location
));
266 location
->probe_name
= probe_name_copy
;
267 location
->provider_name
= provider_name_copy
;
268 location
->binary_path
= binary_path_copy
;
269 location
->binary_fd
= binary_fd
;
271 ret
= &location
->parent
;
272 ret
->lookup_method
= lookup_method
;
273 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
;
277 free(probe_name_copy
);
278 free(provider_name_copy
);
279 if (binary_fd
>= 0) {
280 if (close(binary_fd
)) {
281 PERROR("Error closing binary fd in error path");
288 struct lttng_userspace_probe_location
*
289 lttng_userspace_probe_location_function_create(const char *binary_path
,
290 const char *function_name
,
291 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
293 struct lttng_userspace_probe_location
*ret
= NULL
;
295 if (!binary_path
|| !function_name
) {
296 ERR("Invalid argument(s)");
300 switch (lttng_userspace_probe_location_lookup_method_get_type(
302 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
303 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
306 /* Invalid probe location lookup method. */
310 ret
= lttng_userspace_probe_location_function_create_no_check(
311 binary_path
, function_name
, lookup_method
, true);
316 struct lttng_userspace_probe_location
*
317 lttng_userspace_probe_location_tracepoint_create(const char *binary_path
,
318 const char *provider_name
, const char *probe_name
,
319 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
321 struct lttng_userspace_probe_location
*ret
= NULL
;
323 if (!binary_path
|| !probe_name
|| !provider_name
) {
324 ERR("Invalid argument(s)");
328 switch (lttng_userspace_probe_location_lookup_method_get_type(
330 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
333 /* Invalid probe location lookup method. */
337 ret
= lttng_userspace_probe_location_tracepoint_create_no_check(
338 binary_path
, provider_name
, probe_name
, lookup_method
, true);
343 static struct lttng_userspace_probe_location_lookup_method
*
344 lttng_userspace_probe_location_lookup_method_function_elf_copy(
345 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
347 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
348 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
350 assert(lookup_method
);
351 assert(lookup_method
->type
==
352 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
354 elf_method
= zmalloc(sizeof(*elf_method
));
356 PERROR("Error allocating ELF userspace probe lookup method");
360 elf_method
->parent
.type
= lookup_method
->type
;
361 parent
= &elf_method
->parent
;
370 static struct lttng_userspace_probe_location_lookup_method
*
371 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
372 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
374 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
375 struct lttng_userspace_probe_location_lookup_method_sdt
*sdt_method
;
377 assert(lookup_method
);
378 assert(lookup_method
->type
==
379 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
);
381 sdt_method
= zmalloc(sizeof(*sdt_method
));
387 sdt_method
->parent
.type
= lookup_method
->type
;
388 parent
= &sdt_method
->parent
;
398 static struct lttng_userspace_probe_location
*
399 lttng_userspace_probe_location_function_copy(
400 const struct lttng_userspace_probe_location
*location
)
402 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
403 struct lttng_userspace_probe_location
*new_location
= NULL
;
404 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
405 const char *binary_path
= NULL
;
406 const char *function_name
= NULL
;
410 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
412 /* Get probe location fields */
413 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
415 ERR("Userspace probe binary path is NULL");
419 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
420 if (!function_name
) {
421 ERR("Userspace probe function name is NULL");
425 /* Duplicate the binary fd */
426 fd
= lttng_userspace_probe_location_function_get_binary_fd(location
);
428 ERR("Error getting file descriptor to binary");
434 PERROR("Error duplicating file descriptor to binary");
439 * Duplicate probe location method fields
441 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
442 location
->lookup_method
);
443 switch (lookup_type
) {
444 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
446 lttng_userspace_probe_location_lookup_method_function_elf_copy(
447 location
->lookup_method
);
448 if (!lookup_method
) {
453 /* Invalid probe location lookup method. */
457 /* Create the probe_location */
458 new_location
= lttng_userspace_probe_location_function_create_no_check(
459 binary_path
, function_name
, lookup_method
, false);
461 goto destroy_lookup_method
;
464 /* Set the duplicated fd to the new probe_location */
465 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, new_fd
) < 0) {
466 goto destroy_probe_location
;
471 destroy_probe_location
:
472 lttng_userspace_probe_location_destroy(new_location
);
473 destroy_lookup_method
:
474 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
476 if (close(new_fd
) < 0) {
477 PERROR("Error closing duplicated file descriptor in error path");
485 static struct lttng_userspace_probe_location
*
486 lttng_userspace_probe_location_tracepoint_copy(
487 const struct lttng_userspace_probe_location
*location
)
489 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
490 struct lttng_userspace_probe_location
*new_location
= NULL
;
491 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
492 const char *binary_path
= NULL
;
493 const char *probe_name
= NULL
;
494 const char *provider_name
= NULL
;
498 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
500 /* Get probe location fields */
501 binary_path
= lttng_userspace_probe_location_tracepoint_get_binary_path(location
);
503 ERR("Userspace probe binary path is NULL");
507 probe_name
= lttng_userspace_probe_location_tracepoint_get_probe_name(location
);
509 ERR("Userspace probe probe name is NULL");
513 provider_name
= lttng_userspace_probe_location_tracepoint_get_provider_name(location
);
514 if (!provider_name
) {
515 ERR("Userspace probe provider name is NULL");
519 /* Duplicate the binary fd */
520 fd
= lttng_userspace_probe_location_tracepoint_get_binary_fd(location
);
522 ERR("Error getting file descriptor to binary");
528 PERROR("Error duplicating file descriptor to binary");
533 * Duplicate probe location method fields
535 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
536 location
->lookup_method
);
537 switch (lookup_type
) {
538 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
540 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
541 location
->lookup_method
);
542 if (!lookup_method
) {
547 /* Invalid probe location lookup method. */
551 /* Create the probe_location */
552 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
553 binary_path
, provider_name
, probe_name
, lookup_method
, false);
555 goto destroy_lookup_method
;
558 /* Set the duplicated fd to the new probe_location */
559 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, new_fd
) < 0) {
560 goto destroy_probe_location
;
565 destroy_probe_location
:
566 lttng_userspace_probe_location_destroy(new_location
);
567 destroy_lookup_method
:
568 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
570 if (close(new_fd
) < 0) {
571 PERROR("Error closing duplicated file descriptor in error path");
579 const char *lttng_userspace_probe_location_function_get_binary_path(
580 const struct lttng_userspace_probe_location
*location
)
582 const char *ret
= NULL
;
583 struct lttng_userspace_probe_location_function
*function_location
;
585 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
586 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
587 ERR("Invalid argument(s)");
591 function_location
= container_of(location
,
592 struct lttng_userspace_probe_location_function
,
594 ret
= function_location
->binary_path
;
599 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
600 const struct lttng_userspace_probe_location
*location
)
602 const char *ret
= NULL
;
603 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
605 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
606 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
607 ERR("Invalid argument(s)");
611 tracepoint_location
= container_of(location
,
612 struct lttng_userspace_probe_location_tracepoint
,
614 ret
= tracepoint_location
->binary_path
;
619 const char *lttng_userspace_probe_location_function_get_function_name(
620 const struct lttng_userspace_probe_location
*location
)
622 const char *ret
= NULL
;
623 struct lttng_userspace_probe_location_function
*function_location
;
625 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
626 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
627 ERR("Invalid argument(s)");
631 function_location
= container_of(location
,
632 struct lttng_userspace_probe_location_function
, parent
);
633 ret
= function_location
->function_name
;
638 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
639 const struct lttng_userspace_probe_location
*location
)
641 const char *ret
= NULL
;
642 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
644 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
645 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
646 ERR("Invalid argument(s)");
650 tracepoint_location
= container_of(location
,
651 struct lttng_userspace_probe_location_tracepoint
, parent
);
652 ret
= tracepoint_location
->probe_name
;
657 const char *lttng_userspace_probe_location_tracepoint_get_provider_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
->provider_name
;
676 int lttng_userspace_probe_location_function_get_binary_fd(
677 const struct lttng_userspace_probe_location
*location
)
680 struct lttng_userspace_probe_location_function
*function_location
;
682 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
683 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
684 ERR("Invalid argument(s)");
688 function_location
= container_of(location
,
689 struct lttng_userspace_probe_location_function
, parent
);
690 ret
= function_location
->binary_fd
;
695 enum lttng_userspace_probe_location_function_instrumentation_type
696 lttng_userspace_probe_location_function_get_instrumentation_type(
697 const struct lttng_userspace_probe_location
*location
)
699 enum lttng_userspace_probe_location_function_instrumentation_type type
;
700 struct lttng_userspace_probe_location_function
*function_location
;
702 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
703 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
704 ERR("Invalid argument(s)");
705 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
709 function_location
= container_of(location
,
710 struct lttng_userspace_probe_location_function
, parent
);
711 type
= function_location
->instrumentation_type
;
716 enum lttng_userspace_probe_location_status
717 lttng_userspace_probe_location_function_set_instrumentation_type(
718 const struct lttng_userspace_probe_location
*location
,
719 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
721 enum lttng_userspace_probe_location_status status
=
722 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
723 struct lttng_userspace_probe_location_function
*function_location
;
725 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
726 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
727 instrumentation_type
!=
728 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
729 ERR("Invalid argument(s)");
730 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
734 function_location
= container_of(location
,
735 struct lttng_userspace_probe_location_function
, parent
);
736 function_location
->instrumentation_type
= instrumentation_type
;
741 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
742 const struct lttng_userspace_probe_location
*location
)
745 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
747 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
748 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
749 ERR("Invalid argument(s)");
753 tracepoint_location
= container_of(location
,
754 struct lttng_userspace_probe_location_tracepoint
, parent
);
755 ret
= tracepoint_location
->binary_fd
;
760 static struct lttng_userspace_probe_location_lookup_method
*
761 lttng_userspace_probe_location_function_get_lookup_method(
762 const struct lttng_userspace_probe_location
*location
)
764 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
766 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
767 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
768 ERR("Invalid argument(s)");
772 ret
= location
->lookup_method
;
777 static struct lttng_userspace_probe_location_lookup_method
*
778 lttng_userspace_probe_location_tracepoint_get_lookup_method(
779 const struct lttng_userspace_probe_location
*location
)
781 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
783 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
784 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
785 ERR("Invalid argument(s)");
789 ret
= location
->lookup_method
;
794 const struct lttng_userspace_probe_location_lookup_method
*
795 lttng_userspace_probe_location_get_lookup_method(
796 const struct lttng_userspace_probe_location
*location
)
798 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
801 switch (location
->type
) {
802 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
803 ret
= lttng_userspace_probe_location_function_get_lookup_method(
806 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
807 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
811 ERR("Unknowned lookup method.");
818 int lttng_userspace_probe_location_lookup_method_serialize(
819 struct lttng_userspace_probe_location_lookup_method
*method
,
820 struct lttng_dynamic_buffer
*buffer
)
823 struct lttng_userspace_probe_location_lookup_method_comm
826 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
827 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
829 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
830 sizeof(lookup_method_comm
));
835 ret
= sizeof(lookup_method_comm
);
841 int lttng_userspace_probe_location_function_serialize(
842 const struct lttng_userspace_probe_location
*location
,
843 struct lttng_dynamic_buffer
*buffer
,
847 size_t function_name_len
, binary_path_len
;
848 struct lttng_userspace_probe_location_function
*location_function
;
849 struct lttng_userspace_probe_location_function_comm location_function_comm
;
852 assert(lttng_userspace_probe_location_get_type(location
) ==
853 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
855 location_function
= container_of(location
,
856 struct lttng_userspace_probe_location_function
,
858 if (!location_function
->function_name
|| !location_function
->binary_path
) {
859 ret
= -LTTNG_ERR_INVALID
;
863 if (binary_fd
&& location_function
->binary_fd
< 0) {
864 ret
= -LTTNG_ERR_INVALID
;
869 *binary_fd
= location_function
->binary_fd
;
872 function_name_len
= strlen(location_function
->function_name
);
873 if (function_name_len
== 0) {
874 ret
= -LTTNG_ERR_INVALID
;
877 binary_path_len
= strlen(location_function
->binary_path
);
878 if (binary_path_len
== 0) {
879 ret
= -LTTNG_ERR_INVALID
;
883 location_function_comm
.function_name_len
= function_name_len
+ 1;
884 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
887 ret
= lttng_dynamic_buffer_append(buffer
,
888 &location_function_comm
,
889 sizeof(location_function_comm
));
891 ret
= -LTTNG_ERR_INVALID
;
894 ret
= lttng_dynamic_buffer_append(buffer
,
895 location_function
->function_name
,
896 location_function_comm
.function_name_len
);
898 ret
= -LTTNG_ERR_INVALID
;
901 ret
= lttng_dynamic_buffer_append(buffer
,
902 location_function
->binary_path
,
903 location_function_comm
.binary_path_len
);
905 ret
= -LTTNG_ERR_INVALID
;
909 ret
= sizeof(location_function_comm
) +
910 location_function_comm
.function_name_len
+
911 location_function_comm
.binary_path_len
;
917 int lttng_userspace_probe_location_tracepoint_serialize(
918 const struct lttng_userspace_probe_location
*location
,
919 struct lttng_dynamic_buffer
*buffer
,
923 size_t probe_name_len
, provider_name_len
, binary_path_len
;
924 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
925 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
928 assert(lttng_userspace_probe_location_get_type(location
) ==
929 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
931 location_tracepoint
= container_of(location
,
932 struct lttng_userspace_probe_location_tracepoint
,
934 if (!location_tracepoint
->probe_name
||
935 !location_tracepoint
->provider_name
||
936 !location_tracepoint
->binary_path
) {
937 ret
= -LTTNG_ERR_INVALID
;
941 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
942 ret
= -LTTNG_ERR_INVALID
;
947 *binary_fd
= location_tracepoint
->binary_fd
;
950 probe_name_len
= strlen(location_tracepoint
->probe_name
);
951 if (probe_name_len
== 0) {
952 ret
= -LTTNG_ERR_INVALID
;
956 provider_name_len
= strlen(location_tracepoint
->provider_name
);
957 if (provider_name_len
== 0) {
958 ret
= -LTTNG_ERR_INVALID
;
962 binary_path_len
= strlen(location_tracepoint
->binary_path
);
963 if (binary_path_len
== 0) {
964 ret
= -LTTNG_ERR_INVALID
;
968 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
969 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
970 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
973 ret
= lttng_dynamic_buffer_append(buffer
,
974 &location_tracepoint_comm
,
975 sizeof(location_tracepoint_comm
));
977 ret
= -LTTNG_ERR_INVALID
;
980 ret
= lttng_dynamic_buffer_append(buffer
,
981 location_tracepoint
->probe_name
,
982 location_tracepoint_comm
.probe_name_len
);
984 ret
= -LTTNG_ERR_INVALID
;
987 ret
= lttng_dynamic_buffer_append(buffer
,
988 location_tracepoint
->provider_name
,
989 location_tracepoint_comm
.provider_name_len
);
991 ret
= -LTTNG_ERR_INVALID
;
994 ret
= lttng_dynamic_buffer_append(buffer
,
995 location_tracepoint
->binary_path
,
996 location_tracepoint_comm
.binary_path_len
);
998 ret
= -LTTNG_ERR_INVALID
;
1002 ret
= sizeof(location_tracepoint_comm
) +
1003 location_tracepoint_comm
.probe_name_len
+
1004 location_tracepoint_comm
.provider_name_len
+
1005 location_tracepoint_comm
.binary_path_len
;
1011 int lttng_userspace_probe_location_serialize(
1012 const struct lttng_userspace_probe_location
*location
,
1013 struct lttng_dynamic_buffer
*buffer
,
1016 int ret
, buffer_use
= 0;
1017 struct lttng_userspace_probe_location_comm location_generic_comm
;
1020 ERR("Invalid argument(s)");
1021 ret
= -LTTNG_ERR_INVALID
;
1025 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1027 location_generic_comm
.type
= (int8_t) location
->type
;
1029 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1030 sizeof(location_generic_comm
));
1035 buffer_use
+= sizeof(location_generic_comm
);
1037 switch (lttng_userspace_probe_location_get_type(location
)) {
1038 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1039 ret
= lttng_userspace_probe_location_function_serialize(
1040 location
, buffer
, binary_fd
);
1042 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1043 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1044 location
, buffer
, binary_fd
);
1047 ERR("Unsupported probe location type");
1048 ret
= -LTTNG_ERR_INVALID
;
1056 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1057 location
->lookup_method
, buffer
);
1067 int lttng_userspace_probe_location_function_create_from_buffer(
1068 const struct lttng_buffer_view
*buffer
,
1069 struct lttng_userspace_probe_location
**location
)
1071 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1072 const char *function_name_src
, *binary_path_src
;
1073 char *function_name
= NULL
, *binary_path
= NULL
;
1077 assert(buffer
->data
);
1080 location_function_comm
=
1081 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1083 const size_t expected_size
= sizeof(*location_function_comm
) +
1084 location_function_comm
->function_name_len
+
1085 location_function_comm
->binary_path_len
;
1087 if (buffer
->size
< expected_size
) {
1088 ret
= -LTTNG_ERR_INVALID
;
1092 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1093 binary_path_src
= function_name_src
+
1094 location_function_comm
->function_name_len
;
1096 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1097 ret
= -LTTNG_ERR_INVALID
;
1100 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1101 ret
= -LTTNG_ERR_INVALID
;
1105 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1106 if (!function_name
) {
1107 PERROR("lttng_strndup");
1111 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1113 PERROR("lttng_strndup");
1117 *location
= lttng_userspace_probe_location_function_create_no_check(
1118 binary_path
, function_name
, NULL
, false);
1120 ret
= -LTTNG_ERR_INVALID
;
1124 ret
= (int) expected_size
;
1126 free(function_name
);
1132 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1133 const struct lttng_buffer_view
*buffer
,
1134 struct lttng_userspace_probe_location
**location
)
1136 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1137 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1138 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1142 assert(buffer
->data
);
1145 location_tracepoint_comm
=
1146 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1148 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1149 location_tracepoint_comm
->probe_name_len
+
1150 location_tracepoint_comm
->provider_name_len
+
1151 location_tracepoint_comm
->binary_path_len
;
1153 if (buffer
->size
< expected_size
) {
1154 ret
= -LTTNG_ERR_INVALID
;
1158 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1159 provider_name_src
= probe_name_src
+
1160 location_tracepoint_comm
->probe_name_len
;
1161 binary_path_src
= provider_name_src
+
1162 location_tracepoint_comm
->provider_name_len
;
1164 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1165 ret
= -LTTNG_ERR_INVALID
;
1169 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1170 ret
= -LTTNG_ERR_INVALID
;
1174 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1175 ret
= -LTTNG_ERR_INVALID
;
1179 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1181 PERROR("lttng_strndup");
1184 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1185 if (!provider_name
) {
1186 PERROR("lttng_strndup");
1190 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1192 PERROR("lttng_strndup");
1196 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1197 binary_path
, provider_name
, probe_name
, NULL
, false);
1199 ret
= -LTTNG_ERR_INVALID
;
1203 ret
= (int) expected_size
;
1206 free(provider_name
);
1212 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1213 struct lttng_buffer_view
*buffer
,
1214 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1217 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1218 enum lttng_userspace_probe_location_lookup_method_type type
;
1221 assert(buffer
->data
);
1222 assert(lookup_method
);
1224 if (buffer
->size
< sizeof(*lookup_comm
)) {
1225 ret
= -LTTNG_ERR_INVALID
;
1229 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1231 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1234 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1235 *lookup_method
= NULL
;
1237 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1239 lttng_userspace_probe_location_lookup_method_function_elf_create();
1240 if (!(*lookup_method
)) {
1241 ret
= -LTTNG_ERR_INVALID
;
1245 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1247 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1248 if (!(*lookup_method
)) {
1249 ret
= -LTTNG_ERR_INVALID
;
1254 ret
= -LTTNG_ERR_INVALID
;
1258 ret
= sizeof(*lookup_comm
);
1264 int lttng_userspace_probe_location_create_from_buffer(
1265 const struct lttng_buffer_view
*buffer
,
1266 struct lttng_userspace_probe_location
**location
)
1268 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1269 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1270 enum lttng_userspace_probe_location_type type
;
1271 struct lttng_buffer_view lookup_method_view
;
1277 assert(buffer
->data
);
1280 lookup_method
= NULL
;
1282 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1283 ret
= -LTTNG_ERR_INVALID
;
1287 probe_location_comm
=
1288 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1289 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1290 consumed
+= sizeof(*probe_location_comm
);
1293 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1295 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1296 buffer
, consumed
, buffer
->size
- consumed
);
1298 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1305 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1307 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1308 buffer
, consumed
, buffer
->size
- consumed
);
1310 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1318 ret
= -LTTNG_ERR_INVALID
;
1323 if (buffer
->size
<= consumed
) {
1324 ret
= -LTTNG_ERR_INVALID
;
1328 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1329 buffer
->size
- consumed
);
1330 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1331 &lookup_method_view
, &lookup_method
);
1333 ret
= -LTTNG_ERR_INVALID
;
1337 assert(lookup_method
);
1338 (*location
)->lookup_method
= lookup_method
;
1339 lookup_method
= NULL
;
1346 int lttng_userspace_probe_location_function_set_binary_fd(
1347 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1350 struct lttng_userspace_probe_location_function
*function_location
;
1353 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1355 function_location
= container_of(location
,
1356 struct lttng_userspace_probe_location_function
, parent
);
1357 if (function_location
->binary_fd
>= 0) {
1358 ret
= close(function_location
->binary_fd
);
1361 ret
= -LTTNG_ERR_INVALID
;
1366 function_location
->binary_fd
= binary_fd
;
1372 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1373 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1376 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1379 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1381 tracepoint_location
= container_of(location
,
1382 struct lttng_userspace_probe_location_tracepoint
, parent
);
1383 if (tracepoint_location
->binary_fd
>= 0) {
1384 ret
= close(tracepoint_location
->binary_fd
);
1387 ret
= -LTTNG_ERR_INVALID
;
1392 tracepoint_location
->binary_fd
= binary_fd
;
1398 int lttng_userspace_probe_location_function_flatten(
1399 const struct lttng_userspace_probe_location
*location
,
1400 struct lttng_dynamic_buffer
*buffer
)
1402 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1403 struct lttng_userspace_probe_location_function
*probe_function
;
1404 struct lttng_userspace_probe_location_function flat_probe
;
1405 size_t function_name_len
, binary_path_len
;
1406 size_t padding_needed
= 0;
1407 char *flat_probe_start
;
1408 int storage_needed
= 0;
1413 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1414 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1415 ret
= -LTTNG_ERR_INVALID
;
1419 probe_function
= container_of(location
,
1420 struct lttng_userspace_probe_location_function
,
1422 assert(probe_function
->function_name
);
1423 assert(probe_function
->binary_path
);
1426 sizeof(struct lttng_userspace_probe_location_function
);
1427 function_name_len
= strlen(probe_function
->function_name
) + 1;
1428 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1429 storage_needed
+= function_name_len
+ binary_path_len
;
1432 * The lookup method is aligned to 64-bit within the buffer.
1433 * This is needed even if there is no lookup method since
1434 * the next structure in the buffer probably needs to be
1435 * aligned too (depending on the arch).
1437 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1438 storage_needed
+= padding_needed
;
1440 if (location
->lookup_method
) {
1441 /* NOTE: elf look-up method is assumed here. */
1442 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1446 ret
= storage_needed
;
1450 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1451 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1452 buffer
->size
+ storage_needed
);
1458 memset(&flat_probe
, 0, sizeof(flat_probe
));
1460 flat_probe_start
= buffer
->data
+ buffer
->size
;
1461 flat_probe
.parent
.type
= location
->type
;
1463 * The lookup method, if present, is the last element in the flat
1464 * representation of the probe.
1466 if (location
->lookup_method
) {
1467 flat_probe
.parent
.lookup_method
=
1468 (struct lttng_userspace_probe_location_lookup_method
*)
1469 (flat_probe_start
+ sizeof(flat_probe
) +
1470 function_name_len
+ binary_path_len
+ padding_needed
);
1472 flat_probe
.parent
.lookup_method
= NULL
;
1475 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1476 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1477 flat_probe
.binary_fd
= -1;
1478 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1479 sizeof(flat_probe
));
1484 ret
= lttng_dynamic_buffer_append(buffer
,
1485 probe_function
->function_name
, function_name_len
);
1489 ret
= lttng_dynamic_buffer_append(buffer
,
1490 probe_function
->binary_path
, binary_path_len
);
1495 /* Insert padding before the lookup method. */
1496 ret
= lttng_dynamic_buffer_set_size(buffer
,
1497 buffer
->size
+ padding_needed
);
1502 if (!location
->lookup_method
) {
1503 /* Not an error, the default method is used. */
1504 ret
= storage_needed
;
1508 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1509 flat_lookup_method
.parent
.type
=
1510 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1511 ret
= lttng_dynamic_buffer_append(buffer
,
1512 &flat_lookup_method
, sizeof(flat_lookup_method
));
1516 ret
= storage_needed
;
1522 int lttng_userspace_probe_location_tracepoint_flatten(
1523 const struct lttng_userspace_probe_location
*location
,
1524 struct lttng_dynamic_buffer
*buffer
)
1526 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1527 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1528 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1529 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1530 size_t padding_needed
= 0;
1531 int storage_needed
= 0;
1532 char *flat_probe_start
;
1537 /* Only SDT tracepoints are supported at the moment */
1538 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1539 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1540 ret
= -LTTNG_ERR_INVALID
;
1543 probe_tracepoint
= container_of(location
,
1544 struct lttng_userspace_probe_location_tracepoint
,
1546 assert(probe_tracepoint
->probe_name
);
1547 assert(probe_tracepoint
->provider_name
);
1548 assert(probe_tracepoint
->binary_path
);
1550 /* Compute the storage space needed to flatten the probe location */
1551 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1553 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1554 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1555 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1557 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1560 * The lookup method is aligned to 64-bit within the buffer.
1561 * This is needed even if there is no lookup method since
1562 * the next structure in the buffer probably needs to be
1563 * aligned too (depending on the arch).
1565 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1566 storage_needed
+= padding_needed
;
1568 if (location
->lookup_method
) {
1569 /* NOTE: elf look-up method is assumed here. */
1571 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1575 * If the caller set buffer to NULL, return the size of the needed buffer.
1578 ret
= storage_needed
;
1582 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1583 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1584 buffer
->size
+ storage_needed
);
1590 memset(&flat_probe
, 0, sizeof(flat_probe
));
1592 flat_probe_start
= buffer
->data
+ buffer
->size
;
1593 flat_probe
.parent
.type
= location
->type
;
1596 * The lookup method, if present, is the last element in the flat
1597 * representation of the probe.
1599 if (location
->lookup_method
) {
1600 flat_probe
.parent
.lookup_method
=
1601 (struct lttng_userspace_probe_location_lookup_method
*)
1602 (flat_probe_start
+ sizeof(flat_probe
) +
1603 probe_name_len
+ provider_name_len
+
1604 binary_path_len
+ padding_needed
);
1606 flat_probe
.parent
.lookup_method
= NULL
;
1609 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1610 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1611 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1612 flat_probe
.binary_fd
= -1;
1613 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1618 /* Append all the fields to the buffer */
1619 ret
= lttng_dynamic_buffer_append(buffer
,
1620 probe_tracepoint
->probe_name
, probe_name_len
);
1624 ret
= lttng_dynamic_buffer_append(buffer
,
1625 probe_tracepoint
->provider_name
, provider_name_len
);
1629 ret
= lttng_dynamic_buffer_append(buffer
,
1630 probe_tracepoint
->binary_path
, binary_path_len
);
1635 /* Insert padding before the lookup method. */
1636 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1641 if (!location
->lookup_method
) {
1642 /* Not an error, the default method is used. */
1643 ret
= storage_needed
;
1647 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1649 flat_lookup_method
.parent
.type
=
1650 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1651 ret
= lttng_dynamic_buffer_append(buffer
,
1652 &flat_lookup_method
, sizeof(flat_lookup_method
));
1656 ret
= storage_needed
;
1662 int lttng_userspace_probe_location_flatten(
1663 const struct lttng_userspace_probe_location
*location
,
1664 struct lttng_dynamic_buffer
*buffer
)
1668 ret
= -LTTNG_ERR_INVALID
;
1672 /* Only types currently supported. */
1673 switch (location
->type
) {
1674 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1675 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1677 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1678 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1681 ret
= -LTTNG_ERR_INVALID
;
1690 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1691 const struct lttng_userspace_probe_location
*location
)
1693 struct lttng_userspace_probe_location
*new_location
= NULL
;
1694 enum lttng_userspace_probe_location_type type
;
1700 type
= lttng_userspace_probe_location_get_type(location
);
1702 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1704 lttng_userspace_probe_location_function_copy(location
);
1705 if (!new_location
) {
1709 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1711 lttng_userspace_probe_location_tracepoint_copy(location
);
1712 if (!new_location
) {
1717 new_location
= NULL
;
1721 return new_location
;