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
= dup(lttng_userspace_probe_location_function_get_binary_fd(location
));
428 PERROR("Error duplicating file descriptor to binary");
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
, 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
);
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
= dup(lttng_userspace_probe_location_tracepoint_get_binary_fd(location
));
516 PERROR("Error duplicating file descriptor to binary");
521 * Duplicate probe location method fields
523 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
524 location
->lookup_method
);
525 switch (lookup_type
) {
526 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
528 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
529 location
->lookup_method
);
530 if (!lookup_method
) {
535 /* Invalid probe location lookup method. */
539 /* Create the probe_location */
540 new_location
= lttng_userspace_probe_location_tracepoint_create_no_check(
541 binary_path
, provider_name
, probe_name
, lookup_method
, false);
543 goto destroy_lookup_method
;
546 /* Set the duplicated fd to the new probe_location */
547 if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location
, fd
) < 0) {
548 goto destroy_probe_location
;
553 destroy_probe_location
:
554 lttng_userspace_probe_location_destroy(new_location
);
555 destroy_lookup_method
:
556 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
559 PERROR("Error closing duplicated file descriptor in error path");
567 const char *lttng_userspace_probe_location_function_get_binary_path(
568 const struct lttng_userspace_probe_location
*location
)
570 const char *ret
= NULL
;
571 struct lttng_userspace_probe_location_function
*function_location
;
573 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
574 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
575 ERR("Invalid argument(s)");
579 function_location
= container_of(location
,
580 struct lttng_userspace_probe_location_function
,
582 ret
= function_location
->binary_path
;
587 const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
588 const struct lttng_userspace_probe_location
*location
)
590 const char *ret
= NULL
;
591 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
593 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
594 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
595 ERR("Invalid argument(s)");
599 tracepoint_location
= container_of(location
,
600 struct lttng_userspace_probe_location_tracepoint
,
602 ret
= tracepoint_location
->binary_path
;
607 const char *lttng_userspace_probe_location_function_get_function_name(
608 const struct lttng_userspace_probe_location
*location
)
610 const char *ret
= NULL
;
611 struct lttng_userspace_probe_location_function
*function_location
;
613 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
614 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
615 ERR("Invalid argument(s)");
619 function_location
= container_of(location
,
620 struct lttng_userspace_probe_location_function
, parent
);
621 ret
= function_location
->function_name
;
626 const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
627 const struct lttng_userspace_probe_location
*location
)
629 const char *ret
= NULL
;
630 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
632 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
633 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
634 ERR("Invalid argument(s)");
638 tracepoint_location
= container_of(location
,
639 struct lttng_userspace_probe_location_tracepoint
, parent
);
640 ret
= tracepoint_location
->probe_name
;
645 const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
646 const struct lttng_userspace_probe_location
*location
)
648 const char *ret
= NULL
;
649 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
651 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
652 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
653 ERR("Invalid argument(s)");
657 tracepoint_location
= container_of(location
,
658 struct lttng_userspace_probe_location_tracepoint
, parent
);
659 ret
= tracepoint_location
->provider_name
;
664 int lttng_userspace_probe_location_function_get_binary_fd(
665 const struct lttng_userspace_probe_location
*location
)
668 struct lttng_userspace_probe_location_function
*function_location
;
670 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
671 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
672 ERR("Invalid argument(s)");
676 function_location
= container_of(location
,
677 struct lttng_userspace_probe_location_function
, parent
);
678 ret
= function_location
->binary_fd
;
683 enum lttng_userspace_probe_location_function_instrumentation_type
684 lttng_userspace_probe_location_function_get_instrumentation_type(
685 const struct lttng_userspace_probe_location
*location
)
687 enum lttng_userspace_probe_location_function_instrumentation_type type
;
688 struct lttng_userspace_probe_location_function
*function_location
;
690 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
691 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
692 ERR("Invalid argument(s)");
693 type
= LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN
;
697 function_location
= container_of(location
,
698 struct lttng_userspace_probe_location_function
, parent
);
699 type
= function_location
->instrumentation_type
;
704 enum lttng_userspace_probe_location_status
705 lttng_userspace_probe_location_function_set_instrumentation_type(
706 const struct lttng_userspace_probe_location
*location
,
707 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type
)
709 enum lttng_userspace_probe_location_status status
=
710 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK
;
711 struct lttng_userspace_probe_location_function
*function_location
;
713 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
714 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
||
715 instrumentation_type
!=
716 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY
) {
717 ERR("Invalid argument(s)");
718 status
= LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID
;
722 function_location
= container_of(location
,
723 struct lttng_userspace_probe_location_function
, parent
);
724 function_location
->instrumentation_type
= instrumentation_type
;
729 int lttng_userspace_probe_location_tracepoint_get_binary_fd(
730 const struct lttng_userspace_probe_location
*location
)
733 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
735 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
736 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
737 ERR("Invalid argument(s)");
741 tracepoint_location
= container_of(location
,
742 struct lttng_userspace_probe_location_tracepoint
, parent
);
743 ret
= tracepoint_location
->binary_fd
;
748 static struct lttng_userspace_probe_location_lookup_method
*
749 lttng_userspace_probe_location_function_get_lookup_method(
750 const struct lttng_userspace_probe_location
*location
)
752 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
754 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
755 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
756 ERR("Invalid argument(s)");
760 ret
= location
->lookup_method
;
765 static struct lttng_userspace_probe_location_lookup_method
*
766 lttng_userspace_probe_location_tracepoint_get_lookup_method(
767 const struct lttng_userspace_probe_location
*location
)
769 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
771 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
772 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
) {
773 ERR("Invalid argument(s)");
777 ret
= location
->lookup_method
;
782 const struct lttng_userspace_probe_location_lookup_method
*
783 lttng_userspace_probe_location_get_lookup_method(
784 const struct lttng_userspace_probe_location
*location
)
786 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
789 switch (location
->type
) {
790 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
791 ret
= lttng_userspace_probe_location_function_get_lookup_method(
794 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
795 ret
= lttng_userspace_probe_location_tracepoint_get_lookup_method(
799 ERR("Unknowned lookup method.");
806 int lttng_userspace_probe_location_lookup_method_serialize(
807 struct lttng_userspace_probe_location_lookup_method
*method
,
808 struct lttng_dynamic_buffer
*buffer
)
811 struct lttng_userspace_probe_location_lookup_method_comm
814 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
815 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
817 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
818 sizeof(lookup_method_comm
));
823 ret
= sizeof(lookup_method_comm
);
829 int lttng_userspace_probe_location_function_serialize(
830 const struct lttng_userspace_probe_location
*location
,
831 struct lttng_dynamic_buffer
*buffer
,
835 size_t function_name_len
, binary_path_len
;
836 struct lttng_userspace_probe_location_function
*location_function
;
837 struct lttng_userspace_probe_location_function_comm location_function_comm
;
840 assert(lttng_userspace_probe_location_get_type(location
) ==
841 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
843 location_function
= container_of(location
,
844 struct lttng_userspace_probe_location_function
,
846 if (!location_function
->function_name
|| !location_function
->binary_path
) {
847 ret
= -LTTNG_ERR_INVALID
;
851 if (binary_fd
&& location_function
->binary_fd
< 0) {
852 ret
= -LTTNG_ERR_INVALID
;
857 *binary_fd
= location_function
->binary_fd
;
860 function_name_len
= strlen(location_function
->function_name
);
861 if (function_name_len
== 0) {
862 ret
= -LTTNG_ERR_INVALID
;
865 binary_path_len
= strlen(location_function
->binary_path
);
866 if (binary_path_len
== 0) {
867 ret
= -LTTNG_ERR_INVALID
;
871 location_function_comm
.function_name_len
= function_name_len
+ 1;
872 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
875 ret
= lttng_dynamic_buffer_append(buffer
,
876 &location_function_comm
,
877 sizeof(location_function_comm
));
879 ret
= -LTTNG_ERR_INVALID
;
882 ret
= lttng_dynamic_buffer_append(buffer
,
883 location_function
->function_name
,
884 location_function_comm
.function_name_len
);
886 ret
= -LTTNG_ERR_INVALID
;
889 ret
= lttng_dynamic_buffer_append(buffer
,
890 location_function
->binary_path
,
891 location_function_comm
.binary_path_len
);
893 ret
= -LTTNG_ERR_INVALID
;
897 ret
= sizeof(location_function_comm
) +
898 location_function_comm
.function_name_len
+
899 location_function_comm
.binary_path_len
;
905 int lttng_userspace_probe_location_tracepoint_serialize(
906 const struct lttng_userspace_probe_location
*location
,
907 struct lttng_dynamic_buffer
*buffer
,
911 size_t probe_name_len
, provider_name_len
, binary_path_len
;
912 struct lttng_userspace_probe_location_tracepoint
*location_tracepoint
;
913 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm
;
916 assert(lttng_userspace_probe_location_get_type(location
) ==
917 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
919 location_tracepoint
= container_of(location
,
920 struct lttng_userspace_probe_location_tracepoint
,
922 if (!location_tracepoint
->probe_name
||
923 !location_tracepoint
->provider_name
||
924 !location_tracepoint
->binary_path
) {
925 ret
= -LTTNG_ERR_INVALID
;
929 if (binary_fd
&& location_tracepoint
->binary_fd
< 0) {
930 ret
= -LTTNG_ERR_INVALID
;
935 *binary_fd
= location_tracepoint
->binary_fd
;
938 probe_name_len
= strlen(location_tracepoint
->probe_name
);
939 if (probe_name_len
== 0) {
940 ret
= -LTTNG_ERR_INVALID
;
944 provider_name_len
= strlen(location_tracepoint
->provider_name
);
945 if (provider_name_len
== 0) {
946 ret
= -LTTNG_ERR_INVALID
;
950 binary_path_len
= strlen(location_tracepoint
->binary_path
);
951 if (binary_path_len
== 0) {
952 ret
= -LTTNG_ERR_INVALID
;
956 location_tracepoint_comm
.probe_name_len
= probe_name_len
+ 1;
957 location_tracepoint_comm
.provider_name_len
= provider_name_len
+ 1;
958 location_tracepoint_comm
.binary_path_len
= binary_path_len
+ 1;
961 ret
= lttng_dynamic_buffer_append(buffer
,
962 &location_tracepoint_comm
,
963 sizeof(location_tracepoint_comm
));
965 ret
= -LTTNG_ERR_INVALID
;
968 ret
= lttng_dynamic_buffer_append(buffer
,
969 location_tracepoint
->probe_name
,
970 location_tracepoint_comm
.probe_name_len
);
972 ret
= -LTTNG_ERR_INVALID
;
975 ret
= lttng_dynamic_buffer_append(buffer
,
976 location_tracepoint
->provider_name
,
977 location_tracepoint_comm
.provider_name_len
);
979 ret
= -LTTNG_ERR_INVALID
;
982 ret
= lttng_dynamic_buffer_append(buffer
,
983 location_tracepoint
->binary_path
,
984 location_tracepoint_comm
.binary_path_len
);
986 ret
= -LTTNG_ERR_INVALID
;
990 ret
= sizeof(location_tracepoint_comm
) +
991 location_tracepoint_comm
.probe_name_len
+
992 location_tracepoint_comm
.provider_name_len
+
993 location_tracepoint_comm
.binary_path_len
;
999 int lttng_userspace_probe_location_serialize(
1000 const struct lttng_userspace_probe_location
*location
,
1001 struct lttng_dynamic_buffer
*buffer
,
1004 int ret
, buffer_use
= 0;
1005 struct lttng_userspace_probe_location_comm location_generic_comm
;
1008 ERR("Invalid argument(s)");
1009 ret
= -LTTNG_ERR_INVALID
;
1013 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
1015 location_generic_comm
.type
= (int8_t) location
->type
;
1017 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
1018 sizeof(location_generic_comm
));
1023 buffer_use
+= sizeof(location_generic_comm
);
1025 switch (lttng_userspace_probe_location_get_type(location
)) {
1026 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1027 ret
= lttng_userspace_probe_location_function_serialize(
1028 location
, buffer
, binary_fd
);
1030 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1031 ret
= lttng_userspace_probe_location_tracepoint_serialize(
1032 location
, buffer
, binary_fd
);
1035 ERR("Unsupported probe location type");
1036 ret
= -LTTNG_ERR_INVALID
;
1044 ret
= lttng_userspace_probe_location_lookup_method_serialize(
1045 location
->lookup_method
, buffer
);
1055 int lttng_userspace_probe_location_function_create_from_buffer(
1056 const struct lttng_buffer_view
*buffer
,
1057 struct lttng_userspace_probe_location
**location
)
1059 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
1060 const char *function_name_src
, *binary_path_src
;
1061 char *function_name
= NULL
, *binary_path
= NULL
;
1065 assert(buffer
->data
);
1068 location_function_comm
=
1069 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
1071 const size_t expected_size
= sizeof(*location_function_comm
) +
1072 location_function_comm
->function_name_len
+
1073 location_function_comm
->binary_path_len
;
1075 if (buffer
->size
< expected_size
) {
1076 ret
= -LTTNG_ERR_INVALID
;
1080 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
1081 binary_path_src
= function_name_src
+
1082 location_function_comm
->function_name_len
;
1084 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
1085 ret
= -LTTNG_ERR_INVALID
;
1088 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
1089 ret
= -LTTNG_ERR_INVALID
;
1093 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1094 if (!function_name
) {
1095 PERROR("lttng_strndup");
1099 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
1101 PERROR("lttng_strndup");
1105 *location
= lttng_userspace_probe_location_function_create_no_check(
1106 binary_path
, function_name
, NULL
, false);
1108 ret
= -LTTNG_ERR_INVALID
;
1112 ret
= (int) expected_size
;
1114 free(function_name
);
1120 int lttng_userspace_probe_location_tracepoint_create_from_buffer(
1121 const struct lttng_buffer_view
*buffer
,
1122 struct lttng_userspace_probe_location
**location
)
1124 struct lttng_userspace_probe_location_tracepoint_comm
*location_tracepoint_comm
;
1125 const char *probe_name_src
, *provider_name_src
, *binary_path_src
;
1126 char *probe_name
= NULL
, *provider_name
= NULL
, *binary_path
= NULL
;
1130 assert(buffer
->data
);
1133 location_tracepoint_comm
=
1134 (struct lttng_userspace_probe_location_tracepoint_comm
*) buffer
->data
;
1136 const size_t expected_size
= sizeof(*location_tracepoint_comm
) +
1137 location_tracepoint_comm
->probe_name_len
+
1138 location_tracepoint_comm
->provider_name_len
+
1139 location_tracepoint_comm
->binary_path_len
;
1141 if (buffer
->size
< expected_size
) {
1142 ret
= -LTTNG_ERR_INVALID
;
1146 probe_name_src
= buffer
->data
+ sizeof(*location_tracepoint_comm
);
1147 provider_name_src
= probe_name_src
+
1148 location_tracepoint_comm
->probe_name_len
;
1149 binary_path_src
= provider_name_src
+
1150 location_tracepoint_comm
->provider_name_len
;
1152 if (probe_name_src
[location_tracepoint_comm
->probe_name_len
- 1] != '\0') {
1153 ret
= -LTTNG_ERR_INVALID
;
1157 if (provider_name_src
[location_tracepoint_comm
->provider_name_len
- 1] != '\0') {
1158 ret
= -LTTNG_ERR_INVALID
;
1162 if (binary_path_src
[location_tracepoint_comm
->binary_path_len
- 1] != '\0') {
1163 ret
= -LTTNG_ERR_INVALID
;
1167 probe_name
= lttng_strndup(probe_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1169 PERROR("lttng_strndup");
1172 provider_name
= lttng_strndup(provider_name_src
, LTTNG_SYMBOL_NAME_LEN
);
1173 if (!provider_name
) {
1174 PERROR("lttng_strndup");
1178 binary_path
= lttng_strndup(binary_path_src
, LTTNG_SYMBOL_NAME_LEN
);
1180 PERROR("lttng_strndup");
1184 *location
= lttng_userspace_probe_location_tracepoint_create_no_check(
1185 binary_path
, provider_name
, probe_name
, NULL
, false);
1187 ret
= -LTTNG_ERR_INVALID
;
1191 ret
= (int) expected_size
;
1194 free(provider_name
);
1200 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
1201 struct lttng_buffer_view
*buffer
,
1202 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
1205 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
1206 enum lttng_userspace_probe_location_lookup_method_type type
;
1209 assert(buffer
->data
);
1210 assert(lookup_method
);
1212 if (buffer
->size
< sizeof(*lookup_comm
)) {
1213 ret
= -LTTNG_ERR_INVALID
;
1217 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
1219 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
1222 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
1223 *lookup_method
= NULL
;
1225 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
1227 lttng_userspace_probe_location_lookup_method_function_elf_create();
1228 if (!(*lookup_method
)) {
1229 ret
= -LTTNG_ERR_INVALID
;
1233 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
:
1235 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1236 if (!(*lookup_method
)) {
1237 ret
= -LTTNG_ERR_INVALID
;
1242 ret
= -LTTNG_ERR_INVALID
;
1246 ret
= sizeof(*lookup_comm
);
1252 int lttng_userspace_probe_location_create_from_buffer(
1253 const struct lttng_buffer_view
*buffer
,
1254 struct lttng_userspace_probe_location
**location
)
1256 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
1257 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
1258 enum lttng_userspace_probe_location_type type
;
1259 struct lttng_buffer_view lookup_method_view
;
1265 assert(buffer
->data
);
1268 lookup_method
= NULL
;
1270 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
1271 ret
= -LTTNG_ERR_INVALID
;
1275 probe_location_comm
=
1276 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
1277 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
1278 consumed
+= sizeof(*probe_location_comm
);
1281 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1283 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1284 buffer
, consumed
, buffer
->size
- consumed
);
1286 ret
= lttng_userspace_probe_location_function_create_from_buffer(
1293 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1295 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
1296 buffer
, consumed
, buffer
->size
- consumed
);
1298 ret
= lttng_userspace_probe_location_tracepoint_create_from_buffer(
1306 ret
= -LTTNG_ERR_INVALID
;
1311 if (buffer
->size
<= consumed
) {
1312 ret
= -LTTNG_ERR_INVALID
;
1316 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
1317 buffer
->size
- consumed
);
1318 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
1319 &lookup_method_view
, &lookup_method
);
1321 ret
= -LTTNG_ERR_INVALID
;
1325 assert(lookup_method
);
1326 (*location
)->lookup_method
= lookup_method
;
1327 lookup_method
= NULL
;
1334 int lttng_userspace_probe_location_function_set_binary_fd(
1335 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1338 struct lttng_userspace_probe_location_function
*function_location
;
1341 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
1343 function_location
= container_of(location
,
1344 struct lttng_userspace_probe_location_function
, parent
);
1345 if (function_location
->binary_fd
>= 0) {
1346 ret
= close(function_location
->binary_fd
);
1349 ret
= -LTTNG_ERR_INVALID
;
1354 function_location
->binary_fd
= binary_fd
;
1360 int lttng_userspace_probe_location_tracepoint_set_binary_fd(
1361 struct lttng_userspace_probe_location
*location
, int binary_fd
)
1364 struct lttng_userspace_probe_location_tracepoint
*tracepoint_location
;
1367 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
);
1369 tracepoint_location
= container_of(location
,
1370 struct lttng_userspace_probe_location_tracepoint
, parent
);
1371 if (tracepoint_location
->binary_fd
>= 0) {
1372 ret
= close(tracepoint_location
->binary_fd
);
1375 ret
= -LTTNG_ERR_INVALID
;
1380 tracepoint_location
->binary_fd
= binary_fd
;
1386 int lttng_userspace_probe_location_function_flatten(
1387 const struct lttng_userspace_probe_location
*location
,
1388 struct lttng_dynamic_buffer
*buffer
)
1390 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
1391 struct lttng_userspace_probe_location_function
*probe_function
;
1392 struct lttng_userspace_probe_location_function flat_probe
;
1393 size_t function_name_len
, binary_path_len
;
1394 size_t padding_needed
= 0;
1395 char *flat_probe_start
;
1396 int storage_needed
= 0;
1401 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1402 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
1403 ret
= -LTTNG_ERR_INVALID
;
1407 probe_function
= container_of(location
,
1408 struct lttng_userspace_probe_location_function
,
1410 assert(probe_function
->function_name
);
1411 assert(probe_function
->binary_path
);
1414 sizeof(struct lttng_userspace_probe_location_function
);
1415 function_name_len
= strlen(probe_function
->function_name
) + 1;
1416 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
1417 storage_needed
+= function_name_len
+ binary_path_len
;
1420 * The lookup method is aligned to 64-bit within the buffer.
1421 * This is needed even if there is no lookup method since
1422 * the next structure in the buffer probably needs to be
1423 * aligned too (depending on the arch).
1425 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1426 storage_needed
+= padding_needed
;
1428 if (location
->lookup_method
) {
1429 /* NOTE: elf look-up method is assumed here. */
1430 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1434 ret
= storage_needed
;
1438 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1439 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1440 buffer
->size
+ storage_needed
);
1446 memset(&flat_probe
, 0, sizeof(flat_probe
));
1448 flat_probe_start
= buffer
->data
+ buffer
->size
;
1449 flat_probe
.parent
.type
= location
->type
;
1451 * The lookup method, if present, is the last element in the flat
1452 * representation of the probe.
1454 if (location
->lookup_method
) {
1455 flat_probe
.parent
.lookup_method
=
1456 (struct lttng_userspace_probe_location_lookup_method
*)
1457 (flat_probe_start
+ sizeof(flat_probe
) +
1458 function_name_len
+ binary_path_len
+ padding_needed
);
1460 flat_probe
.parent
.lookup_method
= NULL
;
1463 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
1464 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
1465 flat_probe
.binary_fd
= -1;
1466 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
1467 sizeof(flat_probe
));
1472 ret
= lttng_dynamic_buffer_append(buffer
,
1473 probe_function
->function_name
, function_name_len
);
1477 ret
= lttng_dynamic_buffer_append(buffer
,
1478 probe_function
->binary_path
, binary_path_len
);
1483 /* Insert padding before the lookup method. */
1484 ret
= lttng_dynamic_buffer_set_size(buffer
,
1485 buffer
->size
+ padding_needed
);
1490 if (!location
->lookup_method
) {
1491 /* Not an error, the default method is used. */
1492 ret
= storage_needed
;
1496 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1497 flat_lookup_method
.parent
.type
=
1498 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
1499 ret
= lttng_dynamic_buffer_append(buffer
,
1500 &flat_lookup_method
, sizeof(flat_lookup_method
));
1504 ret
= storage_needed
;
1510 int lttng_userspace_probe_location_tracepoint_flatten(
1511 const struct lttng_userspace_probe_location
*location
,
1512 struct lttng_dynamic_buffer
*buffer
)
1514 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method
;
1515 struct lttng_userspace_probe_location_tracepoint
*probe_tracepoint
;
1516 struct lttng_userspace_probe_location_tracepoint flat_probe
;
1517 size_t probe_name_len
, provider_name_len
, binary_path_len
;
1518 size_t padding_needed
= 0;
1519 int storage_needed
= 0;
1520 char *flat_probe_start
;
1525 /* Only SDT tracepoints are supported at the moment */
1526 if (location
->lookup_method
&& location
->lookup_method
->type
!=
1527 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
) {
1528 ret
= -LTTNG_ERR_INVALID
;
1531 probe_tracepoint
= container_of(location
,
1532 struct lttng_userspace_probe_location_tracepoint
,
1534 assert(probe_tracepoint
->probe_name
);
1535 assert(probe_tracepoint
->provider_name
);
1536 assert(probe_tracepoint
->binary_path
);
1538 /* Compute the storage space needed to flatten the probe location */
1539 storage_needed
+= sizeof(struct lttng_userspace_probe_location_tracepoint
);
1541 probe_name_len
= strlen(probe_tracepoint
->probe_name
) + 1;
1542 provider_name_len
= strlen(probe_tracepoint
->provider_name
) + 1;
1543 binary_path_len
= strlen(probe_tracepoint
->binary_path
) + 1;
1545 storage_needed
+= probe_name_len
+ provider_name_len
+ binary_path_len
;
1548 * The lookup method is aligned to 64-bit within the buffer.
1549 * This is needed even if there is no lookup method since
1550 * the next structure in the buffer probably needs to be
1551 * aligned too (depending on the arch).
1553 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
1554 storage_needed
+= padding_needed
;
1556 if (location
->lookup_method
) {
1557 /* NOTE: elf look-up method is assumed here. */
1559 sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
1563 * If the caller set buffer to NULL, return the size of the needed buffer.
1566 ret
= storage_needed
;
1570 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
1571 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
1572 buffer
->size
+ storage_needed
);
1578 memset(&flat_probe
, 0, sizeof(flat_probe
));
1580 flat_probe_start
= buffer
->data
+ buffer
->size
;
1581 flat_probe
.parent
.type
= location
->type
;
1584 * The lookup method, if present, is the last element in the flat
1585 * representation of the probe.
1587 if (location
->lookup_method
) {
1588 flat_probe
.parent
.lookup_method
=
1589 (struct lttng_userspace_probe_location_lookup_method
*)
1590 (flat_probe_start
+ sizeof(flat_probe
) +
1591 probe_name_len
+ provider_name_len
+
1592 binary_path_len
+ padding_needed
);
1594 flat_probe
.parent
.lookup_method
= NULL
;
1597 flat_probe
.probe_name
= flat_probe_start
+ sizeof(flat_probe
);
1598 flat_probe
.provider_name
= flat_probe
.probe_name
+ probe_name_len
;
1599 flat_probe
.binary_path
= flat_probe
.provider_name
+ provider_name_len
;
1600 flat_probe
.binary_fd
= -1;
1601 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
, sizeof(flat_probe
));
1606 /* Append all the fields to the buffer */
1607 ret
= lttng_dynamic_buffer_append(buffer
,
1608 probe_tracepoint
->probe_name
, probe_name_len
);
1612 ret
= lttng_dynamic_buffer_append(buffer
,
1613 probe_tracepoint
->provider_name
, provider_name_len
);
1617 ret
= lttng_dynamic_buffer_append(buffer
,
1618 probe_tracepoint
->binary_path
, binary_path_len
);
1623 /* Insert padding before the lookup method. */
1624 ret
= lttng_dynamic_buffer_set_size(buffer
, buffer
->size
+ padding_needed
);
1629 if (!location
->lookup_method
) {
1630 /* Not an error, the default method is used. */
1631 ret
= storage_needed
;
1635 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
1637 flat_lookup_method
.parent
.type
=
1638 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT
;
1639 ret
= lttng_dynamic_buffer_append(buffer
,
1640 &flat_lookup_method
, sizeof(flat_lookup_method
));
1644 ret
= storage_needed
;
1650 int lttng_userspace_probe_location_flatten(
1651 const struct lttng_userspace_probe_location
*location
,
1652 struct lttng_dynamic_buffer
*buffer
)
1656 ret
= -LTTNG_ERR_INVALID
;
1660 /* Only types currently supported. */
1661 switch (location
->type
) {
1662 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1663 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
1665 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1666 ret
= lttng_userspace_probe_location_tracepoint_flatten(location
, buffer
);
1669 ret
= -LTTNG_ERR_INVALID
;
1678 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
1679 const struct lttng_userspace_probe_location
*location
)
1681 struct lttng_userspace_probe_location
*new_location
= NULL
;
1682 enum lttng_userspace_probe_location_type type
;
1688 type
= lttng_userspace_probe_location_get_type(location
);
1690 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
1692 lttng_userspace_probe_location_function_copy(location
);
1693 if (!new_location
) {
1697 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
1699 lttng_userspace_probe_location_tracepoint_copy(location
);
1700 if (!new_location
) {
1705 new_location
= NULL
;
1709 return new_location
;