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