Introduce lttng_domain_type_str utility
[lttng-tools.git] / src / common / userspace-probe.c
CommitLineData
1ce46cfe 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
1ce46cfe 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
1ce46cfe 5 *
1ce46cfe
JG
6 */
7
e368fb43 8#include "lttng/lttng-error.h"
1ce46cfe 9#include <assert.h>
dfcfa983 10#include <common/compat/string.h>
1ce46cfe
JG
11#include <common/error.h>
12#include <common/macros.h>
9e620ea7
JG
13#include <common/payload.h>
14#include <common/payload-view.h>
1ce46cfe
JG
15#include <fcntl.h>
16#include <lttng/constant.h>
17#include <lttng/userspace-probe-internal.h>
dfcfa983
JR
18#include <sys/stat.h>
19#include <sys/types.h>
20#include <sys/unistd.h>
1ce46cfe 21
fe489250 22static
2cde0510 23int lttng_userspace_probe_location_function_set_binary_fd_handle(
fe489250 24 struct lttng_userspace_probe_location *location,
2cde0510 25 struct fd_handle *binary_fd_handle);
fe489250
JG
26
27static
2cde0510 28int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
fe489250 29 struct lttng_userspace_probe_location *location,
2cde0510 30 struct fd_handle *binary_fd_handle);
fe489250 31
1ce46cfe
JG
32enum lttng_userspace_probe_location_lookup_method_type
33lttng_userspace_probe_location_lookup_method_get_type(
34 const struct lttng_userspace_probe_location_lookup_method *lookup_method)
35{
36 return lookup_method ? lookup_method->type :
37 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_UNKNOWN;
38}
39
40void lttng_userspace_probe_location_lookup_method_destroy(
41 struct lttng_userspace_probe_location_lookup_method *lookup_method)
42{
43 if (!lookup_method){
44 return;
45 }
46
5d21f143 47 free(lookup_method);
1ce46cfe
JG
48}
49
50struct lttng_userspace_probe_location_lookup_method *
51lttng_userspace_probe_location_lookup_method_function_elf_create(void)
52{
53 struct lttng_userspace_probe_location_lookup_method *ret = NULL;
54 struct lttng_userspace_probe_location_lookup_method_elf *elf_method;
55
56 elf_method = zmalloc(sizeof(*elf_method));
57 if (!elf_method) {
58 PERROR("zmalloc");
59 goto end;
60 }
61
62 ret = &elf_method->parent;
63 ret->type = LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF;
64end:
65 return ret;
66}
67
f4d0bb2e
FD
68struct lttng_userspace_probe_location_lookup_method *
69lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create(void)
70{
71 struct lttng_userspace_probe_location_lookup_method *ret = NULL;
72 struct lttng_userspace_probe_location_lookup_method_sdt *sdt_method;
73
74 sdt_method = zmalloc(sizeof(*sdt_method));
75 if (!sdt_method) {
76 PERROR("zmalloc");
77 goto end;
78 }
79
80 ret = &sdt_method->parent;
81 ret->type = LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT;
82end:
83 return ret;
84}
85
1ce46cfe
JG
86enum lttng_userspace_probe_location_type lttng_userspace_probe_location_get_type(
87 const struct lttng_userspace_probe_location *location)
88{
89 return location ? location->type :
90 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN;
91}
92
93static
94void lttng_userspace_probe_location_function_destroy(
95 struct lttng_userspace_probe_location *location)
96{
97 struct lttng_userspace_probe_location_function *location_function = NULL;
98
99 assert(location);
100
101 location_function = container_of(location,
102 struct lttng_userspace_probe_location_function, parent);
103
104 assert(location_function);
105
106 free(location_function->function_name);
107 free(location_function->binary_path);
2cde0510 108 fd_handle_put(location_function->binary_fd_handle);
1ce46cfe
JG
109 free(location);
110}
111
f4d0bb2e
FD
112static
113void lttng_userspace_probe_location_tracepoint_destroy(
114 struct lttng_userspace_probe_location *location)
115{
116 struct lttng_userspace_probe_location_tracepoint *location_tracepoint = NULL;
117
118 assert(location);
119
120 location_tracepoint = container_of(location,
121 struct lttng_userspace_probe_location_tracepoint,
122 parent);
123
124 assert(location_tracepoint);
125
126 free(location_tracepoint->probe_name);
127 free(location_tracepoint->provider_name);
128 free(location_tracepoint->binary_path);
2cde0510 129 fd_handle_put(location_tracepoint->binary_fd_handle);
f4d0bb2e
FD
130 free(location);
131}
132
1ce46cfe
JG
133void lttng_userspace_probe_location_destroy(
134 struct lttng_userspace_probe_location *location)
135{
136 if (!location) {
137 return;
138 }
139
140 lttng_userspace_probe_location_lookup_method_destroy(
141 location->lookup_method);
142
143 switch (location->type) {
144 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
145 lttng_userspace_probe_location_function_destroy(location);
146 break;
f4d0bb2e
FD
147 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
148 lttng_userspace_probe_location_tracepoint_destroy(location);
149 break;
1ce46cfe 150 default:
adf53c67 151 abort();
1ce46cfe
JG
152 }
153}
154
dfcfa983
JR
155/* Compare two file descriptors based on their inode and device numbers. */
156static bool fd_is_equal(int a, int b)
157{
158 int ret;
159 bool is_equal = false;
160 struct stat a_stat, b_stat;
161
162 if (a < 0 && b >= 0) {
163 goto end;
164 }
165
166 if (b < 0 && a >= 0) {
167 goto end;
168 }
169
170 if (a < 0 && b < 0) {
171 if (a == -1 && b == -1) {
172 is_equal = true;
173 goto end;
174 }
175
176 /* Invalid state, abort. */
177 abort();
178 }
179
180 /* Both are valid file descriptors. */
181 ret = fstat(a, &a_stat);
182 if (ret) {
183 PERROR("Failed to fstat userspace probe location binary fd %d",
184 a);
185 goto end;
186 }
187
188 ret = fstat(b, &b_stat);
189 if (ret) {
190 PERROR("Failed to fstat userspace probe location binary fd %d",
191 b);
192 goto end;
193 }
194
195 is_equal = (a_stat.st_ino == b_stat.st_ino) &&
196 (a_stat.st_dev == b_stat.st_dev);
197
198end:
199 return is_equal;
200}
201
202static bool lttng_userspace_probe_location_function_is_equal(
203 const struct lttng_userspace_probe_location *_a,
204 const struct lttng_userspace_probe_location *_b)
205{
206 bool is_equal = false;
207 struct lttng_userspace_probe_location_function *a, *b;
208
209 a = container_of(_a, struct lttng_userspace_probe_location_function,
210 parent);
211 b = container_of(_b, struct lttng_userspace_probe_location_function,
212 parent);
213
214 if (a->instrumentation_type != b->instrumentation_type) {
215 goto end;
216 }
217
218 assert(a->function_name);
219 assert(b->function_name);
220 if (strcmp(a->function_name, b->function_name)) {
221 goto end;
222 }
223
224 assert(a->binary_path);
225 assert(b->binary_path);
226 if (strcmp(a->binary_path, b->binary_path)) {
227 goto end;
228 }
229
2cde0510
JG
230 is_equal = fd_is_equal(a->binary_fd_handle ? fd_handle_get_fd(a->binary_fd_handle) : -1,
231 b->binary_fd_handle ? fd_handle_get_fd(b->binary_fd_handle) : -1);
dfcfa983
JR
232end:
233 return is_equal;
234}
235
1ce46cfe
JG
236static struct lttng_userspace_probe_location *
237lttng_userspace_probe_location_function_create_no_check(const char *binary_path,
238 const char *function_name,
239 struct lttng_userspace_probe_location_lookup_method *lookup_method,
240 bool open_binary)
241{
242 int binary_fd = -1;
fe489250 243 struct fd_handle *binary_fd_handle = NULL;
1ce46cfe
JG
244 char *function_name_copy = NULL, *binary_path_copy = NULL;
245 struct lttng_userspace_probe_location *ret = NULL;
246 struct lttng_userspace_probe_location_function *location;
247
248 if (open_binary) {
249 binary_fd = open(binary_path, O_RDONLY);
250 if (binary_fd < 0) {
251 PERROR("Error opening the binary");
252 goto error;
253 }
fe489250
JG
254
255 binary_fd_handle = fd_handle_create(binary_fd);
256 if (!binary_fd) {
257 goto error;
258 }
259
260 /* Ownership transferred to fd_handle. */
1ce46cfe
JG
261 binary_fd = -1;
262 }
263
264 function_name_copy = lttng_strndup(function_name, LTTNG_SYMBOL_NAME_LEN);
265 if (!function_name_copy) {
266 PERROR("Error duplicating the function name");
267 goto error;
268 }
269
270 binary_path_copy = lttng_strndup(binary_path, LTTNG_PATH_MAX);
271 if (!binary_path_copy) {
272 PERROR("Error duplicating the function name");
273 goto error;
274 }
275
276 location = zmalloc(sizeof(*location));
277 if (!location) {
278 PERROR("Error allocating userspace probe location");
279 goto error;
280 }
281
282 location->function_name = function_name_copy;
283 location->binary_path = binary_path_copy;
2cde0510 284 location->binary_fd_handle = binary_fd_handle;
fe489250 285 binary_fd_handle = NULL;
9d3981b5
JG
286 location->instrumentation_type =
287 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY;
1ce46cfe
JG
288
289 ret = &location->parent;
290 ret->lookup_method = lookup_method;
291 ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION;
dfcfa983 292 ret->equal = lttng_userspace_probe_location_function_is_equal;
1ce46cfe
JG
293 goto end;
294
295error:
296 free(function_name_copy);
297 free(binary_path_copy);
298 if (binary_fd >= 0) {
299 if (close(binary_fd)) {
300 PERROR("Error closing binary fd in error path");
301 }
302 }
fe489250 303 fd_handle_put(binary_fd_handle);
1ce46cfe
JG
304end:
305 return ret;
306}
307
dfcfa983
JR
308static bool lttng_userspace_probe_location_tracepoint_is_equal(
309 const struct lttng_userspace_probe_location *_a,
310 const struct lttng_userspace_probe_location *_b)
311{
312 bool is_equal = false;
313 struct lttng_userspace_probe_location_tracepoint *a, *b;
314
315 a = container_of(_a, struct lttng_userspace_probe_location_tracepoint,
316 parent);
317 b = container_of(_b, struct lttng_userspace_probe_location_tracepoint,
318 parent);
319
320 assert(a->probe_name);
321 assert(b->probe_name);
322 if (strcmp(a->probe_name, b->probe_name)) {
323 goto end;
324 }
325
326 assert(a->provider_name);
327 assert(b->provider_name);
328 if (strcmp(a->provider_name, b->provider_name)) {
329 goto end;
330 }
331
332 assert(a->binary_path);
333 assert(b->binary_path);
334 if (strcmp(a->binary_path, b->binary_path)) {
335 goto end;
336 }
337
2cde0510
JG
338 is_equal = fd_is_equal(a->binary_fd_handle ? fd_handle_get_fd(a->binary_fd_handle) : -1,
339 b->binary_fd_handle ? fd_handle_get_fd(b->binary_fd_handle) : -1);
dfcfa983
JR
340
341end:
342 return is_equal;
343}
344
f4d0bb2e
FD
345static struct lttng_userspace_probe_location *
346lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_path,
347 const char *provider_name, const char *probe_name,
348 struct lttng_userspace_probe_location_lookup_method *lookup_method,
349 bool open_binary)
350{
351 int binary_fd = -1;
fe489250 352 struct fd_handle *binary_fd_handle = NULL;
f4d0bb2e
FD
353 char *probe_name_copy = NULL;
354 char *provider_name_copy = NULL;
355 char *binary_path_copy = NULL;
356 struct lttng_userspace_probe_location *ret = NULL;
357 struct lttng_userspace_probe_location_tracepoint *location;
358
359 if (open_binary) {
360 binary_fd = open(binary_path, O_RDONLY);
361 if (binary_fd < 0) {
362 PERROR("open");
363 goto error;
364 }
fe489250
JG
365
366 binary_fd_handle = fd_handle_create(binary_fd);
367 if (!binary_fd) {
368 goto error;
369 }
370
371 /* Ownership transferred to fd_handle. */
f4d0bb2e
FD
372 binary_fd = -1;
373 }
374
375 probe_name_copy = lttng_strndup(probe_name, LTTNG_SYMBOL_NAME_LEN);
376 if (!probe_name_copy) {
377 PERROR("lttng_strndup");
378 goto error;
379 }
380
381 provider_name_copy = lttng_strndup(provider_name, LTTNG_SYMBOL_NAME_LEN);
382 if (!provider_name_copy) {
383 PERROR("lttng_strndup");
384 goto error;
385 }
386
387 binary_path_copy = lttng_strndup(binary_path, LTTNG_PATH_MAX);
388 if (!binary_path_copy) {
389 PERROR("lttng_strndup");
390 goto error;
391 }
392
393 location = zmalloc(sizeof(*location));
394 if (!location) {
395 PERROR("zmalloc");
396 goto error;
397 }
398
399 location->probe_name = probe_name_copy;
400 location->provider_name = provider_name_copy;
401 location->binary_path = binary_path_copy;
2cde0510 402 location->binary_fd_handle = binary_fd_handle;
fe489250 403 binary_fd_handle = NULL;
f4d0bb2e
FD
404
405 ret = &location->parent;
406 ret->lookup_method = lookup_method;
407 ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT;
dfcfa983 408 ret->equal = lttng_userspace_probe_location_tracepoint_is_equal;
f4d0bb2e
FD
409 goto end;
410
411error:
412 free(probe_name_copy);
413 free(provider_name_copy);
7c86453b 414 free(binary_path_copy);
f4d0bb2e
FD
415 if (binary_fd >= 0) {
416 if (close(binary_fd)) {
417 PERROR("Error closing binary fd in error path");
418 }
419 }
fe489250 420 fd_handle_put(binary_fd_handle);
f4d0bb2e
FD
421end:
422 return ret;
423}
424
1ce46cfe
JG
425struct lttng_userspace_probe_location *
426lttng_userspace_probe_location_function_create(const char *binary_path,
427 const char *function_name,
428 struct lttng_userspace_probe_location_lookup_method *lookup_method)
429{
430 struct lttng_userspace_probe_location *ret = NULL;
431
432 if (!binary_path || !function_name) {
f04a8200 433 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
1ce46cfe
JG
434 goto end;
435 }
436
437 switch (lttng_userspace_probe_location_lookup_method_get_type(
438 lookup_method)) {
439 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT:
440 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
441 break;
442 default:
443 /* Invalid probe location lookup method. */
444 goto end;
445 }
446
447 ret = lttng_userspace_probe_location_function_create_no_check(
448 binary_path, function_name, lookup_method, true);
449end:
450 return ret;
451}
452
f4d0bb2e
FD
453struct lttng_userspace_probe_location *
454lttng_userspace_probe_location_tracepoint_create(const char *binary_path,
455 const char *provider_name, const char *probe_name,
456 struct lttng_userspace_probe_location_lookup_method *lookup_method)
457{
458 struct lttng_userspace_probe_location *ret = NULL;
459
460 if (!binary_path || !probe_name || !provider_name) {
f04a8200 461 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
f4d0bb2e
FD
462 goto end;
463 }
464
465 switch (lttng_userspace_probe_location_lookup_method_get_type(
466 lookup_method)) {
467 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
468 break;
469 default:
470 /* Invalid probe location lookup method. */
471 goto end;
472 }
473
474 ret = lttng_userspace_probe_location_tracepoint_create_no_check(
475 binary_path, provider_name, probe_name, lookup_method, true);
476end:
477 return ret;
478}
479
394357fe
FD
480static struct lttng_userspace_probe_location_lookup_method *
481lttng_userspace_probe_location_lookup_method_function_elf_copy(
482 const struct lttng_userspace_probe_location_lookup_method *lookup_method)
483{
484 struct lttng_userspace_probe_location_lookup_method *parent = NULL;
485 struct lttng_userspace_probe_location_lookup_method_elf *elf_method;
486
487 assert(lookup_method);
488 assert(lookup_method->type ==
489 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF);
490
491 elf_method = zmalloc(sizeof(*elf_method));
492 if (!elf_method) {
493 PERROR("Error allocating ELF userspace probe lookup method");
494 goto error;
495 }
496
497 elf_method->parent.type = lookup_method->type;
498 parent = &elf_method->parent;
499
500 goto end;
501error:
502 parent = NULL;
503end:
504 return parent;
505}
506
f4d0bb2e
FD
507static struct lttng_userspace_probe_location_lookup_method *
508lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
509 struct lttng_userspace_probe_location_lookup_method *lookup_method)
510{
511 struct lttng_userspace_probe_location_lookup_method *parent = NULL;
512 struct lttng_userspace_probe_location_lookup_method_sdt *sdt_method;
513
514 assert(lookup_method);
515 assert(lookup_method->type ==
516 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT);
517
518 sdt_method = zmalloc(sizeof(*sdt_method));
519 if (!sdt_method) {
520 PERROR("zmalloc");
521 goto error;
522 }
523
524 sdt_method->parent.type = lookup_method->type;
525 parent = &sdt_method->parent;
526
527 goto end;
528
529error:
530 parent = NULL;
531end:
532 return parent;
533}
534
394357fe
FD
535static struct lttng_userspace_probe_location *
536lttng_userspace_probe_location_function_copy(
537 const struct lttng_userspace_probe_location *location)
538{
539 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
540 struct lttng_userspace_probe_location *new_location = NULL;
541 struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
cc831309
FD
542 const char *binary_path = NULL;
543 const char *function_name = NULL;
fe489250 544 struct lttng_userspace_probe_location_function *function_location;
394357fe
FD
545
546 assert(location);
547 assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION);
fe489250
JG
548 function_location = container_of(
549 location, typeof(*function_location), parent);
394357fe 550
cc831309
FD
551 /* Get probe location fields */
552 binary_path = lttng_userspace_probe_location_function_get_binary_path(location);
394357fe 553 if (!binary_path) {
cc831309 554 ERR("Userspace probe binary path is NULL");
394357fe
FD
555 goto error;
556 }
557
cc831309 558 function_name = lttng_userspace_probe_location_function_get_function_name(location);
394357fe 559 if (!function_name) {
cc831309 560 ERR("Userspace probe function name is NULL");
394357fe
FD
561 goto error;
562 }
563
394357fe
FD
564 /*
565 * Duplicate probe location method fields
566 */
567 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(
568 location->lookup_method);
569 switch (lookup_type) {
570 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
571 lookup_method =
572 lttng_userspace_probe_location_lookup_method_function_elf_copy(
573 location->lookup_method);
574 if (!lookup_method) {
fe489250 575 goto error;
394357fe
FD
576 }
577 break;
578 default:
579 /* Invalid probe location lookup method. */
fe489250 580 goto error;
394357fe
FD
581 }
582
583 /* Create the probe_location */
584 new_location = lttng_userspace_probe_location_function_create_no_check(
cc831309 585 binary_path, function_name, lookup_method, false);
394357fe
FD
586 if (!new_location) {
587 goto destroy_lookup_method;
588 }
589
590 /* Set the duplicated fd to the new probe_location */
2cde0510
JG
591 if (lttng_userspace_probe_location_function_set_binary_fd_handle(new_location,
592 function_location->binary_fd_handle) < 0) {
394357fe
FD
593 goto destroy_probe_location;
594 }
595
596 goto end;
597
598destroy_probe_location:
599 lttng_userspace_probe_location_destroy(new_location);
600destroy_lookup_method:
601 lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
394357fe 602error:
394357fe
FD
603 new_location = NULL;
604end:
605 return new_location;
606}
607
f4d0bb2e
FD
608static struct lttng_userspace_probe_location *
609lttng_userspace_probe_location_tracepoint_copy(
610 const struct lttng_userspace_probe_location *location)
611{
612 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
613 struct lttng_userspace_probe_location *new_location = NULL;
614 struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
cc831309
FD
615 const char *binary_path = NULL;
616 const char *probe_name = NULL;
617 const char *provider_name = NULL;
fe489250 618 struct lttng_userspace_probe_location_tracepoint *tracepoint_location;
f4d0bb2e
FD
619
620 assert(location);
621 assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT);
fe489250
JG
622 tracepoint_location = container_of(
623 location, typeof(*tracepoint_location), parent);
f4d0bb2e 624
fe489250 625 /* Get probe location fields */
cc831309 626 binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path(location);
f4d0bb2e 627 if (!binary_path) {
cc831309 628 ERR("Userspace probe binary path is NULL");
f4d0bb2e
FD
629 goto error;
630 }
631
cc831309 632 probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name(location);
f4d0bb2e 633 if (!probe_name) {
cc831309 634 ERR("Userspace probe probe name is NULL");
f4d0bb2e
FD
635 goto error;
636 }
637
cc831309 638 provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name(location);
f4d0bb2e 639 if (!provider_name) {
cc831309 640 ERR("Userspace probe provider name is NULL");
f4d0bb2e
FD
641 goto error;
642 }
643
f4d0bb2e
FD
644 /*
645 * Duplicate probe location method fields
646 */
647 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(
648 location->lookup_method);
649 switch (lookup_type) {
650 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
651 lookup_method =
652 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_copy(
653 location->lookup_method);
654 if (!lookup_method) {
fe489250 655 goto error;
f4d0bb2e
FD
656 }
657 break;
658 default:
659 /* Invalid probe location lookup method. */
fe489250 660 goto error;
f4d0bb2e
FD
661 }
662
663 /* Create the probe_location */
664 new_location = lttng_userspace_probe_location_tracepoint_create_no_check(
cc831309 665 binary_path, provider_name, probe_name, lookup_method, false);
f4d0bb2e
FD
666 if (!new_location) {
667 goto destroy_lookup_method;
668 }
669
670 /* Set the duplicated fd to the new probe_location */
2cde0510
JG
671 if (lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(new_location,
672 tracepoint_location->binary_fd_handle) < 0) {
f4d0bb2e
FD
673 goto destroy_probe_location;
674 }
675
676 goto end;
677
678destroy_probe_location:
679 lttng_userspace_probe_location_destroy(new_location);
680destroy_lookup_method:
681 lttng_userspace_probe_location_lookup_method_destroy(lookup_method);
f4d0bb2e 682error:
f4d0bb2e
FD
683 new_location = NULL;
684end:
685 return new_location;
686}
687
1ce46cfe
JG
688const char *lttng_userspace_probe_location_function_get_binary_path(
689 const struct lttng_userspace_probe_location *location)
690{
691 const char *ret = NULL;
692 struct lttng_userspace_probe_location_function *function_location;
693
694 if (!location || lttng_userspace_probe_location_get_type(location) !=
695 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) {
f04a8200 696 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
1ce46cfe
JG
697 goto end;
698 }
699
700 function_location = container_of(location,
701 struct lttng_userspace_probe_location_function,
702 parent);
703 ret = function_location->binary_path;
704end:
705 return ret;
706}
707
f4d0bb2e
FD
708const char *lttng_userspace_probe_location_tracepoint_get_binary_path(
709 const struct lttng_userspace_probe_location *location)
710{
711 const char *ret = NULL;
712 struct lttng_userspace_probe_location_tracepoint *tracepoint_location;
713
714 if (!location || lttng_userspace_probe_location_get_type(location) !=
715 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) {
f04a8200 716 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
f4d0bb2e
FD
717 goto end;
718 }
719
720 tracepoint_location = container_of(location,
721 struct lttng_userspace_probe_location_tracepoint,
722 parent);
723 ret = tracepoint_location->binary_path;
724end:
725 return ret;
726}
727
1ce46cfe
JG
728const char *lttng_userspace_probe_location_function_get_function_name(
729 const struct lttng_userspace_probe_location *location)
730{
731 const char *ret = NULL;
732 struct lttng_userspace_probe_location_function *function_location;
733
734 if (!location || lttng_userspace_probe_location_get_type(location) !=
735 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) {
f04a8200 736 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
1ce46cfe
JG
737 goto end;
738 }
739
740 function_location = container_of(location,
741 struct lttng_userspace_probe_location_function, parent);
742 ret = function_location->function_name;
743end:
744 return ret;
745}
746
f4d0bb2e
FD
747const char *lttng_userspace_probe_location_tracepoint_get_probe_name(
748 const struct lttng_userspace_probe_location *location)
749{
750 const char *ret = NULL;
751 struct lttng_userspace_probe_location_tracepoint *tracepoint_location;
752
753 if (!location || lttng_userspace_probe_location_get_type(location) !=
754 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) {
f04a8200 755 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
f4d0bb2e
FD
756 goto end;
757 }
758
759 tracepoint_location = container_of(location,
760 struct lttng_userspace_probe_location_tracepoint, parent);
761 ret = tracepoint_location->probe_name;
762end:
763 return ret;
764}
765
766const char *lttng_userspace_probe_location_tracepoint_get_provider_name(
767 const struct lttng_userspace_probe_location *location)
768{
769 const char *ret = NULL;
770 struct lttng_userspace_probe_location_tracepoint *tracepoint_location;
771
772 if (!location || lttng_userspace_probe_location_get_type(location) !=
773 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) {
f04a8200 774 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
f4d0bb2e
FD
775 goto end;
776 }
777
778 tracepoint_location = container_of(location,
779 struct lttng_userspace_probe_location_tracepoint, parent);
780 ret = tracepoint_location->provider_name;
781end:
782 return ret;
783}
784
1ce46cfe
JG
785int lttng_userspace_probe_location_function_get_binary_fd(
786 const struct lttng_userspace_probe_location *location)
787{
788 int ret = -1;
789 struct lttng_userspace_probe_location_function *function_location;
790
791 if (!location || lttng_userspace_probe_location_get_type(location) !=
792 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) {
f04a8200 793 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
1ce46cfe
JG
794 goto end;
795 }
796
797 function_location = container_of(location,
798 struct lttng_userspace_probe_location_function, parent);
2cde0510
JG
799 ret = function_location->binary_fd_handle ?
800 fd_handle_get_fd(function_location->binary_fd_handle) : -1;
1ce46cfe
JG
801end:
802 return ret;
803}
804
9d3981b5
JG
805enum lttng_userspace_probe_location_function_instrumentation_type
806lttng_userspace_probe_location_function_get_instrumentation_type(
807 const struct lttng_userspace_probe_location *location)
808{
809 enum lttng_userspace_probe_location_function_instrumentation_type type;
810 struct lttng_userspace_probe_location_function *function_location;
811
812 if (!location || lttng_userspace_probe_location_get_type(location) !=
813 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) {
f04a8200 814 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
9d3981b5
JG
815 type = LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN;
816 goto end;
817 }
818
819 function_location = container_of(location,
820 struct lttng_userspace_probe_location_function, parent);
821 type = function_location->instrumentation_type;
822end:
823 return type;
824}
825
826enum lttng_userspace_probe_location_status
827lttng_userspace_probe_location_function_set_instrumentation_type(
828 const struct lttng_userspace_probe_location *location,
829 enum lttng_userspace_probe_location_function_instrumentation_type instrumentation_type)
830{
831 enum lttng_userspace_probe_location_status status =
832 LTTNG_USERSPACE_PROBE_LOCATION_STATUS_OK;
833 struct lttng_userspace_probe_location_function *function_location;
834
835 if (!location || lttng_userspace_probe_location_get_type(location) !=
836 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION ||
837 instrumentation_type !=
838 LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY) {
f04a8200 839 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
9d3981b5
JG
840 status = LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID;
841 goto end;
842 }
843
844 function_location = container_of(location,
845 struct lttng_userspace_probe_location_function, parent);
846 function_location->instrumentation_type = instrumentation_type;
847end:
848 return status;
849}
850
f4d0bb2e
FD
851int lttng_userspace_probe_location_tracepoint_get_binary_fd(
852 const struct lttng_userspace_probe_location *location)
853{
854 int ret = -1;
855 struct lttng_userspace_probe_location_tracepoint *tracepoint_location;
856
857 if (!location || lttng_userspace_probe_location_get_type(location) !=
858 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) {
f04a8200 859 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
f4d0bb2e
FD
860 goto end;
861 }
862
863 tracepoint_location = container_of(location,
864 struct lttng_userspace_probe_location_tracepoint, parent);
2cde0510
JG
865 ret = tracepoint_location->binary_fd_handle ?
866 fd_handle_get_fd(tracepoint_location->binary_fd_handle) : -1;
f4d0bb2e
FD
867end:
868 return ret;
869}
870
1ce46cfe
JG
871static struct lttng_userspace_probe_location_lookup_method *
872lttng_userspace_probe_location_function_get_lookup_method(
873 const struct lttng_userspace_probe_location *location)
874{
875 struct lttng_userspace_probe_location_lookup_method *ret = NULL;
876
877 if (!location || lttng_userspace_probe_location_get_type(location) !=
878 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) {
f04a8200 879 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
1ce46cfe
JG
880 goto end;
881 }
882
883 ret = location->lookup_method;
884end:
885 return ret;
886}
887
f4d0bb2e
FD
888static struct lttng_userspace_probe_location_lookup_method *
889lttng_userspace_probe_location_tracepoint_get_lookup_method(
890 const struct lttng_userspace_probe_location *location)
891{
892 struct lttng_userspace_probe_location_lookup_method *ret = NULL;
893
894 if (!location || lttng_userspace_probe_location_get_type(location) !=
895 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) {
f04a8200 896 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
f4d0bb2e
FD
897 goto end;
898 }
899
900 ret = location->lookup_method;
901end:
902 return ret;
903}
904
87597c2c 905const struct lttng_userspace_probe_location_lookup_method *
1ce46cfe
JG
906lttng_userspace_probe_location_get_lookup_method(
907 const struct lttng_userspace_probe_location *location)
908{
909 struct lttng_userspace_probe_location_lookup_method *ret = NULL;
910
911 assert(location);
912 switch (location->type) {
913 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
914 ret = lttng_userspace_probe_location_function_get_lookup_method(
915 location);
916 break;
f4d0bb2e
FD
917 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
918 ret = lttng_userspace_probe_location_tracepoint_get_lookup_method(
919 location);
920 break;
1ce46cfe
JG
921 default:
922 ERR("Unknowned lookup method.");
923 break;
924 }
925 return ret;
926}
927
928static
929int lttng_userspace_probe_location_lookup_method_serialize(
930 struct lttng_userspace_probe_location_lookup_method *method,
e368fb43 931 struct lttng_payload *payload)
1ce46cfe
JG
932{
933 int ret;
934 struct lttng_userspace_probe_location_lookup_method_comm
935 lookup_method_comm;
936
937 lookup_method_comm.type = (int8_t) (method ? method->type :
938 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT);
e368fb43
JG
939 if (payload) {
940 ret = lttng_dynamic_buffer_append(&payload->buffer, &lookup_method_comm,
1ce46cfe
JG
941 sizeof(lookup_method_comm));
942 if (ret) {
943 goto end;
944 }
945 }
f4d0bb2e
FD
946 ret = sizeof(lookup_method_comm);
947end:
948 return ret;
949}
950
951static
952int lttng_userspace_probe_location_function_serialize(
953 const struct lttng_userspace_probe_location *location,
e368fb43 954 struct lttng_payload *payload)
f4d0bb2e
FD
955{
956 int ret;
957 size_t function_name_len, binary_path_len;
958 struct lttng_userspace_probe_location_function *location_function;
959 struct lttng_userspace_probe_location_function_comm location_function_comm;
960
961 assert(location);
962 assert(lttng_userspace_probe_location_get_type(location) ==
963 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION);
964
965 location_function = container_of(location,
966 struct lttng_userspace_probe_location_function,
967 parent);
968 if (!location_function->function_name || !location_function->binary_path) {
969 ret = -LTTNG_ERR_INVALID;
970 goto end;
971 }
972
2cde0510 973 if (payload && !location_function->binary_fd_handle) {
f4d0bb2e
FD
974 ret = -LTTNG_ERR_INVALID;
975 goto end;
976 }
977
f4d0bb2e
FD
978 function_name_len = strlen(location_function->function_name);
979 if (function_name_len == 0) {
980 ret = -LTTNG_ERR_INVALID;
981 goto end;
982 }
983 binary_path_len = strlen(location_function->binary_path);
984 if (binary_path_len == 0) {
985 ret = -LTTNG_ERR_INVALID;
986 goto end;
987 }
988
989 location_function_comm.function_name_len = function_name_len + 1;
990 location_function_comm.binary_path_len = binary_path_len + 1;
991
e368fb43
JG
992 if (payload) {
993 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
994 &location_function_comm,
995 sizeof(location_function_comm));
996 if (ret) {
997 ret = -LTTNG_ERR_INVALID;
998 goto end;
999 }
e368fb43 1000 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
1001 location_function->function_name,
1002 location_function_comm.function_name_len);
1003 if (ret) {
1004 ret = -LTTNG_ERR_INVALID;
1005 goto end;
1006 }
e368fb43 1007 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
1008 location_function->binary_path,
1009 location_function_comm.binary_path_len);
1010 if (ret) {
1011 ret = -LTTNG_ERR_INVALID;
1012 goto end;
1013 }
fe489250 1014 ret = lttng_payload_push_fd_handle(
2cde0510 1015 payload, location_function->binary_fd_handle);
e368fb43
JG
1016 if (ret) {
1017 ret = -LTTNG_ERR_INVALID;
1018 goto end;
1019 }
f4d0bb2e
FD
1020 }
1021 ret = sizeof(location_function_comm) +
1022 location_function_comm.function_name_len +
1023 location_function_comm.binary_path_len;
1ce46cfe
JG
1024end:
1025 return ret;
1026}
1027
1028static
f4d0bb2e 1029int lttng_userspace_probe_location_tracepoint_serialize(
1ce46cfe 1030 const struct lttng_userspace_probe_location *location,
e368fb43 1031 struct lttng_payload *payload)
1ce46cfe
JG
1032{
1033 int ret;
f4d0bb2e
FD
1034 size_t probe_name_len, provider_name_len, binary_path_len;
1035 struct lttng_userspace_probe_location_tracepoint *location_tracepoint;
1036 struct lttng_userspace_probe_location_tracepoint_comm location_tracepoint_comm;
1ce46cfe
JG
1037
1038 assert(location);
1039 assert(lttng_userspace_probe_location_get_type(location) ==
f4d0bb2e 1040 LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT);
1ce46cfe 1041
f4d0bb2e
FD
1042 location_tracepoint = container_of(location,
1043 struct lttng_userspace_probe_location_tracepoint,
1ce46cfe 1044 parent);
f4d0bb2e
FD
1045 if (!location_tracepoint->probe_name ||
1046 !location_tracepoint->provider_name ||
1047 !location_tracepoint->binary_path) {
1ce46cfe
JG
1048 ret = -LTTNG_ERR_INVALID;
1049 goto end;
1050 }
1051
2cde0510 1052 if (payload && !location_tracepoint->binary_fd_handle) {
1ce46cfe
JG
1053 ret = -LTTNG_ERR_INVALID;
1054 goto end;
1055 }
1056
f4d0bb2e
FD
1057 probe_name_len = strlen(location_tracepoint->probe_name);
1058 if (probe_name_len == 0) {
1ce46cfe
JG
1059 ret = -LTTNG_ERR_INVALID;
1060 goto end;
1061 }
f4d0bb2e
FD
1062
1063 provider_name_len = strlen(location_tracepoint->provider_name);
1064 if (provider_name_len == 0) {
1065 ret = -LTTNG_ERR_INVALID;
1066 goto end;
1067 }
1068
1069 binary_path_len = strlen(location_tracepoint->binary_path);
1ce46cfe
JG
1070 if (binary_path_len == 0) {
1071 ret = -LTTNG_ERR_INVALID;
1072 goto end;
1073 }
1074
f4d0bb2e
FD
1075 location_tracepoint_comm.probe_name_len = probe_name_len + 1;
1076 location_tracepoint_comm.provider_name_len = provider_name_len + 1;
1077 location_tracepoint_comm.binary_path_len = binary_path_len + 1;
1ce46cfe 1078
e368fb43
JG
1079 if (payload) {
1080 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
1081 &location_tracepoint_comm,
1082 sizeof(location_tracepoint_comm));
1ce46cfe
JG
1083 if (ret) {
1084 ret = -LTTNG_ERR_INVALID;
1085 goto end;
1086 }
e368fb43 1087 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
1088 location_tracepoint->probe_name,
1089 location_tracepoint_comm.probe_name_len);
1ce46cfe
JG
1090 if (ret) {
1091 ret = -LTTNG_ERR_INVALID;
1092 goto end;
1093 }
e368fb43 1094 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
1095 location_tracepoint->provider_name,
1096 location_tracepoint_comm.provider_name_len);
1097 if (ret) {
1098 ret = -LTTNG_ERR_INVALID;
1099 goto end;
1100 }
e368fb43 1101 ret = lttng_dynamic_buffer_append(&payload->buffer,
f4d0bb2e
FD
1102 location_tracepoint->binary_path,
1103 location_tracepoint_comm.binary_path_len);
1ce46cfe
JG
1104 if (ret) {
1105 ret = -LTTNG_ERR_INVALID;
1106 goto end;
1107 }
fe489250 1108 ret = lttng_payload_push_fd_handle(
2cde0510 1109 payload, location_tracepoint->binary_fd_handle);
e368fb43
JG
1110 if (ret) {
1111 ret = -LTTNG_ERR_INVALID;
1112 goto end;
1113 }
1ce46cfe 1114 }
e368fb43 1115
f4d0bb2e
FD
1116 ret = sizeof(location_tracepoint_comm) +
1117 location_tracepoint_comm.probe_name_len +
1118 location_tracepoint_comm.provider_name_len +
1119 location_tracepoint_comm.binary_path_len;
1ce46cfe
JG
1120end:
1121 return ret;
1122}
1123
1124LTTNG_HIDDEN
1125int lttng_userspace_probe_location_serialize(
1126 const struct lttng_userspace_probe_location *location,
e368fb43 1127 struct lttng_payload *payload)
1ce46cfe
JG
1128{
1129 int ret, buffer_use = 0;
1130 struct lttng_userspace_probe_location_comm location_generic_comm;
1131
1132 if (!location) {
f04a8200 1133 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
1ce46cfe
JG
1134 ret = -LTTNG_ERR_INVALID;
1135 goto end;
1136 }
1137
56f0bc67
JG
1138 memset(&location_generic_comm, 0, sizeof(location_generic_comm));
1139
1ce46cfe 1140 location_generic_comm.type = (int8_t) location->type;
e368fb43
JG
1141 if (payload) {
1142 ret = lttng_dynamic_buffer_append(&payload->buffer,
1143 &location_generic_comm,
1ce46cfe
JG
1144 sizeof(location_generic_comm));
1145 if (ret) {
1146 goto end;
1147 }
1148 }
1149 buffer_use += sizeof(location_generic_comm);
1150
1151 switch (lttng_userspace_probe_location_get_type(location)) {
1152 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
1153 ret = lttng_userspace_probe_location_function_serialize(
e368fb43 1154 location, payload);
1ce46cfe 1155 break;
f4d0bb2e
FD
1156 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
1157 ret = lttng_userspace_probe_location_tracepoint_serialize(
e368fb43 1158 location, payload);
f4d0bb2e 1159 break;
1ce46cfe
JG
1160 default:
1161 ERR("Unsupported probe location type");
1162 ret = -LTTNG_ERR_INVALID;
1163 goto end;
1164 }
1165 if (ret < 0) {
1166 goto end;
1167 }
1168 buffer_use += ret;
1169
1170 ret = lttng_userspace_probe_location_lookup_method_serialize(
e368fb43 1171 location->lookup_method, payload);
1ce46cfe
JG
1172 if (ret < 0) {
1173 goto end;
1174 }
1175 ret += buffer_use;
1176end:
1177 return ret;
1178}
1179
1180static
e368fb43
JG
1181int lttng_userspace_probe_location_function_create_from_payload(
1182 struct lttng_payload_view *view,
1ce46cfe
JG
1183 struct lttng_userspace_probe_location **location)
1184{
1185 struct lttng_userspace_probe_location_function_comm *location_function_comm;
1186 const char *function_name_src, *binary_path_src;
1187 char *function_name = NULL, *binary_path = NULL;
1188 int ret = 0;
e368fb43 1189 size_t expected_size;
2cde0510 1190 struct fd_handle *binary_fd_handle = lttng_payload_view_pop_fd_handle(view);
1ce46cfe 1191
1ce46cfe
JG
1192 assert(location);
1193
e368fb43
JG
1194 if (view->buffer.size < sizeof(*location_function_comm)) {
1195 ret = -LTTNG_ERR_INVALID;
1196 goto end;
1197 }
1198
1ce46cfe 1199 location_function_comm =
e368fb43 1200 (typeof(location_function_comm)) view->buffer.data;
1ce46cfe 1201
e368fb43 1202 expected_size = sizeof(*location_function_comm) +
1ce46cfe
JG
1203 location_function_comm->function_name_len +
1204 location_function_comm->binary_path_len;
1205
e368fb43 1206 if (view->buffer.size < expected_size) {
1ce46cfe
JG
1207 ret = -LTTNG_ERR_INVALID;
1208 goto end;
1209 }
1210
e368fb43 1211 function_name_src = view->buffer.data + sizeof(*location_function_comm);
1ce46cfe
JG
1212 binary_path_src = function_name_src +
1213 location_function_comm->function_name_len;
1214
48c24aea
JG
1215 if (!lttng_buffer_view_contains_string(&view->buffer, function_name_src,
1216 location_function_comm->function_name_len)) {
1ce46cfe
JG
1217 ret = -LTTNG_ERR_INVALID;
1218 goto end;
1219 }
48c24aea
JG
1220
1221 if (!lttng_buffer_view_contains_string(&view->buffer, binary_path_src,
1222 location_function_comm->binary_path_len)) {
1ce46cfe
JG
1223 ret = -LTTNG_ERR_INVALID;
1224 goto end;
1225 }
1226
1227 function_name = lttng_strndup(function_name_src, LTTNG_SYMBOL_NAME_LEN);
1228 if (!function_name) {
1229 PERROR("lttng_strndup");
2aa28610 1230 ret = -LTTNG_ERR_NOMEM;
1ce46cfe
JG
1231 goto end;
1232 }
1233
1234 binary_path = lttng_strndup(binary_path_src, LTTNG_PATH_MAX);
1235 if (!binary_path) {
1236 PERROR("lttng_strndup");
2aa28610 1237 ret = -LTTNG_ERR_NOMEM;
1ce46cfe
JG
1238 goto end;
1239 }
1240
1241 *location = lttng_userspace_probe_location_function_create_no_check(
1242 binary_path, function_name, NULL, false);
1243 if (!(*location)) {
1244 ret = -LTTNG_ERR_INVALID;
1245 goto end;
1246 }
1247
2cde0510
JG
1248 ret = lttng_userspace_probe_location_function_set_binary_fd_handle(
1249 *location, binary_fd_handle);
e368fb43 1250 if (ret) {
e368fb43
JG
1251 ret = -LTTNG_ERR_INVALID;
1252 goto end;
1253 }
1254
1ce46cfe
JG
1255 ret = (int) expected_size;
1256end:
2cde0510 1257 fd_handle_put(binary_fd_handle);
1ce46cfe
JG
1258 free(function_name);
1259 free(binary_path);
1260 return ret;
1261}
1262
f4d0bb2e 1263static
e368fb43
JG
1264int lttng_userspace_probe_location_tracepoint_create_from_payload(
1265 struct lttng_payload_view *view,
f4d0bb2e
FD
1266 struct lttng_userspace_probe_location **location)
1267{
1268 struct lttng_userspace_probe_location_tracepoint_comm *location_tracepoint_comm;
1269 const char *probe_name_src, *provider_name_src, *binary_path_src;
1270 char *probe_name = NULL, *provider_name = NULL, *binary_path = NULL;
1271 int ret = 0;
e368fb43 1272 size_t expected_size;
2cde0510 1273 struct fd_handle *binary_fd_handle = lttng_payload_view_pop_fd_handle(view);
f4d0bb2e 1274
f4d0bb2e
FD
1275 assert(location);
1276
2cde0510 1277 if (!binary_fd_handle) {
e368fb43
JG
1278 ret = -LTTNG_ERR_INVALID;
1279 goto end;
1280 }
1281
1282 if (view->buffer.size < sizeof(*location_tracepoint_comm)) {
1283 ret = -LTTNG_ERR_INVALID;
1284 goto end;
1285 }
1286
f4d0bb2e 1287 location_tracepoint_comm =
e368fb43 1288 (typeof(location_tracepoint_comm)) view->buffer.data;
f4d0bb2e 1289
e368fb43 1290 expected_size = sizeof(*location_tracepoint_comm) +
f4d0bb2e
FD
1291 location_tracepoint_comm->probe_name_len +
1292 location_tracepoint_comm->provider_name_len +
1293 location_tracepoint_comm->binary_path_len;
1294
e368fb43 1295 if (view->buffer.size < expected_size) {
f4d0bb2e
FD
1296 ret = -LTTNG_ERR_INVALID;
1297 goto end;
1298 }
1299
e368fb43 1300 probe_name_src = view->buffer.data + sizeof(*location_tracepoint_comm);
f4d0bb2e
FD
1301 provider_name_src = probe_name_src +
1302 location_tracepoint_comm->probe_name_len;
1303 binary_path_src = provider_name_src +
1304 location_tracepoint_comm->provider_name_len;
1305
48c24aea
JG
1306 if (!lttng_buffer_view_contains_string(&view->buffer, probe_name_src,
1307 location_tracepoint_comm->probe_name_len)) {
f4d0bb2e
FD
1308 ret = -LTTNG_ERR_INVALID;
1309 goto end;
1310 }
1311
48c24aea
JG
1312 if (!lttng_buffer_view_contains_string(&view->buffer, provider_name_src,
1313 location_tracepoint_comm->provider_name_len)) {
f4d0bb2e
FD
1314 ret = -LTTNG_ERR_INVALID;
1315 goto end;
1316 }
1317
48c24aea
JG
1318 if (!lttng_buffer_view_contains_string(&view->buffer, binary_path_src,
1319 location_tracepoint_comm->binary_path_len)) {
f4d0bb2e
FD
1320 ret = -LTTNG_ERR_INVALID;
1321 goto end;
1322 }
1323
1324 probe_name = lttng_strndup(probe_name_src, LTTNG_SYMBOL_NAME_LEN);
1325 if (!probe_name) {
1326 PERROR("lttng_strndup");
1327 goto end;
1328 }
1329 provider_name = lttng_strndup(provider_name_src, LTTNG_SYMBOL_NAME_LEN);
1330 if (!provider_name) {
1331 PERROR("lttng_strndup");
1332 goto end;
1333 }
1334
1335 binary_path = lttng_strndup(binary_path_src, LTTNG_SYMBOL_NAME_LEN);
1336 if (!binary_path) {
1337 PERROR("lttng_strndup");
1338 goto end;
1339 }
1340
1341 *location = lttng_userspace_probe_location_tracepoint_create_no_check(
1342 binary_path, provider_name, probe_name, NULL, false);
1343 if (!(*location)) {
1344 ret = -LTTNG_ERR_INVALID;
1345 goto end;
1346 }
1347
2cde0510
JG
1348 ret = lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
1349 *location, binary_fd_handle);
e368fb43 1350 if (ret) {
e368fb43
JG
1351 ret = -LTTNG_ERR_INVALID;
1352 goto end;
1353 }
1354
f4d0bb2e
FD
1355 ret = (int) expected_size;
1356end:
2cde0510 1357 fd_handle_put(binary_fd_handle);
f4d0bb2e
FD
1358 free(probe_name);
1359 free(provider_name);
1360 free(binary_path);
1361 return ret;
1362}
1363
1ce46cfe 1364static
e368fb43
JG
1365int lttng_userspace_probe_location_lookup_method_create_from_payload(
1366 struct lttng_payload_view *view,
1ce46cfe
JG
1367 struct lttng_userspace_probe_location_lookup_method **lookup_method)
1368{
1369 int ret;
1370 struct lttng_userspace_probe_location_lookup_method_comm *lookup_comm;
1371 enum lttng_userspace_probe_location_lookup_method_type type;
1372
e368fb43 1373 assert(view);
1ce46cfe
JG
1374 assert(lookup_method);
1375
e368fb43 1376 if (view->buffer.size < sizeof(*lookup_comm)) {
1ce46cfe
JG
1377 ret = -LTTNG_ERR_INVALID;
1378 goto end;
1379 }
1380
e368fb43 1381 lookup_comm = (typeof(lookup_comm)) view->buffer.data;
1ce46cfe
JG
1382 type = (enum lttng_userspace_probe_location_lookup_method_type)
1383 lookup_comm->type;
1384 switch (type) {
1385 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT:
1386 *lookup_method = NULL;
1387 break;
1388 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
1389 *lookup_method =
1390 lttng_userspace_probe_location_lookup_method_function_elf_create();
1391 if (!(*lookup_method)) {
1392 ret = -LTTNG_ERR_INVALID;
1393 goto end;
1394 }
1395 break;
f4d0bb2e
FD
1396 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
1397 *lookup_method =
1398 lttng_userspace_probe_location_lookup_method_tracepoint_sdt_create();
1399 if (!(*lookup_method)) {
1400 ret = -LTTNG_ERR_INVALID;
1401 goto end;
1402 }
1403 break;
1ce46cfe
JG
1404 default:
1405 ret = -LTTNG_ERR_INVALID;
1406 goto end;
1407 }
1408
1409 ret = sizeof(*lookup_comm);
1410end:
1411 return ret;
1412}
1413
1414LTTNG_HIDDEN
e368fb43
JG
1415int lttng_userspace_probe_location_create_from_payload(
1416 struct lttng_payload_view *view,
1ce46cfe
JG
1417 struct lttng_userspace_probe_location **location)
1418{
1419 struct lttng_userspace_probe_location_lookup_method *lookup_method;
1420 struct lttng_userspace_probe_location_comm *probe_location_comm;
1421 enum lttng_userspace_probe_location_type type;
1ce46cfe
JG
1422 int consumed = 0;
1423 int ret;
1424
e368fb43 1425 assert(view);
1ce46cfe
JG
1426 assert(location);
1427
1428 lookup_method = NULL;
1429
e368fb43 1430 if (view->buffer.size <= sizeof(*probe_location_comm)) {
1ce46cfe
JG
1431 ret = -LTTNG_ERR_INVALID;
1432 goto end;
1433 }
1434
e368fb43 1435 probe_location_comm = (typeof(probe_location_comm)) view->buffer.data;
1ce46cfe
JG
1436 type = (enum lttng_userspace_probe_location_type) probe_location_comm->type;
1437 consumed += sizeof(*probe_location_comm);
1438
1439 switch (type) {
1440 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
1441 {
e368fb43
JG
1442 struct lttng_payload_view location_view =
1443 lttng_payload_view_from_view(
1444 view, consumed, -1);
1ce46cfe 1445
e368fb43
JG
1446 ret = lttng_userspace_probe_location_function_create_from_payload(
1447 &location_view, location);
1ce46cfe
JG
1448 if (ret < 0) {
1449 goto end;
1450 }
1451 break;
1452 }
f4d0bb2e
FD
1453 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
1454 {
e368fb43
JG
1455 struct lttng_payload_view location_view =
1456 lttng_payload_view_from_view(view, consumed, -1);
f4d0bb2e 1457
e368fb43
JG
1458 ret = lttng_userspace_probe_location_tracepoint_create_from_payload(
1459 &location_view, location);
f4d0bb2e
FD
1460 if (ret < 0) {
1461 goto end;
1462 }
1463 break;
1464 }
1ce46cfe
JG
1465 default:
1466 ret = -LTTNG_ERR_INVALID;
1467 goto end;
1468 }
1469
1470 consumed += ret;
e368fb43 1471 if (view->buffer.size <= consumed) {
1ce46cfe
JG
1472 ret = -LTTNG_ERR_INVALID;
1473 goto end;
1474 }
1475
e368fb43
JG
1476 {
1477 struct lttng_payload_view lookup_method_view =
1478 lttng_payload_view_from_view(
1479 view, consumed, -1);
1480
1481 ret = lttng_userspace_probe_location_lookup_method_create_from_payload(
1482 &lookup_method_view, &lookup_method);
1483 }
1ce46cfe
JG
1484 if (ret < 0) {
1485 ret = -LTTNG_ERR_INVALID;
1486 goto end;
1487 }
1488
1489 assert(lookup_method);
1490 (*location)->lookup_method = lookup_method;
1491 lookup_method = NULL;
1492 ret += consumed;
1493end:
1494 return ret;
1495}
1496
fe489250 1497static
2cde0510 1498int lttng_userspace_probe_location_function_set_binary_fd_handle(
fe489250
JG
1499 struct lttng_userspace_probe_location *location,
1500 struct fd_handle *binary_fd)
1ce46cfe
JG
1501{
1502 int ret = 0;
1503 struct lttng_userspace_probe_location_function *function_location;
1504
1505 assert(location);
1506 assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION);
1507
1508 function_location = container_of(location,
1509 struct lttng_userspace_probe_location_function, parent);
2cde0510 1510 fd_handle_put(function_location->binary_fd_handle);
fe489250 1511 fd_handle_get(binary_fd);
2cde0510 1512 function_location->binary_fd_handle = binary_fd;
1ce46cfe
JG
1513 return ret;
1514}
1515
fe489250 1516static
2cde0510 1517int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(
fe489250
JG
1518 struct lttng_userspace_probe_location *location,
1519 struct fd_handle *binary_fd)
f4d0bb2e
FD
1520{
1521 int ret = 0;
1522 struct lttng_userspace_probe_location_tracepoint *tracepoint_location;
1523
1524 assert(location);
1525 assert(location->type == LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT);
1526
1527 tracepoint_location = container_of(location,
1528 struct lttng_userspace_probe_location_tracepoint, parent);
2cde0510 1529 fd_handle_put(tracepoint_location->binary_fd_handle);
fe489250 1530 fd_handle_get(binary_fd);
2cde0510 1531 tracepoint_location->binary_fd_handle = binary_fd;
f4d0bb2e
FD
1532 return ret;
1533}
1534
1ce46cfe
JG
1535static
1536int lttng_userspace_probe_location_function_flatten(
1537 const struct lttng_userspace_probe_location *location,
1538 struct lttng_dynamic_buffer *buffer)
1539{
1540 struct lttng_userspace_probe_location_lookup_method_elf flat_lookup_method;
1541 struct lttng_userspace_probe_location_function *probe_function;
1542 struct lttng_userspace_probe_location_function flat_probe;
1543 size_t function_name_len, binary_path_len;
1544 size_t padding_needed = 0;
1545 char *flat_probe_start;
1546 int storage_needed = 0;
1547 int ret;
1548
1549 assert(location);
1550
1551 if (location->lookup_method && location->lookup_method->type !=
1552 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF) {
1553 ret = -LTTNG_ERR_INVALID;
1554 goto end;
1555 }
1556
1557 probe_function = container_of(location,
1558 struct lttng_userspace_probe_location_function,
1559 parent);
1560 assert(probe_function->function_name);
1561 assert(probe_function->binary_path);
1562
1563 storage_needed +=
1564 sizeof(struct lttng_userspace_probe_location_function);
1565 function_name_len = strlen(probe_function->function_name) + 1;
1566 binary_path_len = strlen(probe_function->binary_path) + 1;
1567 storage_needed += function_name_len + binary_path_len;
1568
1569 /*
1570 * The lookup method is aligned to 64-bit within the buffer.
1571 * This is needed even if there is no lookup method since
1572 * the next structure in the buffer probably needs to be
1573 * aligned too (depending on the arch).
1574 */
1575 padding_needed = ALIGN_TO(storage_needed, sizeof(uint64_t)) - storage_needed;
1576 storage_needed += padding_needed;
1577
1578 if (location->lookup_method) {
1579 /* NOTE: elf look-up method is assumed here. */
1580 storage_needed += sizeof(struct lttng_userspace_probe_location_lookup_method_elf);
1581 }
1582
1583 if (!buffer) {
1584 ret = storage_needed;
1585 goto end;
1586 }
1587
1588 if (lttng_dynamic_buffer_get_capacity_left(buffer) < storage_needed) {
1589 ret = lttng_dynamic_buffer_set_capacity(buffer,
1590 buffer->size + storage_needed);
1591 if (ret) {
1592 goto end;
1593 }
1594 }
1595
1596 memset(&flat_probe, 0, sizeof(flat_probe));
1597
1598 flat_probe_start = buffer->data + buffer->size;
1599 flat_probe.parent.type = location->type;
1600 /*
1601 * The lookup method, if present, is the last element in the flat
1602 * representation of the probe.
1603 */
1604 if (location->lookup_method) {
1605 flat_probe.parent.lookup_method =
1606 (struct lttng_userspace_probe_location_lookup_method *)
1607 (flat_probe_start + sizeof(flat_probe) +
1608 function_name_len + binary_path_len + padding_needed);
1609 } else {
1610 flat_probe.parent.lookup_method = NULL;
1611 }
1612
1613 flat_probe.function_name = flat_probe_start + sizeof(flat_probe);
1614 flat_probe.binary_path = flat_probe.function_name + function_name_len;
2cde0510 1615 flat_probe.binary_fd_handle = NULL;
1ce46cfe
JG
1616 ret = lttng_dynamic_buffer_append(buffer, &flat_probe,
1617 sizeof(flat_probe));
1618 if (ret) {
1619 goto end;
1620 }
1621
1622 ret = lttng_dynamic_buffer_append(buffer,
1623 probe_function->function_name, function_name_len);
1624 if (ret) {
1625 goto end;
1626 }
1627 ret = lttng_dynamic_buffer_append(buffer,
1628 probe_function->binary_path, binary_path_len);
1629 if (ret) {
1630 goto end;
1631 }
1632
1633 /* Insert padding before the lookup method. */
1634 ret = lttng_dynamic_buffer_set_size(buffer,
1635 buffer->size + padding_needed);
1636 if (ret) {
1637 goto end;
1638 }
1639
1640 if (!location->lookup_method) {
1641 /* Not an error, the default method is used. */
1642 ret = storage_needed;
1643 goto end;
1644 }
1645
1646 memset(&flat_lookup_method, 0, sizeof(flat_lookup_method));
1647 flat_lookup_method.parent.type =
1648 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF;
1649 ret = lttng_dynamic_buffer_append(buffer,
1650 &flat_lookup_method, sizeof(flat_lookup_method));
1651 if (ret) {
1652 goto end;
1653 }
1654 ret = storage_needed;
1655end:
1656 return ret;
1657}
1658
f4d0bb2e
FD
1659static
1660int lttng_userspace_probe_location_tracepoint_flatten(
1661 const struct lttng_userspace_probe_location *location,
1662 struct lttng_dynamic_buffer *buffer)
1663{
1664 struct lttng_userspace_probe_location_lookup_method_sdt flat_lookup_method;
1665 struct lttng_userspace_probe_location_tracepoint *probe_tracepoint;
1666 struct lttng_userspace_probe_location_tracepoint flat_probe;
1667 size_t probe_name_len, provider_name_len, binary_path_len;
1668 size_t padding_needed = 0;
1669 int storage_needed = 0;
1670 char *flat_probe_start;
1671 int ret = 0;
1672
1673 assert(location);
1674
1675 /* Only SDT tracepoints are supported at the moment */
1676 if (location->lookup_method && location->lookup_method->type !=
1677 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT) {
1678 ret = -LTTNG_ERR_INVALID;
1679 goto end;
1680 }
1681 probe_tracepoint = container_of(location,
1682 struct lttng_userspace_probe_location_tracepoint,
1683 parent);
1684 assert(probe_tracepoint->probe_name);
1685 assert(probe_tracepoint->provider_name);
1686 assert(probe_tracepoint->binary_path);
1687
1688 /* Compute the storage space needed to flatten the probe location */
1689 storage_needed += sizeof(struct lttng_userspace_probe_location_tracepoint);
1690
1691 probe_name_len = strlen(probe_tracepoint->probe_name) + 1;
1692 provider_name_len = strlen(probe_tracepoint->provider_name) + 1;
1693 binary_path_len = strlen(probe_tracepoint->binary_path) + 1;
1694
1695 storage_needed += probe_name_len + provider_name_len + binary_path_len;
1696
1697 /*
1698 * The lookup method is aligned to 64-bit within the buffer.
1699 * This is needed even if there is no lookup method since
1700 * the next structure in the buffer probably needs to be
1701 * aligned too (depending on the arch).
1702 */
1703 padding_needed = ALIGN_TO(storage_needed, sizeof(uint64_t)) - storage_needed;
1704 storage_needed += padding_needed;
1705
1706 if (location->lookup_method) {
1707 /* NOTE: elf look-up method is assumed here. */
1708 storage_needed +=
1709 sizeof(struct lttng_userspace_probe_location_lookup_method_elf);
1710 }
1711
1712 /*
1713 * If the caller set buffer to NULL, return the size of the needed buffer.
1714 */
1715 if (!buffer) {
1716 ret = storage_needed;
1717 goto end;
1718 }
1719
1720 if (lttng_dynamic_buffer_get_capacity_left(buffer) < storage_needed) {
1721 ret = lttng_dynamic_buffer_set_capacity(buffer,
1722 buffer->size + storage_needed);
1723 if (ret) {
1724 goto end;
1725 }
1726 }
1727
1728 memset(&flat_probe, 0, sizeof(flat_probe));
1729
1730 flat_probe_start = buffer->data + buffer->size;
1731 flat_probe.parent.type = location->type;
1732
1733 /*
1734 * The lookup method, if present, is the last element in the flat
1735 * representation of the probe.
1736 */
1737 if (location->lookup_method) {
1738 flat_probe.parent.lookup_method =
1739 (struct lttng_userspace_probe_location_lookup_method *)
1740 (flat_probe_start + sizeof(flat_probe) +
1741 probe_name_len + provider_name_len +
1742 binary_path_len + padding_needed);
1743 } else {
1744 flat_probe.parent.lookup_method = NULL;
1745 }
1746
1747 flat_probe.probe_name = flat_probe_start + sizeof(flat_probe);
1748 flat_probe.provider_name = flat_probe.probe_name + probe_name_len;
1749 flat_probe.binary_path = flat_probe.provider_name + provider_name_len;
2cde0510 1750 flat_probe.binary_fd_handle = NULL;
f4d0bb2e
FD
1751 ret = lttng_dynamic_buffer_append(buffer, &flat_probe, sizeof(flat_probe));
1752 if (ret) {
1753 goto end;
1754 }
1755
1756 /* Append all the fields to the buffer */
1757 ret = lttng_dynamic_buffer_append(buffer,
1758 probe_tracepoint->probe_name, probe_name_len);
1759 if (ret) {
1760 goto end;
1761 }
1762 ret = lttng_dynamic_buffer_append(buffer,
1763 probe_tracepoint->provider_name, provider_name_len);
1764 if (ret) {
1765 goto end;
1766 }
1767 ret = lttng_dynamic_buffer_append(buffer,
1768 probe_tracepoint->binary_path, binary_path_len);
1769 if (ret) {
1770 goto end;
1771 }
1772
1773 /* Insert padding before the lookup method. */
1774 ret = lttng_dynamic_buffer_set_size(buffer, buffer->size + padding_needed);
1775 if (ret) {
1776 goto end;
1777 }
1778
1779 if (!location->lookup_method) {
1780 /* Not an error, the default method is used. */
1781 ret = storage_needed;
1782 goto end;
1783 }
1784
1785 memset(&flat_lookup_method, 0, sizeof(flat_lookup_method));
1786
1787 flat_lookup_method.parent.type =
1788 LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT;
1789 ret = lttng_dynamic_buffer_append(buffer,
1790 &flat_lookup_method, sizeof(flat_lookup_method));
1791 if (ret) {
1792 goto end;
1793 }
1794 ret = storage_needed;
1795end:
1796 return ret;
1797}
1798
1ce46cfe
JG
1799LTTNG_HIDDEN
1800int lttng_userspace_probe_location_flatten(
1801 const struct lttng_userspace_probe_location *location,
1802 struct lttng_dynamic_buffer *buffer)
1803{
1804 int ret;
1805 if (!location) {
1806 ret = -LTTNG_ERR_INVALID;
1807 goto end;
1808 }
1809
1810 /* Only types currently supported. */
1811 switch (location->type) {
1812 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
1813 ret = lttng_userspace_probe_location_function_flatten(location, buffer);
1814 break;
f4d0bb2e
FD
1815 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
1816 ret = lttng_userspace_probe_location_tracepoint_flatten(location, buffer);
1817 break;
1ce46cfe
JG
1818 default:
1819 ret = -LTTNG_ERR_INVALID;
1820 goto end;
1821 }
1822
1823end:
1824 return ret;
1825}
394357fe
FD
1826
1827LTTNG_HIDDEN
1828struct lttng_userspace_probe_location *lttng_userspace_probe_location_copy(
1829 const struct lttng_userspace_probe_location *location)
1830{
1831 struct lttng_userspace_probe_location *new_location = NULL;
1832 enum lttng_userspace_probe_location_type type;
1833
1834 if (!location) {
1835 goto err;
1836 }
1837
1838 type = lttng_userspace_probe_location_get_type(location);
1839 switch (type) {
1840 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
1841 new_location =
1842 lttng_userspace_probe_location_function_copy(location);
1843 if (!new_location) {
1844 goto err;
1845 }
1846 break;
f4d0bb2e
FD
1847 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
1848 new_location =
1849 lttng_userspace_probe_location_tracepoint_copy(location);
1850 if (!new_location) {
1851 goto err;
1852 }
1853 break;
394357fe
FD
1854 default:
1855 new_location = NULL;
1856 goto err;
1857 }
1858err:
1859 return new_location;
1860}
dfcfa983
JR
1861
1862LTTNG_HIDDEN
1863bool lttng_userspace_probe_location_lookup_method_is_equal(
1864 const struct lttng_userspace_probe_location_lookup_method *a,
1865 const struct lttng_userspace_probe_location_lookup_method *b)
1866{
1867 bool is_equal = false;
1868
1869 if (!a || !b) {
1870 goto end;
1871 }
1872
1873 if (a == b) {
1874 is_equal = true;
1875 goto end;
1876 }
1877
1878 if (a->type != b->type) {
1879 goto end;
1880 }
1881
1882 is_equal = true;
1883end:
1884 return is_equal;
1885}
1886
1887LTTNG_HIDDEN
1888bool lttng_userspace_probe_location_is_equal(
1889 const struct lttng_userspace_probe_location *a,
1890 const struct lttng_userspace_probe_location *b)
1891{
1892 bool is_equal = false;
1893
1894 if (!a || !b) {
1895 goto end;
1896 }
1897
1898 if (a == b) {
1899 is_equal = true;
1900 goto end;
1901 }
1902
1903 if (!lttng_userspace_probe_location_lookup_method_is_equal(
1904 a->lookup_method, b->lookup_method)) {
1905 goto end;
1906 }
1907
1908 if (a->type != b->type) {
1909 goto end;
1910 }
1911
1912 is_equal = a->equal ? a->equal(a, b) : true;
1913end:
1914 return is_equal;
1915}
This page took 0.119764 seconds and 4 git commands to generate.