2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <common/error.h>
20 #include <common/macros.h>
21 #include <common/compat/string.h>
23 #include <lttng/constant.h>
24 #include <lttng/userspace-probe-internal.h>
26 enum lttng_userspace_probe_location_lookup_method_type
27 lttng_userspace_probe_location_lookup_method_get_type(
28 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
30 return lookup_method
? lookup_method
->type
:
31 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN
;
34 void lttng_userspace_probe_location_lookup_method_destroy(
35 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
41 switch (lookup_method
->type
) {
42 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
44 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
=
45 container_of(lookup_method
,
46 struct lttng_userspace_probe_location_lookup_method_elf
, parent
);
55 struct lttng_userspace_probe_location_lookup_method
*
56 lttng_userspace_probe_location_lookup_method_function_elf_create(void)
58 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
59 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
61 elf_method
= zmalloc(sizeof(*elf_method
));
67 ret
= &elf_method
->parent
;
68 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
73 enum lttng_userspace_probe_location_type
lttng_userspace_probe_location_get_type(
74 const struct lttng_userspace_probe_location
*location
)
76 return location
? location
->type
:
77 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN
;
81 void lttng_userspace_probe_location_function_destroy(
82 struct lttng_userspace_probe_location
*location
)
84 struct lttng_userspace_probe_location_function
*location_function
= NULL
;
88 location_function
= container_of(location
,
89 struct lttng_userspace_probe_location_function
, parent
);
91 assert(location_function
);
93 free(location_function
->function_name
);
94 free(location_function
->binary_path
);
95 if (location_function
->binary_fd
>= 0) {
96 if (close(location_function
->binary_fd
)) {
103 void lttng_userspace_probe_location_destroy(
104 struct lttng_userspace_probe_location
*location
)
110 lttng_userspace_probe_location_lookup_method_destroy(
111 location
->lookup_method
);
113 switch (location
->type
) {
114 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
115 lttng_userspace_probe_location_function_destroy(location
);
122 static struct lttng_userspace_probe_location
*
123 lttng_userspace_probe_location_function_create_no_check(const char *binary_path
,
124 const char *function_name
,
125 struct lttng_userspace_probe_location_lookup_method
*lookup_method
,
129 char *function_name_copy
= NULL
, *binary_path_copy
= NULL
;
130 struct lttng_userspace_probe_location
*ret
= NULL
;
131 struct lttng_userspace_probe_location_function
*location
;
134 binary_fd
= open(binary_path
, O_RDONLY
);
136 PERROR("Error opening the binary");
143 function_name_copy
= lttng_strndup(function_name
, LTTNG_SYMBOL_NAME_LEN
);
144 if (!function_name_copy
) {
145 PERROR("Error duplicating the function name");
149 binary_path_copy
= lttng_strndup(binary_path
, LTTNG_PATH_MAX
);
150 if (!binary_path_copy
) {
151 PERROR("Error duplicating the function name");
155 location
= zmalloc(sizeof(*location
));
157 PERROR("Error allocating userspace probe location");
161 location
->function_name
= function_name_copy
;
162 location
->binary_path
= binary_path_copy
;
163 location
->binary_fd
= binary_fd
;
165 ret
= &location
->parent
;
166 ret
->lookup_method
= lookup_method
;
167 ret
->type
= LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
;
171 free(function_name_copy
);
172 free(binary_path_copy
);
173 if (binary_fd
>= 0) {
174 if (close(binary_fd
)) {
175 PERROR("Error closing binary fd in error path");
182 struct lttng_userspace_probe_location
*
183 lttng_userspace_probe_location_function_create(const char *binary_path
,
184 const char *function_name
,
185 struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
187 struct lttng_userspace_probe_location
*ret
= NULL
;
189 if (!binary_path
|| !function_name
) {
190 ERR("Invalid argument(s)");
194 switch (lttng_userspace_probe_location_lookup_method_get_type(
196 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
197 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
200 /* Invalid probe location lookup method. */
204 ret
= lttng_userspace_probe_location_function_create_no_check(
205 binary_path
, function_name
, lookup_method
, true);
210 static struct lttng_userspace_probe_location_lookup_method
*
211 lttng_userspace_probe_location_lookup_method_function_elf_copy(
212 const struct lttng_userspace_probe_location_lookup_method
*lookup_method
)
214 struct lttng_userspace_probe_location_lookup_method
*parent
= NULL
;
215 struct lttng_userspace_probe_location_lookup_method_elf
*elf_method
;
217 assert(lookup_method
);
218 assert(lookup_method
->type
==
219 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
);
221 elf_method
= zmalloc(sizeof(*elf_method
));
223 PERROR("Error allocating ELF userspace probe lookup method");
227 elf_method
->parent
.type
= lookup_method
->type
;
228 parent
= &elf_method
->parent
;
237 static struct lttng_userspace_probe_location
*
238 lttng_userspace_probe_location_function_copy(
239 const struct lttng_userspace_probe_location
*location
)
241 enum lttng_userspace_probe_location_lookup_method_type lookup_type
;
242 struct lttng_userspace_probe_location
*new_location
= NULL
;
243 struct lttng_userspace_probe_location_lookup_method
*lookup_method
= NULL
;
244 char *binary_path
= NULL
;
245 char *function_name
= NULL
;
249 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
251 /* Duplicate probe location fields */
253 lttng_strndup(lttng_userspace_probe_location_function_get_binary_path(location
),
260 lttng_strndup(lttng_userspace_probe_location_function_get_function_name(location
),
261 LTTNG_SYMBOL_NAME_LEN
);
262 if (!function_name
) {
263 PERROR("Error duplicating function name string");
267 /* Duplicate the binary fd */
268 fd
= dup(lttng_userspace_probe_location_function_get_binary_fd(location
));
270 PERROR("Error duplicating file descriptor to binary");
275 * Duplicate probe location method fields
277 lookup_type
= lttng_userspace_probe_location_lookup_method_get_type(
278 location
->lookup_method
);
279 switch (lookup_type
) {
280 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
282 lttng_userspace_probe_location_lookup_method_function_elf_copy(
283 location
->lookup_method
);
284 if (!lookup_method
) {
289 /* Invalid probe location lookup method. */
293 /* Create the probe_location */
294 new_location
= lttng_userspace_probe_location_function_create_no_check(
295 binary_path
, function_name
, lookup_method
, true);
297 goto destroy_lookup_method
;
300 /* Set the duplicated fd to the new probe_location */
301 if (lttng_userspace_probe_location_function_set_binary_fd(new_location
, fd
) < 0) {
302 goto destroy_probe_location
;
307 destroy_probe_location
:
308 lttng_userspace_probe_location_destroy(new_location
);
309 destroy_lookup_method
:
310 lttng_userspace_probe_location_lookup_method_destroy(lookup_method
);
313 PERROR("Error closing duplicated file descriptor in error path");
323 const char *lttng_userspace_probe_location_function_get_binary_path(
324 const struct lttng_userspace_probe_location
*location
)
326 const char *ret
= NULL
;
327 struct lttng_userspace_probe_location_function
*function_location
;
329 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
330 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
331 ERR("Invalid argument(s)");
335 function_location
= container_of(location
,
336 struct lttng_userspace_probe_location_function
,
338 ret
= function_location
->binary_path
;
343 const char *lttng_userspace_probe_location_function_get_function_name(
344 const struct lttng_userspace_probe_location
*location
)
346 const char *ret
= NULL
;
347 struct lttng_userspace_probe_location_function
*function_location
;
349 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
350 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
351 ERR("Invalid argument(s)");
355 function_location
= container_of(location
,
356 struct lttng_userspace_probe_location_function
, parent
);
357 ret
= function_location
->function_name
;
362 int lttng_userspace_probe_location_function_get_binary_fd(
363 const struct lttng_userspace_probe_location
*location
)
366 struct lttng_userspace_probe_location_function
*function_location
;
368 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
369 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
370 ERR("Invalid argument(s)");
374 function_location
= container_of(location
,
375 struct lttng_userspace_probe_location_function
, parent
);
376 ret
= function_location
->binary_fd
;
381 static struct lttng_userspace_probe_location_lookup_method
*
382 lttng_userspace_probe_location_function_get_lookup_method(
383 const struct lttng_userspace_probe_location
*location
)
385 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
387 if (!location
|| lttng_userspace_probe_location_get_type(location
) !=
388 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
) {
389 ERR("Invalid argument(s)");
393 ret
= location
->lookup_method
;
398 struct lttng_userspace_probe_location_lookup_method
*
399 lttng_userspace_probe_location_get_lookup_method(
400 const struct lttng_userspace_probe_location
*location
)
402 struct lttng_userspace_probe_location_lookup_method
*ret
= NULL
;
405 switch (location
->type
) {
406 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
407 ret
= lttng_userspace_probe_location_function_get_lookup_method(
411 ERR("Unknowned lookup method.");
418 int lttng_userspace_probe_location_lookup_method_serialize(
419 struct lttng_userspace_probe_location_lookup_method
*method
,
420 struct lttng_dynamic_buffer
*buffer
)
423 struct lttng_userspace_probe_location_lookup_method_comm
426 lookup_method_comm
.type
= (int8_t) (method
? method
->type
:
427 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
);
429 ret
= lttng_dynamic_buffer_append(buffer
, &lookup_method_comm
,
430 sizeof(lookup_method_comm
));
435 ret
= sizeof(lookup_method_comm
);
441 int lttng_userspace_probe_location_function_serialize(
442 const struct lttng_userspace_probe_location
*location
,
443 struct lttng_dynamic_buffer
*buffer
,
447 size_t function_name_len
, binary_path_len
;
448 struct lttng_userspace_probe_location_function
*location_function
;
449 struct lttng_userspace_probe_location_function_comm location_function_comm
;
452 assert(lttng_userspace_probe_location_get_type(location
) ==
453 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
455 location_function
= container_of(location
,
456 struct lttng_userspace_probe_location_function
,
458 if (!location_function
->function_name
|| !location_function
->binary_path
) {
459 ret
= -LTTNG_ERR_INVALID
;
463 if (binary_fd
&& location_function
->binary_fd
< 0) {
464 ret
= -LTTNG_ERR_INVALID
;
469 *binary_fd
= location_function
->binary_fd
;
472 function_name_len
= strlen(location_function
->function_name
);
473 if (function_name_len
== 0) {
474 ret
= -LTTNG_ERR_INVALID
;
477 binary_path_len
= strlen(location_function
->binary_path
);
478 if (binary_path_len
== 0) {
479 ret
= -LTTNG_ERR_INVALID
;
483 location_function_comm
.function_name_len
= function_name_len
+ 1;
484 location_function_comm
.binary_path_len
= binary_path_len
+ 1;
487 ret
= lttng_dynamic_buffer_append(buffer
,
488 &location_function_comm
,
489 sizeof(location_function_comm
));
491 ret
= -LTTNG_ERR_INVALID
;
494 ret
= lttng_dynamic_buffer_append(buffer
,
495 location_function
->function_name
,
496 location_function_comm
.function_name_len
);
498 ret
= -LTTNG_ERR_INVALID
;
501 ret
= lttng_dynamic_buffer_append(buffer
,
502 location_function
->binary_path
,
503 location_function_comm
.binary_path_len
);
505 ret
= -LTTNG_ERR_INVALID
;
509 ret
= sizeof(location_function_comm
) +
510 location_function_comm
.function_name_len
+
511 location_function_comm
.binary_path_len
;
517 int lttng_userspace_probe_location_serialize(
518 const struct lttng_userspace_probe_location
*location
,
519 struct lttng_dynamic_buffer
*buffer
,
522 int ret
, buffer_use
= 0;
523 struct lttng_userspace_probe_location_comm location_generic_comm
;
526 ERR("Invalid argument(s)");
527 ret
= -LTTNG_ERR_INVALID
;
531 memset(&location_generic_comm
, 0, sizeof(location_generic_comm
));
533 location_generic_comm
.type
= (int8_t) location
->type
;
535 ret
= lttng_dynamic_buffer_append(buffer
, &location_generic_comm
,
536 sizeof(location_generic_comm
));
541 buffer_use
+= sizeof(location_generic_comm
);
543 switch (lttng_userspace_probe_location_get_type(location
)) {
544 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
545 ret
= lttng_userspace_probe_location_function_serialize(
546 location
, buffer
, binary_fd
);
549 ERR("Unsupported probe location type");
550 ret
= -LTTNG_ERR_INVALID
;
558 ret
= lttng_userspace_probe_location_lookup_method_serialize(
559 location
->lookup_method
, buffer
);
569 int lttng_userspace_probe_location_function_create_from_buffer(
570 const struct lttng_buffer_view
*buffer
,
571 struct lttng_userspace_probe_location
**location
)
573 struct lttng_userspace_probe_location_function_comm
*location_function_comm
;
574 const char *function_name_src
, *binary_path_src
;
575 char *function_name
= NULL
, *binary_path
= NULL
;
579 assert(buffer
->data
);
582 location_function_comm
=
583 (struct lttng_userspace_probe_location_function_comm
*) buffer
->data
;
585 const size_t expected_size
= sizeof(*location_function_comm
) +
586 location_function_comm
->function_name_len
+
587 location_function_comm
->binary_path_len
;
589 if (buffer
->size
< expected_size
) {
590 ret
= -LTTNG_ERR_INVALID
;
594 function_name_src
= buffer
->data
+ sizeof(*location_function_comm
);
595 binary_path_src
= function_name_src
+
596 location_function_comm
->function_name_len
;
598 if (function_name_src
[location_function_comm
->function_name_len
- 1] != '\0') {
599 ret
= -LTTNG_ERR_INVALID
;
602 if (binary_path_src
[location_function_comm
->binary_path_len
- 1] != '\0') {
603 ret
= -LTTNG_ERR_INVALID
;
607 function_name
= lttng_strndup(function_name_src
, LTTNG_SYMBOL_NAME_LEN
);
608 if (!function_name
) {
609 PERROR("lttng_strndup");
613 binary_path
= lttng_strndup(binary_path_src
, LTTNG_PATH_MAX
);
615 PERROR("lttng_strndup");
619 *location
= lttng_userspace_probe_location_function_create_no_check(
620 binary_path
, function_name
, NULL
, false);
622 ret
= -LTTNG_ERR_INVALID
;
626 ret
= (int) expected_size
;
634 int lttng_userspace_probe_location_lookup_method_create_from_buffer(
635 struct lttng_buffer_view
*buffer
,
636 struct lttng_userspace_probe_location_lookup_method
**lookup_method
)
639 struct lttng_userspace_probe_location_lookup_method_comm
*lookup_comm
;
640 enum lttng_userspace_probe_location_lookup_method_type type
;
643 assert(buffer
->data
);
644 assert(lookup_method
);
646 if (buffer
->size
< sizeof(*lookup_comm
)) {
647 ret
= -LTTNG_ERR_INVALID
;
651 lookup_comm
= (struct lttng_userspace_probe_location_lookup_method_comm
*)
653 type
= (enum lttng_userspace_probe_location_lookup_method_type
)
656 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT
:
657 *lookup_method
= NULL
;
659 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
:
661 lttng_userspace_probe_location_lookup_method_function_elf_create();
662 if (!(*lookup_method
)) {
663 ret
= -LTTNG_ERR_INVALID
;
668 ret
= -LTTNG_ERR_INVALID
;
672 ret
= sizeof(*lookup_comm
);
678 int lttng_userspace_probe_location_create_from_buffer(
679 const struct lttng_buffer_view
*buffer
,
680 struct lttng_userspace_probe_location
**location
)
682 struct lttng_userspace_probe_location_lookup_method
*lookup_method
;
683 struct lttng_userspace_probe_location_comm
*probe_location_comm
;
684 enum lttng_userspace_probe_location_type type
;
685 struct lttng_buffer_view lookup_method_view
;
691 assert(buffer
->data
);
694 lookup_method
= NULL
;
696 if (buffer
->size
<= sizeof(*probe_location_comm
)) {
697 ret
= -LTTNG_ERR_INVALID
;
701 probe_location_comm
=
702 (struct lttng_userspace_probe_location_comm
*) buffer
->data
;
703 type
= (enum lttng_userspace_probe_location_type
) probe_location_comm
->type
;
704 consumed
+= sizeof(*probe_location_comm
);
707 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
709 struct lttng_buffer_view view
= lttng_buffer_view_from_view(
710 buffer
, consumed
, buffer
->size
- consumed
);
712 ret
= lttng_userspace_probe_location_function_create_from_buffer(
720 ret
= -LTTNG_ERR_INVALID
;
725 if (buffer
->size
<= consumed
) {
726 ret
= -LTTNG_ERR_INVALID
;
730 lookup_method_view
= lttng_buffer_view_from_view(buffer
, consumed
,
731 buffer
->size
- consumed
);
732 ret
= lttng_userspace_probe_location_lookup_method_create_from_buffer(
733 &lookup_method_view
, &lookup_method
);
735 ret
= -LTTNG_ERR_INVALID
;
739 assert(lookup_method
);
740 (*location
)->lookup_method
= lookup_method
;
741 lookup_method
= NULL
;
748 int lttng_userspace_probe_location_function_set_binary_fd(
749 struct lttng_userspace_probe_location
*location
, int binary_fd
)
752 struct lttng_userspace_probe_location_function
*function_location
;
755 assert(location
->type
== LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
);
757 function_location
= container_of(location
,
758 struct lttng_userspace_probe_location_function
, parent
);
759 if (function_location
->binary_fd
>= 0) {
760 ret
= close(function_location
->binary_fd
);
763 ret
= -LTTNG_ERR_INVALID
;
768 function_location
->binary_fd
= binary_fd
;
774 int lttng_userspace_probe_location_function_flatten(
775 const struct lttng_userspace_probe_location
*location
,
776 struct lttng_dynamic_buffer
*buffer
)
778 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method
;
779 struct lttng_userspace_probe_location_function
*probe_function
;
780 struct lttng_userspace_probe_location_function flat_probe
;
781 size_t function_name_len
, binary_path_len
;
782 size_t padding_needed
= 0;
783 char *flat_probe_start
;
784 int storage_needed
= 0;
789 if (location
->lookup_method
&& location
->lookup_method
->type
!=
790 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
) {
791 ret
= -LTTNG_ERR_INVALID
;
795 probe_function
= container_of(location
,
796 struct lttng_userspace_probe_location_function
,
798 assert(probe_function
->function_name
);
799 assert(probe_function
->binary_path
);
802 sizeof(struct lttng_userspace_probe_location_function
);
803 function_name_len
= strlen(probe_function
->function_name
) + 1;
804 binary_path_len
= strlen(probe_function
->binary_path
) + 1;
805 storage_needed
+= function_name_len
+ binary_path_len
;
808 * The lookup method is aligned to 64-bit within the buffer.
809 * This is needed even if there is no lookup method since
810 * the next structure in the buffer probably needs to be
811 * aligned too (depending on the arch).
813 padding_needed
= ALIGN_TO(storage_needed
, sizeof(uint64_t)) - storage_needed
;
814 storage_needed
+= padding_needed
;
816 if (location
->lookup_method
) {
817 /* NOTE: elf look-up method is assumed here. */
818 storage_needed
+= sizeof(struct lttng_userspace_probe_location_lookup_method_elf
);
822 ret
= storage_needed
;
826 if (lttng_dynamic_buffer_get_capacity_left(buffer
) < storage_needed
) {
827 ret
= lttng_dynamic_buffer_set_capacity(buffer
,
828 buffer
->size
+ storage_needed
);
834 memset(&flat_probe
, 0, sizeof(flat_probe
));
836 flat_probe_start
= buffer
->data
+ buffer
->size
;
837 flat_probe
.parent
.type
= location
->type
;
839 * The lookup method, if present, is the last element in the flat
840 * representation of the probe.
842 if (location
->lookup_method
) {
843 flat_probe
.parent
.lookup_method
=
844 (struct lttng_userspace_probe_location_lookup_method
*)
845 (flat_probe_start
+ sizeof(flat_probe
) +
846 function_name_len
+ binary_path_len
+ padding_needed
);
848 flat_probe
.parent
.lookup_method
= NULL
;
851 flat_probe
.function_name
= flat_probe_start
+ sizeof(flat_probe
);
852 flat_probe
.binary_path
= flat_probe
.function_name
+ function_name_len
;
853 flat_probe
.binary_fd
= -1;
854 ret
= lttng_dynamic_buffer_append(buffer
, &flat_probe
,
860 ret
= lttng_dynamic_buffer_append(buffer
,
861 probe_function
->function_name
, function_name_len
);
865 ret
= lttng_dynamic_buffer_append(buffer
,
866 probe_function
->binary_path
, binary_path_len
);
871 /* Insert padding before the lookup method. */
872 ret
= lttng_dynamic_buffer_set_size(buffer
,
873 buffer
->size
+ padding_needed
);
878 if (!location
->lookup_method
) {
879 /* Not an error, the default method is used. */
880 ret
= storage_needed
;
884 memset(&flat_lookup_method
, 0, sizeof(flat_lookup_method
));
885 flat_lookup_method
.parent
.type
=
886 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF
;
887 ret
= lttng_dynamic_buffer_append(buffer
,
888 &flat_lookup_method
, sizeof(flat_lookup_method
));
892 ret
= storage_needed
;
898 int lttng_userspace_probe_location_flatten(
899 const struct lttng_userspace_probe_location
*location
,
900 struct lttng_dynamic_buffer
*buffer
)
904 ret
= -LTTNG_ERR_INVALID
;
908 /* Only types currently supported. */
909 switch (location
->type
) {
910 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
911 ret
= lttng_userspace_probe_location_function_flatten(location
, buffer
);
914 ret
= -LTTNG_ERR_INVALID
;
923 struct lttng_userspace_probe_location
*lttng_userspace_probe_location_copy(
924 const struct lttng_userspace_probe_location
*location
)
926 struct lttng_userspace_probe_location
*new_location
= NULL
;
927 enum lttng_userspace_probe_location_type type
;
933 type
= lttng_userspace_probe_location_get_type(location
);
935 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
937 lttng_userspace_probe_location_function_copy(location
);