#include <common/macros.h>
#include <common/payload.h>
#include <common/payload-view.h>
+#include <common/hashtable/hashtable.h>
+#include <common/hashtable/utils.h>
#include <fcntl.h>
#include <lttng/constant.h>
#include <lttng/userspace-probe-internal.h>
#include <sys/unistd.h>
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);
enum lttng_userspace_probe_location_lookup_method_type
lttng_userspace_probe_location_lookup_method_get_type(
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);
}
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);
}
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)
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;
}
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;
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:
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)
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;
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:
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;
}
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;
}
}
/* 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;
}
}
/* 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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
goto end;
}
- if (payload && location_function->binary_fd < 0) {
+ if (payload && !location_function->binary_fd_handle) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
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;
goto end;
}
- if (payload && location_tracepoint->binary_fd < 0) {
+ if (payload && !location_tracepoint->binary_fd_handle) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
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;
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;
}
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);
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;
}
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;
ret = (int) expected_size;
end:
- fd_handle_put(binary_fd);
+ fd_handle_put(binary_fd_handle);
free(function_name);
free(binary_path);
return ret;
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;
}
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;
}
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;
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);
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);
}
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)
{
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)
{
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;
}
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) {
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;
end:
return is_equal;
}
+
+LTTNG_HIDDEN
+unsigned long lttng_userspace_probe_location_hash(
+ const struct lttng_userspace_probe_location *location)
+{
+ return location->hash(location);
+}