+int lttng_syscalls_register_trigger(struct lttng_trigger_enabler *trigger_enabler, void *filter)
+{
+ struct lttng_trigger_group *group = trigger_enabler->group;
+ unsigned int i;
+ int ret = 0;
+
+ wrapper_vmalloc_sync_all();
+
+ if (!group->trigger_syscall_dispatch) {
+ group->trigger_syscall_dispatch = kzalloc(sizeof(struct list_head)
+ * ARRAY_SIZE(sc_table), GFP_KERNEL);
+ if (!group->trigger_syscall_dispatch)
+ return -ENOMEM;
+
+ /* Initialize all list_head */
+ for (i = 0; i < ARRAY_SIZE(sc_table); i++)
+ INIT_LIST_HEAD(&group->trigger_syscall_dispatch[i]);
+ }
+
+#ifdef CONFIG_COMPAT
+ if (!group->trigger_compat_syscall_dispatch) {
+ group->trigger_compat_syscall_dispatch = kzalloc(sizeof(struct list_head)
+ * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
+ if (!group->trigger_syscall_dispatch)
+ return -ENOMEM;
+
+ /* Initialize all list_head */
+ for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++)
+ INIT_LIST_HEAD(&group->trigger_compat_syscall_dispatch[i]);
+ }
+#endif
+
+ if (!group->sys_enter_registered) {
+ ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
+ (void *) syscall_entry_trigger_probe, group);
+ if (ret)
+ return ret;
+ group->sys_enter_registered = 1;
+ }
+
+ return ret;
+}
+
+static int create_matching_triggers(struct lttng_trigger_enabler *trigger_enabler,
+ void *filter, const struct trace_syscall_entry *table,
+ size_t table_len, bool is_compat)
+{
+ struct lttng_trigger_group *group = trigger_enabler->group;
+ const struct lttng_event_desc *desc;
+ uint64_t id = trigger_enabler->id;
+ unsigned int i;
+ int ret = 0;
+
+ /* iterate over all syscall and create trigger that match */
+ for (i = 0; i < table_len; i++) {
+ struct lttng_trigger *trigger;
+ struct lttng_kernel_trigger trigger_param;
+ struct hlist_head *head;
+ int found = 0;
+
+ desc = table[i].desc;
+ if (!desc) {
+ /* Unknown syscall */
+ continue;
+ }
+
+ if (!lttng_desc_match_enabler(desc,
+ lttng_trigger_enabler_as_enabler(trigger_enabler)))
+ continue;
+
+ /*
+ * Check if already created.
+ */
+ head = utils_borrow_hash_table_bucket(group->triggers_ht.table,
+ LTTNG_TRIGGER_HT_SIZE, desc->name);
+ lttng_hlist_for_each_entry(trigger, head, hlist) {
+ if (trigger->desc == desc
+ && trigger->id == trigger_enabler->id)
+ found = 1;
+ }
+ if (found)
+ continue;
+
+ memset(&trigger_param, 0, sizeof(trigger_param));
+ strncat(trigger_param.name, desc->name,
+ LTTNG_KERNEL_SYM_NAME_LEN - strlen(trigger_param.name) - 1);
+ trigger_param.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
+ trigger_param.instrumentation = LTTNG_KERNEL_SYSCALL;
+
+ trigger = _lttng_trigger_create(desc, id, group,
+ &trigger_param, filter, trigger_param.instrumentation);
+ if (IS_ERR(trigger)) {
+ printk(KERN_INFO "Unable to create trigger %s\n",
+ desc->name);
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ trigger->u.syscall.syscall_id = i;
+ trigger->u.syscall.is_compat = is_compat;
+ }
+end:
+ return ret;
+
+}
+
+int lttng_syscals_create_matching_triggers(struct lttng_trigger_enabler *trigger_enabler, void *filter)
+{
+ int ret;
+
+ ret = create_matching_triggers(trigger_enabler, filter, sc_table,
+ ARRAY_SIZE(sc_table), false);
+ if (ret)
+ goto end;
+
+ ret = create_matching_triggers(trigger_enabler, filter, compat_sc_table,
+ ARRAY_SIZE(compat_sc_table), true);
+end:
+ return ret;
+}
+
+/*
+ * TODO
+ */
+int lttng_syscalls_unregister_trigger(struct lttng_trigger_group *trigger_group)
+{
+ int ret;
+
+ if (trigger_group->sys_enter_registered) {
+ ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
+ (void *) syscall_entry_trigger_probe, trigger_group);
+ if (ret)
+ return ret;
+ trigger_group->sys_enter_registered = 0;
+ }
+
+ kfree(trigger_group->trigger_syscall_dispatch);
+#ifdef CONFIG_COMPAT
+ kfree(trigger_group->trigger_compat_syscall_dispatch);
+#endif
+ return 0;
+}
+
+int lttng_syscalls_unregister_event(struct lttng_channel *chan)