X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Fkernel-probe.c;h=33ba00fca37a9a906cc45b59fed628ae74e7163b;hb=3afa94aeca5a0daae40fd7b6cc96b7e4c150c7d8;hp=1934a76b1e261ffb44505fe8d02da21c5c74119a;hpb=808cb744a46310d2e5fbbe9ab025cd427bcfc0a8;p=lttng-tools.git diff --git a/src/common/kernel-probe.c b/src/common/kernel-probe.c index 1934a76b1..33ba00fca 100644 --- a/src/common/kernel-probe.c +++ b/src/common/kernel-probe.c @@ -6,18 +6,20 @@ */ #include "lttng/lttng-error.h" -#include #include +#include +#include #include -#include +#include #include +#include #include #include -#include #include +#include #include #include -#include +#include static int lttng_kernel_probe_location_address_serialize( @@ -39,6 +41,24 @@ bool lttng_kernel_probe_location_symbol_is_equal( const struct lttng_kernel_probe_location *a, const struct lttng_kernel_probe_location *b); +static +unsigned long lttng_kernel_probe_location_address_hash( + const struct lttng_kernel_probe_location *location); + +static +unsigned long lttng_kernel_probe_location_symbol_hash( + const struct lttng_kernel_probe_location *location); + +static +enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize( + const struct lttng_kernel_probe_location *location, + struct mi_writer *writer); + +static +enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize( + const struct lttng_kernel_probe_location *location, + struct mi_writer *writer); + enum lttng_kernel_probe_location_type lttng_kernel_probe_location_get_type( const struct lttng_kernel_probe_location *location) { @@ -50,7 +70,7 @@ static void lttng_kernel_probe_location_address_destroy( struct lttng_kernel_probe_location *location) { - assert(location); + LTTNG_ASSERT(location); free(location); } @@ -60,13 +80,13 @@ void lttng_kernel_probe_location_symbol_destroy( { struct lttng_kernel_probe_location_symbol *location_symbol = NULL; - assert(location); + LTTNG_ASSERT(location); location_symbol = container_of(location, struct lttng_kernel_probe_location_symbol, parent); - assert(location_symbol); + LTTNG_ASSERT(location_symbol); free(location_symbol->symbol_name); free(location); @@ -99,7 +119,7 @@ lttng_kernel_probe_location_address_create(uint64_t address) location = zmalloc(sizeof(*location)); if (!location) { - PERROR("Error allocating userspace probe location"); + PERROR("Error allocating userspace probe location."); goto end; } @@ -109,6 +129,8 @@ lttng_kernel_probe_location_address_create(uint64_t address) ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS; ret->equal = lttng_kernel_probe_location_address_is_equal; ret->serialize = lttng_kernel_probe_location_address_serialize; + ret->hash = lttng_kernel_probe_location_address_hash; + ret->mi_serialize = lttng_kernel_probe_location_address_mi_serialize; end: return ret; @@ -145,6 +167,8 @@ lttng_kernel_probe_location_symbol_create(const char *symbol_name, ret->type = LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET; ret->equal = lttng_kernel_probe_location_symbol_is_equal; ret->serialize = lttng_kernel_probe_location_symbol_serialize; + ret->hash = lttng_kernel_probe_location_symbol_hash; + ret->mi_serialize = lttng_kernel_probe_location_symbol_mi_serialize; goto end; error: @@ -162,7 +186,7 @@ lttng_kernel_probe_location_address_get_address( LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK; struct lttng_kernel_probe_location_address *address_location; - assert(offset); + LTTNG_ASSERT(offset); if (!location || lttng_kernel_probe_location_get_type(location) != LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS) { @@ -206,7 +230,7 @@ lttng_kernel_probe_location_symbol_get_offset( LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK; struct lttng_kernel_probe_location_symbol *symbol_location; - assert(offset); + LTTNG_ASSERT(offset); if (!location || lttng_kernel_probe_location_get_type(location) != LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET) { @@ -239,7 +263,7 @@ int lttng_kernel_probe_location_symbol_serialize( goto end; } - assert(lttng_kernel_probe_location_get_type(location) == + LTTNG_ASSERT(lttng_kernel_probe_location_get_type(location) == LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET); original_payload_size = payload->buffer.size; @@ -290,8 +314,8 @@ int lttng_kernel_probe_location_address_serialize( struct lttng_kernel_probe_location_address *location_address; struct lttng_kernel_probe_location_address_comm location_address_comm; - assert(location); - assert(lttng_kernel_probe_location_get_type(location) == + LTTNG_ASSERT(location); + LTTNG_ASSERT(lttng_kernel_probe_location_get_type(location) == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS); original_payload_size = payload->buffer.size; @@ -314,7 +338,6 @@ end: return ret; } -LTTNG_HIDDEN int lttng_kernel_probe_location_serialize( const struct lttng_kernel_probe_location *location, struct lttng_payload *payload) @@ -358,7 +381,7 @@ int lttng_kernel_probe_location_symbol_create_from_payload( ssize_t ret = 0; size_t expected_size; - assert(location); + LTTNG_ASSERT(location); if (view->buffer.size < sizeof(*location_symbol_comm)) { ret = -LTTNG_ERR_INVALID; @@ -405,7 +428,7 @@ ssize_t lttng_kernel_probe_location_address_create_from_payload( ssize_t ret = 0; size_t expected_size; - assert(location); + LTTNG_ASSERT(location); expected_size = sizeof(*location_address_comm); @@ -428,25 +451,27 @@ end: return ret; } -LTTNG_HIDDEN ssize_t lttng_kernel_probe_location_create_from_payload( struct lttng_payload_view *view, struct lttng_kernel_probe_location **location) { - struct lttng_kernel_probe_location_comm *probe_location_comm; enum lttng_kernel_probe_location_type type; ssize_t consumed = 0; ssize_t ret; + const struct lttng_kernel_probe_location_comm *probe_location_comm; + const struct lttng_payload_view probe_location_comm_view = + lttng_payload_view_from_view( + view, 0, sizeof(*probe_location_comm)); - assert(view); - assert(location); + LTTNG_ASSERT(view); + LTTNG_ASSERT(location); - if (view->buffer.size <= sizeof(*probe_location_comm)) { + if (!lttng_payload_view_is_valid(&probe_location_comm_view)) { ret = -LTTNG_ERR_INVALID; goto end; } - probe_location_comm = (typeof(probe_location_comm)) view->buffer.data; + probe_location_comm = (typeof(probe_location_comm)) probe_location_comm_view.buffer.data; type = (enum lttng_kernel_probe_location_type) probe_location_comm->type; consumed += sizeof(*probe_location_comm); @@ -486,6 +511,22 @@ end: return ret; } +static +unsigned long lttng_kernel_probe_location_address_hash( + const struct lttng_kernel_probe_location *location) +{ + unsigned long hash = hash_key_ulong( + (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS, + lttng_ht_seed); + struct lttng_kernel_probe_location_address *address_location = + container_of(location, typeof(*address_location), + parent); + + hash ^= hash_key_u64(&address_location->address, lttng_ht_seed); + + return hash; +} + static bool lttng_kernel_probe_location_address_is_equal( const struct lttng_kernel_probe_location *_a, @@ -509,6 +550,23 @@ end: return is_equal; } +static +unsigned long lttng_kernel_probe_location_symbol_hash( + const struct lttng_kernel_probe_location *location) +{ + unsigned long hash = hash_key_ulong( + (void *) LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET, + lttng_ht_seed); + struct lttng_kernel_probe_location_symbol *symbol_location = + container_of(location, typeof(*symbol_location), + parent); + + hash ^= hash_key_str(symbol_location->symbol_name, lttng_ht_seed); + hash ^= hash_key_u64(&symbol_location->offset, lttng_ht_seed); + + return hash; +} + static bool lttng_kernel_probe_location_symbol_is_equal( const struct lttng_kernel_probe_location *_a, @@ -522,8 +580,8 @@ bool lttng_kernel_probe_location_symbol_is_equal( b = container_of(_b, struct lttng_kernel_probe_location_symbol, parent); - assert(a->symbol_name); - assert(b->symbol_name); + LTTNG_ASSERT(a->symbol_name); + LTTNG_ASSERT(b->symbol_name); if (strcmp(a->symbol_name, b->symbol_name)) { goto end; } @@ -538,7 +596,6 @@ end: return is_equal; } -LTTNG_HIDDEN bool lttng_kernel_probe_location_is_equal( const struct lttng_kernel_probe_location *a, const struct lttng_kernel_probe_location *b) @@ -562,3 +619,261 @@ bool lttng_kernel_probe_location_is_equal( end: return is_equal; } + +static struct lttng_kernel_probe_location * +lttng_kernel_probe_location_symbol_copy( + const struct lttng_kernel_probe_location *location) +{ + struct lttng_kernel_probe_location *new_location = NULL; + struct lttng_kernel_probe_location_symbol *symbol_location; + enum lttng_kernel_probe_location_status status; + const char *symbol_name = NULL; + uint64_t offset; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET); + symbol_location = container_of( + location, typeof(*symbol_location), parent); + + /* Get probe location offset */ + status = lttng_kernel_probe_location_symbol_get_offset(location, &offset); + if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) { + ERR("Get kernel probe location offset failed."); + goto error; + } + + symbol_name = lttng_kernel_probe_location_symbol_get_name(location); + if (!symbol_name) { + ERR("Kernel probe symbol name is NULL."); + goto error; + } + + /* Create the probe_location */ + new_location = lttng_kernel_probe_location_symbol_create( + symbol_name, offset); + + goto end; + +error: + new_location = NULL; +end: + return new_location; +} +static struct lttng_kernel_probe_location * +lttng_kernel_probe_location_address_copy( + const struct lttng_kernel_probe_location *location) +{ + struct lttng_kernel_probe_location *new_location = NULL; + struct lttng_kernel_probe_location_address *address_location; + enum lttng_kernel_probe_location_status status; + uint64_t address; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS); + address_location = container_of( + location, typeof(*address_location), parent); + + + /* Get probe location fields */ + status = lttng_kernel_probe_location_address_get_address(location, &address); + if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) { + ERR("Get kernel probe address failed."); + goto error; + } + + /* Create the probe_location */ + new_location = lttng_kernel_probe_location_address_create(address); + + goto end; + +error: + new_location = NULL; +end: + return new_location; +} + +struct lttng_kernel_probe_location *lttng_kernel_probe_location_copy( + const struct lttng_kernel_probe_location *location) +{ + struct lttng_kernel_probe_location *new_location = NULL; + enum lttng_kernel_probe_location_type type; + + if (!location) { + goto err; + } + + type = lttng_kernel_probe_location_get_type(location); + switch (type) { + case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS: + new_location = + lttng_kernel_probe_location_address_copy(location); + if (!new_location) { + goto err; + } + break; + case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET: + new_location = + lttng_kernel_probe_location_symbol_copy(location); + if (!new_location) { + goto err; + } + break; + default: + new_location = NULL; + goto err; + } +err: + return new_location; +} + +unsigned long lttng_kernel_probe_location_hash( + const struct lttng_kernel_probe_location *location) +{ + return location->hash(location); +} + +static +enum lttng_error_code lttng_kernel_probe_location_address_mi_serialize( + const struct lttng_kernel_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + enum lttng_kernel_probe_location_status status; + uint64_t address; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(writer); + LTTNG_ASSERT(location->type == LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS); + + status = lttng_kernel_probe_location_address_get_address( + location, &address); + LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK); + + /* Open kernel probe location address element. */ + ret = mi_lttng_writer_open_element( + writer, mi_lttng_element_kernel_probe_location_address); + if (ret) { + goto mi_error; + } + + ret = mi_lttng_writer_write_element_unsigned_int(writer, + mi_lttng_element_kernel_probe_location_address_address, + address); + if (ret) { + goto mi_error; + } + + /* Close kernel probe location address element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +} + +static +enum lttng_error_code lttng_kernel_probe_location_symbol_mi_serialize( + const struct lttng_kernel_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + enum lttng_kernel_probe_location_status status; + const char *name = NULL; + uint64_t offset; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(writer); + LTTNG_ASSERT(location->type == + LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET); + + name = lttng_kernel_probe_location_symbol_get_name(location); + LTTNG_ASSERT(name); + + status = lttng_kernel_probe_location_symbol_get_offset( + location, &offset); + LTTNG_ASSERT(status == LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK); + + /* Open kernel probe location symbol offset element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_kernel_probe_location_symbol_offset); + if (ret) { + goto mi_error; + } + + /* Name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_kernel_probe_location_symbol_offset_name, + name); + if (ret) { + goto mi_error; + } + + /* Offset. */ + ret = mi_lttng_writer_write_element_unsigned_int(writer, + mi_lttng_element_kernel_probe_location_symbol_offset_offset, + offset); + if (ret) { + goto mi_error; + } + + /* Close kernel probe location symbol offset element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +} + +enum lttng_error_code lttng_kernel_probe_location_mi_serialize( + const struct lttng_kernel_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + + LTTNG_ASSERT(location); + LTTNG_ASSERT(writer); + + /* Open kernel probe location element. */ + ret = mi_lttng_writer_open_element( + writer, mi_lttng_element_kernel_probe_location); + if (ret) { + goto mi_error; + } + + /* Serialize the location sub type. */ + ret_code = location->mi_serialize(location, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close kernel probe location element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto mi_error; + } + + ret_code = LTTNG_OK; + goto end; + +mi_error: + ret_code = LTTNG_ERR_MI_IO_FAIL; +end: + return ret_code; +}