X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Fuserspace-probe.c;h=67b0ee69820c708e28bbd297674f8c3d055b7539;hb=6a751b953a43c566b74818ec6325db0978e16c66;hp=5e66f41c146e6cf9615e75ad71ec9951e949643d;hpb=fe489250ce102edf511e99669025934ec9587c63;p=lttng-tools.git diff --git a/src/common/userspace-probe.c b/src/common/userspace-probe.c index 5e66f41c1..67b0ee698 100644 --- a/src/common/userspace-probe.c +++ b/src/common/userspace-probe.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include #include -#include +#include #include +#include #include #include #include @@ -20,14 +23,30 @@ #include static -int lttng_userspace_probe_location_function_set_binary_fd( +int lttng_userspace_probe_location_function_set_binary_fd_handle( struct lttng_userspace_probe_location *location, - struct fd_handle *binary_fd); + struct fd_handle *binary_fd_handle); static -int lttng_userspace_probe_location_tracepoint_set_binary_fd( +int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle( struct lttng_userspace_probe_location *location, - struct fd_handle *binary_fd); + struct fd_handle *binary_fd_handle); + +static +enum lttng_error_code lttng_userspace_probe_location_lookup_method_mi_serialize( + const struct lttng_userspace_probe_location_lookup_method + *method, + struct mi_writer *writer); + +static +enum lttng_error_code lttng_userspace_probe_location_tracepoint_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer); + +static +enum lttng_error_code lttng_userspace_probe_location_function_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer); enum lttng_userspace_probe_location_lookup_method_type lttng_userspace_probe_location_lookup_method_get_type( @@ -105,7 +124,7 @@ void lttng_userspace_probe_location_function_destroy( free(location_function->function_name); free(location_function->binary_path); - fd_handle_put(location_function->binary_fd); + fd_handle_put(location_function->binary_fd_handle); free(location); } @@ -126,7 +145,7 @@ void lttng_userspace_probe_location_tracepoint_destroy( free(location_tracepoint->probe_name); free(location_tracepoint->provider_name); free(location_tracepoint->binary_path); - fd_handle_put(location_tracepoint->binary_fd); + fd_handle_put(location_tracepoint->binary_fd_handle); free(location); } @@ -199,6 +218,25 @@ end: return is_equal; } +static unsigned long lttng_userspace_probe_location_function_hash( + const struct lttng_userspace_probe_location *location) +{ + unsigned long hash = hash_key_ulong( + (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION, + lttng_ht_seed); + struct lttng_userspace_probe_location_function *function_location = + container_of(location, typeof(*function_location), + parent); + + hash ^= hash_key_str(function_location->function_name, lttng_ht_seed); + hash ^= hash_key_str(function_location->binary_path, lttng_ht_seed); + /* + * No need to hash on the fd. Worst comes to worse, + * the equal function will discriminate. + */ + return hash; +} + static bool lttng_userspace_probe_location_function_is_equal( const struct lttng_userspace_probe_location *_a, const struct lttng_userspace_probe_location *_b) @@ -227,8 +265,8 @@ static bool lttng_userspace_probe_location_function_is_equal( goto end; } - is_equal = fd_is_equal(a->binary_fd ? fd_handle_get_fd(a->binary_fd) : -1, - b->binary_fd ? fd_handle_get_fd(b->binary_fd) : -1); + is_equal = fd_is_equal(a->binary_fd_handle ? fd_handle_get_fd(a->binary_fd_handle) : -1, + b->binary_fd_handle ? fd_handle_get_fd(b->binary_fd_handle) : -1); end: return is_equal; } @@ -281,7 +319,7 @@ lttng_userspace_probe_location_function_create_no_check(const char *binary_path, location->function_name = function_name_copy; location->binary_path = binary_path_copy; - location->binary_fd = binary_fd_handle; + location->binary_fd_handle = binary_fd_handle; binary_fd_handle = NULL; location->instrumentation_type = LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY; @@ -290,6 +328,7 @@ lttng_userspace_probe_location_function_create_no_check(const char *binary_path, ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION; ret->equal = lttng_userspace_probe_location_function_is_equal; + ret->hash = lttng_userspace_probe_location_function_hash; goto end; error: @@ -305,6 +344,25 @@ end: return ret; } +static unsigned long lttng_userspace_probe_location_tracepoint_hash( + const struct lttng_userspace_probe_location *location) +{ + unsigned long hash = hash_key_ulong( + (void *) LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT, + lttng_ht_seed); + struct lttng_userspace_probe_location_tracepoint *tp_location = + container_of(location, typeof(*tp_location), parent); + + hash ^= hash_key_str(tp_location->probe_name, lttng_ht_seed); + hash ^= hash_key_str(tp_location->provider_name, lttng_ht_seed); + hash ^= hash_key_str(tp_location->binary_path, lttng_ht_seed); + /* + * No need to hash on the fd. Worst comes to worse, + * the equal function will discriminate. + */ + return hash; +} + static bool lttng_userspace_probe_location_tracepoint_is_equal( const struct lttng_userspace_probe_location *_a, const struct lttng_userspace_probe_location *_b) @@ -335,8 +393,8 @@ static bool lttng_userspace_probe_location_tracepoint_is_equal( goto end; } - is_equal = fd_is_equal(a->binary_fd ? fd_handle_get_fd(a->binary_fd) : -1, - b->binary_fd ? fd_handle_get_fd(b->binary_fd) : -1); + is_equal = fd_is_equal(a->binary_fd_handle ? fd_handle_get_fd(a->binary_fd_handle) : -1, + b->binary_fd_handle ? fd_handle_get_fd(b->binary_fd_handle) : -1); end: return is_equal; @@ -399,13 +457,14 @@ lttng_userspace_probe_location_tracepoint_create_no_check(const char *binary_pat location->probe_name = probe_name_copy; location->provider_name = provider_name_copy; location->binary_path = binary_path_copy; - location->binary_fd = binary_fd_handle; + location->binary_fd_handle = binary_fd_handle; binary_fd_handle = NULL; ret = &location->parent; ret->lookup_method = lookup_method; ret->type = LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT; ret->equal = lttng_userspace_probe_location_tracepoint_is_equal; + ret->hash = lttng_userspace_probe_location_tracepoint_hash; goto end; error: @@ -430,7 +489,7 @@ lttng_userspace_probe_location_function_create(const char *binary_path, struct lttng_userspace_probe_location *ret = NULL; if (!binary_path || !function_name) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -458,7 +517,7 @@ lttng_userspace_probe_location_tracepoint_create(const char *binary_path, struct lttng_userspace_probe_location *ret = NULL; if (!binary_path || !probe_name || !provider_name) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -588,8 +647,8 @@ lttng_userspace_probe_location_function_copy( } /* Set the duplicated fd to the new probe_location */ - if (lttng_userspace_probe_location_function_set_binary_fd(new_location, - function_location->binary_fd) < 0) { + if (lttng_userspace_probe_location_function_set_binary_fd_handle(new_location, + function_location->binary_fd_handle) < 0) { goto destroy_probe_location; } @@ -668,8 +727,8 @@ lttng_userspace_probe_location_tracepoint_copy( } /* Set the duplicated fd to the new probe_location */ - if (lttng_userspace_probe_location_tracepoint_set_binary_fd(new_location, - tracepoint_location->binary_fd) < 0) { + if (lttng_userspace_probe_location_tracepoint_set_binary_fd_handle(new_location, + tracepoint_location->binary_fd_handle) < 0) { goto destroy_probe_location; } @@ -693,7 +752,7 @@ const char *lttng_userspace_probe_location_function_get_binary_path( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -713,7 +772,7 @@ const char *lttng_userspace_probe_location_tracepoint_get_binary_path( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -733,7 +792,7 @@ const char *lttng_userspace_probe_location_function_get_function_name( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -752,7 +811,7 @@ const char *lttng_userspace_probe_location_tracepoint_get_probe_name( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -771,7 +830,7 @@ const char *lttng_userspace_probe_location_tracepoint_get_provider_name( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -790,14 +849,14 @@ int lttng_userspace_probe_location_function_get_binary_fd( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } function_location = container_of(location, struct lttng_userspace_probe_location_function, parent); - ret = function_location->binary_fd ? - fd_handle_get_fd(function_location->binary_fd) : -1; + ret = function_location->binary_fd_handle ? + fd_handle_get_fd(function_location->binary_fd_handle) : -1; end: return ret; } @@ -811,7 +870,7 @@ lttng_userspace_probe_location_function_get_instrumentation_type( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); type = LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_UNKNOWN; goto end; } @@ -836,7 +895,7 @@ lttng_userspace_probe_location_function_set_instrumentation_type( LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION || instrumentation_type != LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); status = LTTNG_USERSPACE_PROBE_LOCATION_STATUS_INVALID; goto end; } @@ -856,14 +915,14 @@ int lttng_userspace_probe_location_tracepoint_get_binary_fd( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } tracepoint_location = container_of(location, struct lttng_userspace_probe_location_tracepoint, parent); - ret = tracepoint_location->binary_fd ? - fd_handle_get_fd(tracepoint_location->binary_fd) : -1; + ret = tracepoint_location->binary_fd_handle ? + fd_handle_get_fd(tracepoint_location->binary_fd_handle) : -1; end: return ret; } @@ -876,7 +935,7 @@ lttng_userspace_probe_location_function_get_lookup_method( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -893,7 +952,7 @@ lttng_userspace_probe_location_tracepoint_get_lookup_method( if (!location || lttng_userspace_probe_location_get_type(location) != LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); goto end; } @@ -970,7 +1029,7 @@ int lttng_userspace_probe_location_function_serialize( goto end; } - if (payload && location_function->binary_fd < 0) { + if (payload && !location_function->binary_fd_handle) { ret = -LTTNG_ERR_INVALID; goto end; } @@ -1012,7 +1071,7 @@ int lttng_userspace_probe_location_function_serialize( goto end; } ret = lttng_payload_push_fd_handle( - payload, location_function->binary_fd); + payload, location_function->binary_fd_handle); if (ret) { ret = -LTTNG_ERR_INVALID; goto end; @@ -1049,7 +1108,7 @@ int lttng_userspace_probe_location_tracepoint_serialize( goto end; } - if (payload && location_tracepoint->binary_fd < 0) { + if (payload && !location_tracepoint->binary_fd_handle) { ret = -LTTNG_ERR_INVALID; goto end; } @@ -1106,7 +1165,7 @@ int lttng_userspace_probe_location_tracepoint_serialize( goto end; } ret = lttng_payload_push_fd_handle( - payload, location_tracepoint->binary_fd); + payload, location_tracepoint->binary_fd_handle); if (ret) { ret = -LTTNG_ERR_INVALID; goto end; @@ -1130,7 +1189,7 @@ int lttng_userspace_probe_location_serialize( struct lttng_userspace_probe_location_comm location_generic_comm; if (!location) { - ERR("Invalid argument(s)"); + ERR("Invalid argument(s) passed to '%s'", __FUNCTION__); ret = -LTTNG_ERR_INVALID; goto end; } @@ -1187,7 +1246,7 @@ int lttng_userspace_probe_location_function_create_from_payload( char *function_name = NULL, *binary_path = NULL; int ret = 0; size_t expected_size; - struct fd_handle *binary_fd = lttng_payload_view_pop_fd_handle(view); + struct fd_handle *binary_fd_handle = lttng_payload_view_pop_fd_handle(view); assert(location); @@ -1212,11 +1271,14 @@ int lttng_userspace_probe_location_function_create_from_payload( binary_path_src = function_name_src + location_function_comm->function_name_len; - if (function_name_src[location_function_comm->function_name_len - 1] != '\0') { + if (!lttng_buffer_view_contains_string(&view->buffer, function_name_src, + location_function_comm->function_name_len)) { ret = -LTTNG_ERR_INVALID; goto end; } - if (binary_path_src[location_function_comm->binary_path_len - 1] != '\0') { + + if (!lttng_buffer_view_contains_string(&view->buffer, binary_path_src, + location_function_comm->binary_path_len)) { ret = -LTTNG_ERR_INVALID; goto end; } @@ -1242,8 +1304,8 @@ int lttng_userspace_probe_location_function_create_from_payload( goto end; } - ret = lttng_userspace_probe_location_function_set_binary_fd( - *location, binary_fd); + ret = lttng_userspace_probe_location_function_set_binary_fd_handle( + *location, binary_fd_handle); if (ret) { ret = -LTTNG_ERR_INVALID; goto end; @@ -1251,7 +1313,7 @@ int lttng_userspace_probe_location_function_create_from_payload( ret = (int) expected_size; end: - fd_handle_put(binary_fd); + fd_handle_put(binary_fd_handle); free(function_name); free(binary_path); return ret; @@ -1267,11 +1329,11 @@ int lttng_userspace_probe_location_tracepoint_create_from_payload( char *probe_name = NULL, *provider_name = NULL, *binary_path = NULL; int ret = 0; size_t expected_size; - struct fd_handle *binary_fd = lttng_payload_view_pop_fd_handle(view); + struct fd_handle *binary_fd_handle = lttng_payload_view_pop_fd_handle(view); assert(location); - if (binary_fd < 0) { + if (!binary_fd_handle) { ret = -LTTNG_ERR_INVALID; goto end; } @@ -1300,17 +1362,20 @@ int lttng_userspace_probe_location_tracepoint_create_from_payload( binary_path_src = provider_name_src + location_tracepoint_comm->provider_name_len; - if (probe_name_src[location_tracepoint_comm->probe_name_len - 1] != '\0') { + if (!lttng_buffer_view_contains_string(&view->buffer, probe_name_src, + location_tracepoint_comm->probe_name_len)) { ret = -LTTNG_ERR_INVALID; goto end; } - if (provider_name_src[location_tracepoint_comm->provider_name_len - 1] != '\0') { + if (!lttng_buffer_view_contains_string(&view->buffer, provider_name_src, + location_tracepoint_comm->provider_name_len)) { ret = -LTTNG_ERR_INVALID; goto end; } - if (binary_path_src[location_tracepoint_comm->binary_path_len - 1] != '\0') { + if (!lttng_buffer_view_contains_string(&view->buffer, binary_path_src, + location_tracepoint_comm->binary_path_len)) { ret = -LTTNG_ERR_INVALID; goto end; } @@ -1339,8 +1404,8 @@ int lttng_userspace_probe_location_tracepoint_create_from_payload( goto end; } - ret = lttng_userspace_probe_location_tracepoint_set_binary_fd( - *location, binary_fd); + ret = lttng_userspace_probe_location_tracepoint_set_binary_fd_handle( + *location, binary_fd_handle); if (ret) { ret = -LTTNG_ERR_INVALID; goto end; @@ -1348,7 +1413,7 @@ int lttng_userspace_probe_location_tracepoint_create_from_payload( ret = (int) expected_size; end: - fd_handle_put(binary_fd); + fd_handle_put(binary_fd_handle); free(probe_name); free(provider_name); free(binary_path); @@ -1411,22 +1476,25 @@ int lttng_userspace_probe_location_create_from_payload( struct lttng_userspace_probe_location **location) { struct lttng_userspace_probe_location_lookup_method *lookup_method; - struct lttng_userspace_probe_location_comm *probe_location_comm; enum lttng_userspace_probe_location_type type; int consumed = 0; int ret; + struct lttng_userspace_probe_location_comm *probe_location_comm; + struct lttng_payload_view probe_location_comm_view = + lttng_payload_view_from_view( + view, 0, sizeof(*probe_location_comm)); assert(view); assert(location); lookup_method = NULL; - 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_userspace_probe_location_type) probe_location_comm->type; consumed += sizeof(*probe_location_comm); @@ -1489,7 +1557,7 @@ end: } static -int lttng_userspace_probe_location_function_set_binary_fd( +int lttng_userspace_probe_location_function_set_binary_fd_handle( struct lttng_userspace_probe_location *location, struct fd_handle *binary_fd) { @@ -1501,14 +1569,14 @@ int lttng_userspace_probe_location_function_set_binary_fd( function_location = container_of(location, struct lttng_userspace_probe_location_function, parent); - fd_handle_put(function_location->binary_fd); + fd_handle_put(function_location->binary_fd_handle); fd_handle_get(binary_fd); - function_location->binary_fd = binary_fd; + function_location->binary_fd_handle = binary_fd; return ret; } static -int lttng_userspace_probe_location_tracepoint_set_binary_fd( +int lttng_userspace_probe_location_tracepoint_set_binary_fd_handle( struct lttng_userspace_probe_location *location, struct fd_handle *binary_fd) { @@ -1520,9 +1588,9 @@ int lttng_userspace_probe_location_tracepoint_set_binary_fd( tracepoint_location = container_of(location, struct lttng_userspace_probe_location_tracepoint, parent); - fd_handle_put(tracepoint_location->binary_fd); + fd_handle_put(tracepoint_location->binary_fd_handle); fd_handle_get(binary_fd); - tracepoint_location->binary_fd = binary_fd; + tracepoint_location->binary_fd_handle = binary_fd; return ret; } @@ -1606,7 +1674,7 @@ int lttng_userspace_probe_location_function_flatten( flat_probe.function_name = flat_probe_start + sizeof(flat_probe); flat_probe.binary_path = flat_probe.function_name + function_name_len; - flat_probe.binary_fd = NULL; + flat_probe.binary_fd_handle = NULL; ret = lttng_dynamic_buffer_append(buffer, &flat_probe, sizeof(flat_probe)); if (ret) { @@ -1741,7 +1809,7 @@ int lttng_userspace_probe_location_tracepoint_flatten( flat_probe.probe_name = flat_probe_start + sizeof(flat_probe); flat_probe.provider_name = flat_probe.probe_name + probe_name_len; flat_probe.binary_path = flat_probe.provider_name + provider_name_len; - flat_probe.binary_fd = NULL; + flat_probe.binary_fd_handle = NULL; ret = lttng_dynamic_buffer_append(buffer, &flat_probe, sizeof(flat_probe)); if (ret) { goto end; @@ -1907,3 +1975,291 @@ bool lttng_userspace_probe_location_is_equal( end: return is_equal; } + +LTTNG_HIDDEN +unsigned long lttng_userspace_probe_location_hash( + const struct lttng_userspace_probe_location *location) +{ + return location->hash(location); +} + +LTTNG_HIDDEN +enum lttng_error_code lttng_userspace_probe_location_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer) +{ + typedef enum lttng_error_code (*mi_fp)( + const struct lttng_userspace_probe_location *, + struct mi_writer *); + + int ret; + enum lttng_error_code ret_code; + mi_fp mi_function = NULL; + + assert(location); + assert(writer); + + switch (lttng_userspace_probe_location_get_type(location)) { + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION: + mi_function = lttng_userspace_probe_location_function_mi_serialize; + break; + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT: + mi_function = lttng_userspace_probe_location_tracepoint_mi_serialize; + break; + default: + abort(); + break; + } + + /* Open userspace probe location element. */ + ret = mi_lttng_writer_open_element( + writer, mi_lttng_element_userspace_probe_location); + if (ret) { + goto mi_error; + } + + /* Underlying user space probe location. */ + ret_code = mi_function(location, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close userspace 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; +} + +enum lttng_error_code lttng_userspace_probe_location_lookup_method_mi_serialize( + const struct lttng_userspace_probe_location_lookup_method + *method, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + const char *type_element_str; + + assert(method); + assert(writer); + + switch (lttng_userspace_probe_location_lookup_method_get_type(method)) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT: + type_element_str = + mi_lttng_element_userspace_probe_location_lookup_method_function_default; + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF: + type_element_str = + mi_lttng_element_userspace_probe_location_lookup_method_function_elf; + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT: + type_element_str = + mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt; + break; + default: + abort(); + break; + } + + /* Open userspace probe location lookup method element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_userspace_probe_location_lookup_method); + if (ret) { + goto mi_error; + } + + /* User space probe location lookup method empty element. */ + ret = mi_lttng_writer_open_element(writer, type_element_str); + if (ret) { + goto mi_error; + } + + /* Close userspace probe location lookup method element. */ + ret = mi_lttng_close_multi_element(writer, 2); + 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_userspace_probe_location_tracepoint_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + const char *probe_name = NULL; + const char *provider_name = NULL; + const char *binary_path = NULL; + const struct lttng_userspace_probe_location_lookup_method + *lookup_method = NULL; + + assert(location); + assert(writer); + + probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name( + location); + provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name( + location); + binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path( + location); + lookup_method = lttng_userspace_probe_location_tracepoint_get_lookup_method( + location); + + /* Open userspace probe location tracepoint element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_userspace_probe_location_tracepoint); + if (ret) { + goto mi_error; + } + + /* Probe name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_tracepoint_probe_name, + probe_name); + if (ret) { + goto mi_error; + } + + /* Provider name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_tracepoint_provider_name, + provider_name); + if (ret) { + goto mi_error; + } + + /* Binary path. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + goto mi_error; + } + + /* The lookup method. */ + ret_code = lttng_userspace_probe_location_lookup_method_mi_serialize( + lookup_method, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close userspace probe location tracepoint. */ + 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_userspace_probe_location_function_mi_serialize( + const struct lttng_userspace_probe_location *location, + struct mi_writer *writer) +{ + int ret; + enum lttng_error_code ret_code; + const char *function_name = NULL; + const char *binary_path = NULL; + const char *instrumentation_type_str = NULL; + enum lttng_userspace_probe_location_function_instrumentation_type + instrumentation_type; + const struct lttng_userspace_probe_location_lookup_method + *lookup_method = NULL; + + assert(location); + assert(writer); + + function_name = lttng_userspace_probe_location_function_get_function_name( + location); + binary_path = lttng_userspace_probe_location_function_get_binary_path( + location); + instrumentation_type = + lttng_userspace_probe_location_function_get_instrumentation_type( + location); + lookup_method = lttng_userspace_probe_location_function_get_lookup_method( + location); + + switch (instrumentation_type) { + case LTTNG_USERSPACE_PROBE_LOCATION_FUNCTION_INSTRUMENTATION_TYPE_ENTRY: + instrumentation_type_str = + mi_lttng_userspace_probe_location_function_instrumentation_type_entry; + break; + default: + abort(); + break; + } + + /* Open userspace probe location function element. */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_userspace_probe_location_function); + if (ret) { + goto mi_error; + } + + /* Function name. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_function_name, + function_name); + if (ret) { + goto mi_error; + } + + /* Binary path. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + goto mi_error; + } + + /* Instrumentation type. */ + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_userspace_probe_location_function_instrumentation_type, + instrumentation_type_str); + if (ret) { + goto mi_error; + } + + /* The lookup method. */ + ret_code = lttng_userspace_probe_location_lookup_method_mi_serialize( + lookup_method, writer); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Close userspace probe location function 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; +}