Fix: userspace probe accessors are not const-correct
[lttng-tools.git] / src / bin / lttng-sessiond / trace-kernel.c
index ef5abbab4c3b20fe8d39165012e27b756234a43e..b9d03a72e002ca0042764a877f0ae556e87f1faa 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#include <lttng/event.h>
+#include <lttng/lttng-error.h>
+#include <lttng/userspace-probe.h>
+#include <lttng/userspace-probe-internal.h>
+
 #include <common/common.h>
 #include <common/defaults.h>
 
@@ -292,18 +297,23 @@ error:
  *
  * Return pointer to structure or NULL.
  */
-struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev,
-               char *filter_expression, struct lttng_filter_bytecode *filter)
+enum lttng_error_code trace_kernel_create_event(
+               struct lttng_event *ev, char *filter_expression,
+               struct lttng_filter_bytecode *filter,
+               struct ltt_kernel_event **kernel_event)
 {
-       struct ltt_kernel_event *lke;
+       enum lttng_error_code ret;
        struct lttng_kernel_event *attr;
+       struct ltt_kernel_event *local_kernel_event;
+       struct lttng_userspace_probe_location *userspace_probe_location = NULL;
 
        assert(ev);
 
-       lke = zmalloc(sizeof(struct ltt_kernel_event));
+       local_kernel_event = zmalloc(sizeof(struct ltt_kernel_event));
        attr = zmalloc(sizeof(struct lttng_kernel_event));
-       if (lke == NULL || attr == NULL) {
+       if (local_kernel_event == NULL || attr == NULL) {
                PERROR("kernel event zmalloc");
+               ret = LTTNG_ERR_NOMEM;
                goto error;
        }
 
@@ -316,6 +326,84 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev,
                                ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN);
                attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
                break;
+       case LTTNG_EVENT_USERSPACE_PROBE:
+       {
+               const struct lttng_userspace_probe_location* location = NULL;
+               const struct lttng_userspace_probe_location_lookup_method *lookup = NULL;
+
+               location = lttng_event_get_userspace_probe_location(ev);
+               if (!location) {
+                       ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
+                       goto error;
+               }
+
+               /*
+                * From this point on, the specific term 'uprobe' is used
+                * instead of the generic 'userspace probe' because it's the
+                * technology used at the moment for this instrumentation.
+                * LTTng currently implements userspace probes using uprobes.
+                * In the interactions with the kernel tracer, we use the
+                * uprobe term.
+                */
+               attr->instrumentation = LTTNG_KERNEL_UPROBE;
+
+               /*
+                * Only the elf lookup method is supported at the moment.
+                */
+               lookup = lttng_userspace_probe_location_get_lookup_method(
+                               location);
+               if (!lookup) {
+                       ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
+                       goto error;
+               }
+
+               /*
+                * From the kernel tracer's perspective, all userspace probe
+                * event types are all the same: a file and an offset.
+                */
+               switch (lttng_userspace_probe_location_lookup_method_get_type(lookup)) {
+               case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
+                       /* Get the file descriptor on the target binary. */
+                       attr->u.uprobe.fd =
+                                       lttng_userspace_probe_location_function_get_binary_fd(location);
+
+                       /*
+                        * Save a reference to the probe location used during
+                        * the listing of events. Close its FD since it won't
+                        * be needed for listing.
+                        */
+                       userspace_probe_location =
+                                       lttng_userspace_probe_location_copy(location);
+                       ret = lttng_userspace_probe_location_function_set_binary_fd(
+                                       userspace_probe_location, -1);
+                       if (ret) {
+                               goto error;
+                       }
+                       break;
+               case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
+                       /* Get the file descriptor on the target binary. */
+                       attr->u.uprobe.fd =
+                                       lttng_userspace_probe_location_tracepoint_get_binary_fd(location);
+
+                       /*
+                        * Save a reference to the probe location used during the listing of
+                        * events. Close its FD since it won't be needed for listing.
+                        */
+                       userspace_probe_location =
+                                       lttng_userspace_probe_location_copy(location);
+                       ret = lttng_userspace_probe_location_tracepoint_set_binary_fd(
+                                       userspace_probe_location, -1);
+                       if (ret) {
+                               goto error;
+                       }
+                       break;
+               default:
+                       DBG("Unsupported lookup method type");
+                       ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
+                       goto error;
+               }
+               break;
+       }
        case LTTNG_EVENT_FUNCTION:
                attr->instrumentation = LTTNG_KERNEL_KRETPROBE;
                attr->u.kretprobe.addr = ev->attr.probe.addr;
@@ -341,6 +429,7 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev,
                break;
        default:
                ERR("Unknown kernel instrumentation type (%d)", ev->type);
+               ret = LTTNG_ERR_INVALID;
                goto error;
        }
 
@@ -349,20 +438,23 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev,
        attr->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
 
        /* Setting up a kernel event */
-       lke->fd = -1;
-       lke->event = attr;
-       lke->enabled = 1;
-       lke->filter_expression = filter_expression;
-       lke->filter = filter;
+       local_kernel_event->fd = -1;
+       local_kernel_event->event = attr;
+       local_kernel_event->enabled = 1;
+       local_kernel_event->filter_expression = filter_expression;
+       local_kernel_event->filter = filter;
+       local_kernel_event->userspace_probe_location = userspace_probe_location;
+
+       *kernel_event = local_kernel_event;
 
-       return lke;
+       return LTTNG_OK;
 
 error:
        free(filter_expression);
        free(filter);
-       free(lke);
+       free(local_kernel_event);
        free(attr);
-       return NULL;
+       return ret;
 }
 
 /*
This page took 0.025227 seconds and 4 git commands to generate.