Build fix: unknown warning -Wduplicated-branches
[lttng-tools.git] / src / common / kernel-probe.cpp
CommitLineData
808cb744
JR
1/*
2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include "lttng/lttng-error.h"
c9e313bc
SM
9#include <common/error.hpp>
10#include <common/hashtable/hashtable.hpp>
11#include <common/hashtable/utils.hpp>
12#include <common/macros.hpp>
13#include <common/mi-lttng.hpp>
14#include <common/payload-view.hpp>
15#include <common/payload.hpp>
808cb744
JR
16#include <fcntl.h>
17#include <lttng/constant.h>
c9e313bc 18#include <lttng/kernel-probe-internal.hpp>
6a751b95 19#include <lttng/kernel-probe.h>
808cb744
JR
20#include <sys/stat.h>
21#include <sys/types.h>
8f14767d 22#include <unistd.h>
808cb744
JR
23
24static
25int lttng_kernel_probe_location_address_serialize(
26 const struct lttng_kernel_probe_location *location,
27 struct lttng_payload *payload);
28
29static
30int lttng_kernel_probe_location_symbol_serialize(
31 const struct lttng_kernel_probe_location *location,
32 struct lttng_payload *payload);
33
34static
35bool lttng_kernel_probe_location_address_is_equal(
36 const struct lttng_kernel_probe_location *a,
37 const struct lttng_kernel_probe_location *b);
38
39static
40bool lttng_kernel_probe_location_symbol_is_equal(
41 const struct lttng_kernel_probe_location *a,
42 const struct lttng_kernel_probe_location *b);
43
959e3c66
JR
44static
45unsigned long lttng_kernel_probe_location_address_hash(
46 const struct lttng_kernel_probe_location *location);
47
48static
49unsigned long lttng_kernel_probe_location_symbol_hash(
50 const struct lttng_kernel_probe_location *location);
51
6a751b95
JR
52static
53enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
54 const struct lttng_kernel_probe_location *location,
55 struct mi_writer *writer);
56
57static
58enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
59 const struct lttng_kernel_probe_location *location,
60 struct mi_writer *writer);
61
808cb744
JR
62enum lttng_kernel_probe_location_type lttng_kernel_probe_location_get_type(
63 const struct lttng_kernel_probe_location *location)
64{
65 return location ? location->type :
66 LTTNG_KERNEL_PROBE_LOCATION_TYPE_UNKNOWN;
67}
68
69static
70void lttng_kernel_probe_location_address_destroy(
71 struct lttng_kernel_probe_location *location)
72{
a0377dfe 73 LTTNG_ASSERT(location);
808cb744
JR
74 free(location);
75}
76
77static
78void lttng_kernel_probe_location_symbol_destroy(
79 struct lttng_kernel_probe_location *location)
80{
81 struct lttng_kernel_probe_location_symbol *location_symbol = NULL;
82
a0377dfe 83 LTTNG_ASSERT(location);
808cb744 84
0114db0e
JG
85 location_symbol = lttng::utils::container_of(location,
86 &lttng_kernel_probe_location_symbol::parent);
808cb744 87
a0377dfe 88 LTTNG_ASSERT(location_symbol);
808cb744
JR
89
90 free(location_symbol->symbol_name);
91 free(location);
92}
93
94void lttng_kernel_probe_location_destroy(
95 struct lttng_kernel_probe_location *location)
96{
97 if (!location) {
98 return;
99 }
100
101 switch (location->type) {
102 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
103 lttng_kernel_probe_location_address_destroy(location);
104 break;
105 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
106 lttng_kernel_probe_location_symbol_destroy(location);
107 break;
108 default:
109 abort();
110 }
111}
112
113struct lttng_kernel_probe_location *
114lttng_kernel_probe_location_address_create(uint64_t address)
115{
116 struct lttng_kernel_probe_location *ret = NULL;
117 struct lttng_kernel_probe_location_address *location;
118
64803277 119 location = zmalloc<lttng_kernel_probe_location_address>();
808cb744 120 if (!location) {
077192fd 121 PERROR("Error allocating userspace probe location.");
808cb744
JR
122 goto end;
123 }
124
125 location->address = address;
126
127 ret = &location->parent;
128 ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS;
129 ret->equal = lttng_kernel_probe_location_address_is_equal;
130 ret->serialize = lttng_kernel_probe_location_address_serialize;
959e3c66 131 ret->hash = lttng_kernel_probe_location_address_hash;
6a751b95 132 ret->mi_serialize = lttng_kernel_probe_location_address_mi_serialize;
808cb744
JR
133
134end:
135 return ret;
136}
137
138struct lttng_kernel_probe_location *
139lttng_kernel_probe_location_symbol_create(const char *symbol_name,
140 uint64_t offset)
141{
142 char *symbol_name_copy = NULL;
143 struct lttng_kernel_probe_location *ret = NULL;
144 struct lttng_kernel_probe_location_symbol *location;
145
146 if (!symbol_name || strlen(symbol_name) >= LTTNG_SYMBOL_NAME_LEN) {
147 goto error;
148 }
149
150 symbol_name_copy = strdup(symbol_name);
151 if (!symbol_name_copy) {
152 PERROR("Failed to copy symbol name '%s'", symbol_name);
153 goto error;
154 }
155
64803277 156 location = zmalloc<lttng_kernel_probe_location_symbol>();
808cb744
JR
157 if (!location) {
158 PERROR("Failed to allocate kernel symbol probe location");
159 goto error;
160 }
161
162 location->symbol_name = symbol_name_copy;
163 location->offset = offset;
164
165 ret = &location->parent;
166 ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET;
167 ret->equal = lttng_kernel_probe_location_symbol_is_equal;
168 ret->serialize = lttng_kernel_probe_location_symbol_serialize;
959e3c66 169 ret->hash = lttng_kernel_probe_location_symbol_hash;
6a751b95 170 ret->mi_serialize = lttng_kernel_probe_location_symbol_mi_serialize;
808cb744
JR
171 goto end;
172
173error:
174 free(symbol_name_copy);
175end:
176 return ret;
177}
178
179enum lttng_kernel_probe_location_status
180lttng_kernel_probe_location_address_get_address(
181 const struct lttng_kernel_probe_location *location,
182 uint64_t *offset)
183{
184 enum lttng_kernel_probe_location_status ret =
185 LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK;
186 struct lttng_kernel_probe_location_address *address_location;
187
a0377dfe 188 LTTNG_ASSERT(offset);
808cb744
JR
189
190 if (!location || lttng_kernel_probe_location_get_type(location) !=
191 LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS) {
192 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
193 ret = LTTNG_KERNEL_PROBE_LOCATION_STATUS_INVALID;
194 goto end;
195 }
196
0114db0e
JG
197 address_location = lttng::utils::container_of(location,
198 &lttng_kernel_probe_location_address::parent);
808cb744
JR
199 *offset = address_location->address;
200end:
201 return ret;
202}
203
204const char *lttng_kernel_probe_location_symbol_get_name(
205 const struct lttng_kernel_probe_location *location)
206{
207 const char *ret = NULL;
208 struct lttng_kernel_probe_location_symbol *symbol_location;
209
210 if (!location || lttng_kernel_probe_location_get_type(location) !=
211 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET) {
212 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
213 goto end;
214 }
215
0114db0e
JG
216 symbol_location = lttng::utils::container_of(location,
217 &lttng_kernel_probe_location_symbol::parent);
808cb744
JR
218 ret = symbol_location->symbol_name;
219end:
220 return ret;
221}
222
223enum lttng_kernel_probe_location_status
224lttng_kernel_probe_location_symbol_get_offset(
225 const struct lttng_kernel_probe_location *location,
226 uint64_t *offset)
227{
228 enum lttng_kernel_probe_location_status ret =
229 LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK;
230 struct lttng_kernel_probe_location_symbol *symbol_location;
231
a0377dfe 232 LTTNG_ASSERT(offset);
808cb744
JR
233
234 if (!location || lttng_kernel_probe_location_get_type(location) !=
235 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET) {
236 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
237 ret = LTTNG_KERNEL_PROBE_LOCATION_STATUS_INVALID;
238 goto end;
239 }
240
0114db0e
JG
241 symbol_location = lttng::utils::container_of(location,
242 &lttng_kernel_probe_location_symbol::parent);
808cb744
JR
243 *offset = symbol_location->offset;
244end:
245 return ret;
246}
247
248static
249int lttng_kernel_probe_location_symbol_serialize(
250 const struct lttng_kernel_probe_location *location,
251 struct lttng_payload *payload)
252{
253 int ret;
254 size_t symbol_name_len;
255 size_t original_payload_size;
256 struct lttng_kernel_probe_location_symbol *location_symbol;
257 struct lttng_kernel_probe_location_symbol_comm location_symbol_comm;
258
259 if (!location || !payload) {
260 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
261 ret = -LTTNG_ERR_INVALID;
262 goto end;
263 }
264
a0377dfe 265 LTTNG_ASSERT(lttng_kernel_probe_location_get_type(location) ==
808cb744
JR
266 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
267
268 original_payload_size = payload->buffer.size;
0114db0e
JG
269 location_symbol = lttng::utils::container_of(location,
270 &lttng_kernel_probe_location_symbol::parent);
808cb744
JR
271
272 if (!location_symbol->symbol_name) {
273 ret = -LTTNG_ERR_INVALID;
274 goto end;
275 }
276
277 symbol_name_len = strlen(location_symbol->symbol_name);
278 if (symbol_name_len == 0) {
279 ret = -LTTNG_ERR_INVALID;
280 goto end;
281 }
282
283 location_symbol_comm.symbol_len = symbol_name_len + 1;
284 location_symbol_comm.offset = location_symbol->offset;
285
286 ret = lttng_dynamic_buffer_append(&payload->buffer,
287 &location_symbol_comm, sizeof(location_symbol_comm));
288 if (ret) {
289 ret = -LTTNG_ERR_INVALID;
290 goto end;
291 }
292
293 ret = lttng_dynamic_buffer_append(&payload->buffer,
294 location_symbol->symbol_name,
295 location_symbol_comm.symbol_len);
296 if (ret) {
297 ret = -LTTNG_ERR_INVALID;
298 goto end;
299 }
300
301 ret = (int) (payload->buffer.size - original_payload_size);
302end:
303 return ret;
304}
305
306static
307int lttng_kernel_probe_location_address_serialize(
308 const struct lttng_kernel_probe_location *location,
309 struct lttng_payload *payload)
310{
311 int ret;
312 size_t original_payload_size;
313 struct lttng_kernel_probe_location_address *location_address;
314 struct lttng_kernel_probe_location_address_comm location_address_comm;
315
a0377dfe
FD
316 LTTNG_ASSERT(location);
317 LTTNG_ASSERT(lttng_kernel_probe_location_get_type(location) ==
808cb744
JR
318 LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
319
320 original_payload_size = payload->buffer.size;
0114db0e
JG
321 location_address = lttng::utils::container_of(location,
322 &lttng_kernel_probe_location_address::parent);
808cb744
JR
323
324 location_address_comm.address = location_address->address;
325
326 ret = lttng_dynamic_buffer_append(&payload->buffer,
327 &location_address_comm,
328 sizeof(location_address_comm));
329 if (ret) {
330 ret = -LTTNG_ERR_INVALID;
331 goto end;
332 }
333
334 ret = (int) (payload->buffer.size - original_payload_size);
335end:
336 return ret;
337}
338
808cb744
JR
339int lttng_kernel_probe_location_serialize(
340 const struct lttng_kernel_probe_location *location,
341 struct lttng_payload *payload)
342{
343 int ret;
344 size_t original_payload_size;
345 struct lttng_kernel_probe_location_comm location_generic_comm = {};
346
347 if (!location || !payload) {
348 ERR("Invalid argument(s) passed to '%s'", __FUNCTION__);
349 ret = -LTTNG_ERR_INVALID;
350 goto end;
351 }
352
353 original_payload_size = payload->buffer.size;
354 location_generic_comm.type = (int8_t) location->type;
355 ret = lttng_dynamic_buffer_append(&payload->buffer,
356 &location_generic_comm,
357 sizeof(location_generic_comm));
358 if (ret) {
359 goto end;
360 }
361
362 ret = location->serialize(location, payload);
363 if (ret < 0) {
364 goto end;
365 }
366
367 ret = (int) (payload->buffer.size - original_payload_size);
368end:
369 return ret;
370}
371
372static
373int lttng_kernel_probe_location_symbol_create_from_payload(
374 struct lttng_payload_view *view,
375 struct lttng_kernel_probe_location **location)
376{
377 struct lttng_kernel_probe_location_symbol_comm *location_symbol_comm;
378 const char *symbol_name_src;
379 ssize_t ret = 0;
380 size_t expected_size;
381
a0377dfe 382 LTTNG_ASSERT(location);
808cb744
JR
383
384 if (view->buffer.size < sizeof(*location_symbol_comm)) {
385 ret = -LTTNG_ERR_INVALID;
386 goto end;
387 }
388
389 location_symbol_comm =
390 (typeof(location_symbol_comm)) view->buffer.data;
391
392 expected_size = sizeof(*location_symbol_comm) +
393 location_symbol_comm->symbol_len;
394
395 if (view->buffer.size < expected_size) {
396 ret = -LTTNG_ERR_INVALID;
397 goto end;
398 }
399
400 symbol_name_src = view->buffer.data + sizeof(*location_symbol_comm);
401
402 if (!lttng_buffer_view_contains_string(&view->buffer, symbol_name_src,
403 location_symbol_comm->symbol_len)) {
404 ret = -LTTNG_ERR_INVALID;
405 goto end;
406 }
407
408 *location = lttng_kernel_probe_location_symbol_create(
409 symbol_name_src, location_symbol_comm->offset);
410 if (!(*location)) {
411 ret = -LTTNG_ERR_INVALID;
412 goto end;
413 }
414
415 ret = (ssize_t) expected_size;
416end:
417 return ret;
418}
419
420static
421ssize_t lttng_kernel_probe_location_address_create_from_payload(
422 struct lttng_payload_view *view,
423 struct lttng_kernel_probe_location **location)
424{
425 struct lttng_kernel_probe_location_address_comm *location_address_comm;
426 ssize_t ret = 0;
427 size_t expected_size;
428
a0377dfe 429 LTTNG_ASSERT(location);
808cb744
JR
430
431 expected_size = sizeof(*location_address_comm);
432
433 if (view->buffer.size < expected_size) {
434 ret = -LTTNG_ERR_INVALID;
435 goto end;
436 }
437
438 location_address_comm =
439 (typeof(location_address_comm)) view->buffer.data;
440
441 *location = lttng_kernel_probe_location_address_create(location_address_comm->address);
442 if (!(*location)) {
443 ret = -LTTNG_ERR_INVALID;
444 goto end;
445 }
446
447 ret = (size_t) expected_size;
448end:
449 return ret;
450}
451
808cb744
JR
452ssize_t lttng_kernel_probe_location_create_from_payload(
453 struct lttng_payload_view *view,
454 struct lttng_kernel_probe_location **location)
455{
808cb744
JR
456 enum lttng_kernel_probe_location_type type;
457 ssize_t consumed = 0;
458 ssize_t ret;
3e6e0df2
JG
459 const struct lttng_kernel_probe_location_comm *probe_location_comm;
460 const struct lttng_payload_view probe_location_comm_view =
461 lttng_payload_view_from_view(
462 view, 0, sizeof(*probe_location_comm));
808cb744 463
a0377dfe
FD
464 LTTNG_ASSERT(view);
465 LTTNG_ASSERT(location);
808cb744 466
3e6e0df2 467 if (!lttng_payload_view_is_valid(&probe_location_comm_view)) {
808cb744
JR
468 ret = -LTTNG_ERR_INVALID;
469 goto end;
470 }
471
3e6e0df2 472 probe_location_comm = (typeof(probe_location_comm)) probe_location_comm_view.buffer.data;
808cb744
JR
473 type = (enum lttng_kernel_probe_location_type) probe_location_comm->type;
474 consumed += sizeof(*probe_location_comm);
475
476 switch (type) {
477 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
478 {
479 struct lttng_payload_view location_view =
480 lttng_payload_view_from_view(
481 view, consumed, -1);
482
483 ret = lttng_kernel_probe_location_symbol_create_from_payload(
484 &location_view, location);
485 break;
486 }
487 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
488 {
489 struct lttng_payload_view location_view =
490 lttng_payload_view_from_view(view, consumed, -1);
491
492 ret = lttng_kernel_probe_location_address_create_from_payload(
493 &location_view, location);
494 break;
495 }
496 default:
497 ret = -LTTNG_ERR_INVALID;
498 break;
499 }
500
501 if (ret < 0) {
502 ret = -LTTNG_ERR_INVALID;
503 goto end;
504 }
505
506 ret += consumed;
507
508end:
509 return ret;
510}
511
959e3c66
JR
512static
513unsigned long lttng_kernel_probe_location_address_hash(
514 const struct lttng_kernel_probe_location *location)
515{
516 unsigned long hash = hash_key_ulong(
517 (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS,
518 lttng_ht_seed);
0114db0e
JG
519 struct lttng_kernel_probe_location_address *address_location = lttng::utils::container_of(
520 location, &lttng_kernel_probe_location_address::parent);
959e3c66
JR
521
522 hash ^= hash_key_u64(&address_location->address, lttng_ht_seed);
523
524 return hash;
525}
526
808cb744
JR
527static
528bool lttng_kernel_probe_location_address_is_equal(
529 const struct lttng_kernel_probe_location *_a,
530 const struct lttng_kernel_probe_location *_b)
531{
532 bool is_equal = false;
533 struct lttng_kernel_probe_location_address *a, *b;
534
0114db0e
JG
535 a = lttng::utils::container_of(_a, &lttng_kernel_probe_location_address::parent);
536 b = lttng::utils::container_of(_b, &lttng_kernel_probe_location_address::parent);
808cb744
JR
537
538 if (a->address != b->address) {
539 goto end;
540 }
541
542 is_equal = true;
543
544end:
545 return is_equal;
546}
547
959e3c66
JR
548static
549unsigned long lttng_kernel_probe_location_symbol_hash(
550 const struct lttng_kernel_probe_location *location)
551{
552 unsigned long hash = hash_key_ulong(
0114db0e
JG
553 (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET, lttng_ht_seed);
554 struct lttng_kernel_probe_location_symbol *symbol_location = lttng::utils::container_of(
555 location, &lttng_kernel_probe_location_symbol::parent);
959e3c66
JR
556
557 hash ^= hash_key_str(symbol_location->symbol_name, lttng_ht_seed);
558 hash ^= hash_key_u64(&symbol_location->offset, lttng_ht_seed);
559
560 return hash;
561}
562
808cb744
JR
563static
564bool lttng_kernel_probe_location_symbol_is_equal(
565 const struct lttng_kernel_probe_location *_a,
566 const struct lttng_kernel_probe_location *_b)
567{
568 bool is_equal = false;
569 struct lttng_kernel_probe_location_symbol *a, *b;
570
0114db0e
JG
571 a = lttng::utils::container_of(_a,
572 &lttng_kernel_probe_location_symbol::parent);
573 b = lttng::utils::container_of(_b,
574 &lttng_kernel_probe_location_symbol::parent);
808cb744 575
a0377dfe
FD
576 LTTNG_ASSERT(a->symbol_name);
577 LTTNG_ASSERT(b->symbol_name);
808cb744
JR
578 if (strcmp(a->symbol_name, b->symbol_name)) {
579 goto end;
580 }
581
582 if (a->offset != b->offset) {
583 goto end;
584 }
585
586 is_equal = true;
587
588end:
589 return is_equal;
590}
591
808cb744
JR
592bool lttng_kernel_probe_location_is_equal(
593 const struct lttng_kernel_probe_location *a,
594 const struct lttng_kernel_probe_location *b)
595{
596 bool is_equal = false;
597
598 if (!a || !b) {
599 goto end;
600 }
601
602 if (a == b) {
603 is_equal = true;
604 goto end;
605 }
606
607 if (a->type != b->type) {
608 goto end;
609 }
610
611 is_equal = a->equal ? a->equal(a, b) : true;
612end:
613 return is_equal;
614}
077192fd
JR
615
616static struct lttng_kernel_probe_location *
617lttng_kernel_probe_location_symbol_copy(
618 const struct lttng_kernel_probe_location *location)
619{
620 struct lttng_kernel_probe_location *new_location = NULL;
077192fd
JR
621 enum lttng_kernel_probe_location_status status;
622 const char *symbol_name = NULL;
623 uint64_t offset;
624
a0377dfe
FD
625 LTTNG_ASSERT(location);
626 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
077192fd
JR
627
628 /* Get probe location offset */
629 status = lttng_kernel_probe_location_symbol_get_offset(location, &offset);
630 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
631 ERR("Get kernel probe location offset failed.");
632 goto error;
633 }
634
635 symbol_name = lttng_kernel_probe_location_symbol_get_name(location);
636 if (!symbol_name) {
637 ERR("Kernel probe symbol name is NULL.");
638 goto error;
639 }
640
641 /* Create the probe_location */
642 new_location = lttng_kernel_probe_location_symbol_create(
643 symbol_name, offset);
644
645 goto end;
646
647error:
648 new_location = NULL;
649end:
650 return new_location;
651}
652static struct lttng_kernel_probe_location *
653lttng_kernel_probe_location_address_copy(
654 const struct lttng_kernel_probe_location *location)
655{
656 struct lttng_kernel_probe_location *new_location = NULL;
077192fd
JR
657 enum lttng_kernel_probe_location_status status;
658 uint64_t address;
659
a0377dfe
FD
660 LTTNG_ASSERT(location);
661 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
077192fd 662
0114db0e 663 /* Get probe location fields */
077192fd
JR
664 status = lttng_kernel_probe_location_address_get_address(location, &address);
665 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
666 ERR("Get kernel probe address failed.");
667 goto error;
668 }
669
670 /* Create the probe_location */
671 new_location = lttng_kernel_probe_location_address_create(address);
672
673 goto end;
674
675error:
676 new_location = NULL;
677end:
678 return new_location;
679}
680
077192fd
JR
681struct lttng_kernel_probe_location *lttng_kernel_probe_location_copy(
682 const struct lttng_kernel_probe_location *location)
683{
684 struct lttng_kernel_probe_location *new_location = NULL;
685 enum lttng_kernel_probe_location_type type;
686
687 if (!location) {
688 goto err;
689 }
690
691 type = lttng_kernel_probe_location_get_type(location);
692 switch (type) {
693 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
694 new_location =
695 lttng_kernel_probe_location_address_copy(location);
696 if (!new_location) {
697 goto err;
698 }
699 break;
700 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
701 new_location =
702 lttng_kernel_probe_location_symbol_copy(location);
703 if (!new_location) {
704 goto err;
705 }
706 break;
707 default:
708 new_location = NULL;
709 goto err;
710 }
711err:
712 return new_location;
713}
959e3c66 714
959e3c66
JR
715unsigned long lttng_kernel_probe_location_hash(
716 const struct lttng_kernel_probe_location *location)
717{
718 return location->hash(location);
719}
6a751b95
JR
720
721static
722enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize(
723 const struct lttng_kernel_probe_location *location,
724 struct mi_writer *writer)
725{
726 int ret;
727 enum lttng_error_code ret_code;
728 enum lttng_kernel_probe_location_status status;
729 uint64_t address;
730
a0377dfe
FD
731 LTTNG_ASSERT(location);
732 LTTNG_ASSERT(writer);
733 LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS);
6a751b95
JR
734
735 status = lttng_kernel_probe_location_address_get_address(
736 location, &address);
a0377dfe 737 LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
6a751b95
JR
738
739 /* Open kernel probe location address element. */
740 ret = mi_lttng_writer_open_element(
741 writer, mi_lttng_element_kernel_probe_location_address);
742 if (ret) {
743 goto mi_error;
744 }
745
746 ret = mi_lttng_writer_write_element_unsigned_int(writer,
747 mi_lttng_element_kernel_probe_location_address_address,
748 address);
749 if (ret) {
750 goto mi_error;
751 }
752
753 /* Close kernel probe location address element. */
754 ret = mi_lttng_writer_close_element(writer);
755 if (ret) {
756 goto mi_error;
757 }
758
759 ret_code = LTTNG_OK;
760 goto end;
761
762mi_error:
763 ret_code = LTTNG_ERR_MI_IO_FAIL;
764end:
765 return ret_code;
766}
767
768static
769enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize(
770 const struct lttng_kernel_probe_location *location,
771 struct mi_writer *writer)
772{
773 int ret;
774 enum lttng_error_code ret_code;
775 enum lttng_kernel_probe_location_status status;
776 const char *name = NULL;
777 uint64_t offset;
778
a0377dfe
FD
779 LTTNG_ASSERT(location);
780 LTTNG_ASSERT(writer);
781 LTTNG_ASSERT(location->type ==
6a751b95
JR
782 LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET);
783
784 name = lttng_kernel_probe_location_symbol_get_name(location);
a0377dfe 785 LTTNG_ASSERT(name);
6a751b95
JR
786
787 status = lttng_kernel_probe_location_symbol_get_offset(
788 location, &offset);
a0377dfe 789 LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK);
6a751b95
JR
790
791 /* Open kernel probe location symbol offset element. */
792 ret = mi_lttng_writer_open_element(writer,
793 mi_lttng_element_kernel_probe_location_symbol_offset);
794 if (ret) {
795 goto mi_error;
796 }
797
798 /* Name. */
799 ret = mi_lttng_writer_write_element_string(writer,
800 mi_lttng_element_kernel_probe_location_symbol_offset_name,
801 name);
802 if (ret) {
803 goto mi_error;
804 }
805
806 /* Offset. */
807 ret = mi_lttng_writer_write_element_unsigned_int(writer,
808 mi_lttng_element_kernel_probe_location_symbol_offset_offset,
809 offset);
810 if (ret) {
811 goto mi_error;
812 }
813
814 /* Close kernel probe location symbol offset element. */
815 ret = mi_lttng_writer_close_element(writer);
816 if (ret) {
817 goto mi_error;
818 }
819
820 ret_code = LTTNG_OK;
821 goto end;
822
823mi_error:
824 ret_code = LTTNG_ERR_MI_IO_FAIL;
825end:
826 return ret_code;
827}
828
6a751b95
JR
829enum lttng_error_code lttng_kernel_probe_location_mi_serialize(
830 const struct lttng_kernel_probe_location *location,
831 struct mi_writer *writer)
832{
833 int ret;
834 enum lttng_error_code ret_code;
835
a0377dfe
FD
836 LTTNG_ASSERT(location);
837 LTTNG_ASSERT(writer);
6a751b95
JR
838
839 /* Open kernel probe location element. */
840 ret = mi_lttng_writer_open_element(
841 writer, mi_lttng_element_kernel_probe_location);
842 if (ret) {
843 goto mi_error;
844 }
845
846 /* Serialize the location sub type. */
847 ret_code = location->mi_serialize(location, writer);
848 if (ret_code != LTTNG_OK) {
849 goto end;
850 }
851
852 /* Close kernel probe location element. */
853 ret = mi_lttng_writer_close_element(writer);
854 if (ret) {
855 goto mi_error;
856 }
857
858 ret_code = LTTNG_OK;
859 goto end;
860
861mi_error:
862 ret_code = LTTNG_ERR_MI_IO_FAIL;
863end:
864 return ret_code;
865}
This page took 0.07536 seconds and 4 git commands to generate.