X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-syscalls.c;h=e8b72573a42131c95b56e4952a11710e5d2e7957;hb=736f2dd654af78b4bce81cf8ba9579370a162a38;hp=d618bd33ae02474338608cc429dcb06dd461c004;hpb=7f52f0d4228ee23b783e907258835d2f818350d7;p=lttng-modules.git diff --git a/src/lttng-syscalls.c b/src/lttng-syscalls.c index d618bd33..e8b72573 100644 --- a/src/lttng-syscalls.c +++ b/src/lttng-syscalls.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -535,8 +536,7 @@ struct lttng_kernel_syscall_table *get_syscall_table_from_event(struct lttng_ker static void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common *syscall_event_enabler, - const struct lttng_kernel_event_desc *desc, struct hlist_head *dispatch_table, - enum sc_type type, unsigned int syscall_nr) + const struct lttng_kernel_event_desc *desc, enum sc_type type, unsigned int syscall_nr) { struct lttng_kernel_event_common *event; @@ -584,8 +584,6 @@ void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common return; } event->priv->u.syscall.syscall_id = syscall_nr; - if (dispatch_table) - hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_table); break; } case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER: @@ -634,8 +632,6 @@ void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common return; } event->priv->u.syscall.syscall_id = syscall_nr; - if (dispatch_table) - hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_table); break; } default: @@ -683,7 +679,7 @@ void lttng_syscall_event_enabler_create_matching_syscall_table_events(struct ltt if (found) continue; - lttng_syscall_event_enabler_create_event(syscall_event_enabler_common, desc, NULL, type, i); + lttng_syscall_event_enabler_create_event(syscall_event_enabler_common, desc, type, i); } } @@ -704,11 +700,9 @@ bool lttng_syscall_event_enabler_is_wildcard_all(struct lttng_event_enabler_comm static void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type) { - struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(event_enabler); struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(event_enabler); struct lttng_kernel_event_common_private *event_priv; const struct lttng_kernel_event_desc *desc; - struct hlist_head *unknown_dispatch_list; bool found = false; struct hlist_head *head; @@ -731,19 +725,15 @@ void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabl switch (type) { case SC_TYPE_ENTRY: desc = &__event_desc___syscall_entry_unknown; - unknown_dispatch_list = &syscall_table->unknown_syscall_dispatch; break; case SC_TYPE_EXIT: desc = &__event_desc___syscall_exit_unknown; - unknown_dispatch_list = &syscall_table->unknown_syscall_exit_dispatch; break; case SC_TYPE_COMPAT_ENTRY: desc = &__event_desc___compat_syscall_entry_unknown; - unknown_dispatch_list = &syscall_table->compat_unknown_syscall_dispatch; break; case SC_TYPE_COMPAT_EXIT: desc = &__event_desc___compat_syscall_exit_unknown; - unknown_dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch; break; default: WARN_ON_ONCE(1); @@ -760,7 +750,7 @@ void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabl } } if (!found) - lttng_syscall_event_enabler_create_event(event_enabler, desc, unknown_dispatch_list, type, -1U); + lttng_syscall_event_enabler_create_event(event_enabler, desc, type, -1U); } static @@ -850,7 +840,7 @@ int lttng_event_enabler_create_syscall_events_if_missing(struct lttng_event_enab lttng_syscall_event_enabler_create_matching_events(syscall_event_enabler); - return ret; + return 0; } int lttng_syscalls_unregister_syscall_table(struct lttng_kernel_syscall_table *syscall_table) @@ -888,52 +878,6 @@ int lttng_syscalls_destroy_syscall_table(struct lttng_kernel_syscall_table *sysc return 0; } -static -int get_syscall_nr(const char *syscall_name) -{ - int syscall_nr = -1; - int i; - - for (i = 0; i < sc_table.len; i++) { - const struct trace_syscall_entry *entry; - const char *it_name; - - entry = &sc_table.table[i]; - if (!entry->desc) - continue; - it_name = entry->desc->event_name; - it_name += strlen(SYSCALL_ENTRY_STR); - if (!strcmp(syscall_name, it_name)) { - syscall_nr = i; - break; - } - } - return syscall_nr; -} - -static -int get_compat_syscall_nr(const char *syscall_name) -{ - int syscall_nr = -1; - int i; - - for (i = 0; i < compat_sc_table.len; i++) { - const struct trace_syscall_entry *entry; - const char *it_name; - - entry = &compat_sc_table.table[i]; - if (!entry->desc) - continue; - it_name = entry->desc->event_name; - it_name += strlen(COMPAT_SYSCALL_ENTRY_STR); - if (!strcmp(syscall_name, it_name)) { - syscall_nr = i; - break; - } - } - return syscall_nr; -} - static uint32_t get_sc_tables_len(void) { @@ -978,28 +922,15 @@ static int lttng_syscall_filter_enable( struct lttng_syscall_filter *filter, const char *desc_name, enum lttng_syscall_abi abi, - enum lttng_syscall_entryexit entryexit) + enum lttng_syscall_entryexit entryexit, + unsigned int syscall_id) { const char *syscall_name; unsigned long *bitmap; u32 *refcount_map; - int syscall_nr; syscall_name = get_syscall_name(desc_name, abi, entryexit); - switch (abi) { - case LTTNG_SYSCALL_ABI_NATIVE: - syscall_nr = get_syscall_nr(syscall_name); - break; - case LTTNG_SYSCALL_ABI_COMPAT: - syscall_nr = get_compat_syscall_nr(syscall_name); - break; - default: - return -EINVAL; - } - if (syscall_nr < 0) - return -ENOENT; - switch (entryexit) { case LTTNG_SYSCALL_ENTRY: switch (abi) { @@ -1032,10 +963,10 @@ int lttng_syscall_filter_enable( default: return -EINVAL; } - if (refcount_map[syscall_nr] == U32_MAX) + if (refcount_map[syscall_id] == U32_MAX) return -EOVERFLOW; - if (refcount_map[syscall_nr]++ == 0) - bitmap_set(bitmap, syscall_nr, 1); + if (refcount_map[syscall_id]++ == 0) + bitmap_set(bitmap, syscall_id, 1); return 0; } @@ -1044,50 +975,81 @@ int lttng_syscall_filter_enable_event(struct lttng_kernel_event_common *event) struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event); unsigned int syscall_id = event->priv->u.syscall.syscall_id; struct hlist_head *dispatch_list; - int ret; + int ret = 0; WARN_ON_ONCE(event->priv->instrumentation != LTTNG_KERNEL_ABI_SYSCALL); - /* Skip unknown syscall */ - if (syscall_id == -1U) - return 0; - - ret = lttng_syscall_filter_enable(syscall_table->sc_filter, - event->priv->desc->event_name, event->priv->u.syscall.abi, - event->priv->u.syscall.entryexit); - if (ret) - return ret; - - switch (event->priv->u.syscall.entryexit) { - case LTTNG_SYSCALL_ENTRY: - switch (event->priv->u.syscall.abi) { - case LTTNG_SYSCALL_ABI_NATIVE: - dispatch_list = &syscall_table->syscall_dispatch[syscall_id]; + /* Unknown syscall */ + if (syscall_id == -1U) { + switch (event->priv->u.syscall.entryexit) { + case LTTNG_SYSCALL_ENTRY: + switch (event->priv->u.syscall.abi) { + case LTTNG_SYSCALL_ABI_NATIVE: + dispatch_list = &syscall_table->unknown_syscall_dispatch; + break; + case LTTNG_SYSCALL_ABI_COMPAT: + dispatch_list = &syscall_table->compat_unknown_syscall_dispatch; + break; + default: + ret = -EINVAL; + goto end; + } break; - case LTTNG_SYSCALL_ABI_COMPAT: - dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id]; + case LTTNG_SYSCALL_EXIT: + switch (event->priv->u.syscall.abi) { + case LTTNG_SYSCALL_ABI_NATIVE: + dispatch_list = &syscall_table->unknown_syscall_exit_dispatch; + break; + case LTTNG_SYSCALL_ABI_COMPAT: + dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch; + break; + default: + ret = -EINVAL; + goto end; + } break; default: ret = -EINVAL; goto end; } - break; - case LTTNG_SYSCALL_EXIT: - switch (event->priv->u.syscall.abi) { - case LTTNG_SYSCALL_ABI_NATIVE: - dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id]; + } else { + ret = lttng_syscall_filter_enable(syscall_table->sc_filter, + event->priv->desc->event_name, event->priv->u.syscall.abi, + event->priv->u.syscall.entryexit, syscall_id); + if (ret) + return ret; + + switch (event->priv->u.syscall.entryexit) { + case LTTNG_SYSCALL_ENTRY: + switch (event->priv->u.syscall.abi) { + case LTTNG_SYSCALL_ABI_NATIVE: + dispatch_list = &syscall_table->syscall_dispatch[syscall_id]; + break; + case LTTNG_SYSCALL_ABI_COMPAT: + dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id]; + break; + default: + ret = -EINVAL; + goto end; + } break; - case LTTNG_SYSCALL_ABI_COMPAT: - dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id]; + case LTTNG_SYSCALL_EXIT: + switch (event->priv->u.syscall.abi) { + case LTTNG_SYSCALL_ABI_NATIVE: + dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id]; + break; + case LTTNG_SYSCALL_ABI_COMPAT: + dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id]; + break; + default: + ret = -EINVAL; + goto end; + } break; default: ret = -EINVAL; goto end; } - break; - default: - ret = -EINVAL; - goto end; } hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_list); @@ -1098,28 +1060,15 @@ end: static int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter, const char *desc_name, enum lttng_syscall_abi abi, - enum lttng_syscall_entryexit entryexit) + enum lttng_syscall_entryexit entryexit, + unsigned int syscall_id) { const char *syscall_name; unsigned long *bitmap; u32 *refcount_map; - int syscall_nr; syscall_name = get_syscall_name(desc_name, abi, entryexit); - switch (abi) { - case LTTNG_SYSCALL_ABI_NATIVE: - syscall_nr = get_syscall_nr(syscall_name); - break; - case LTTNG_SYSCALL_ABI_COMPAT: - syscall_nr = get_compat_syscall_nr(syscall_name); - break; - default: - return -EINVAL; - } - if (syscall_nr < 0) - return -ENOENT; - switch (entryexit) { case LTTNG_SYSCALL_ENTRY: switch (abi) { @@ -1152,10 +1101,10 @@ int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter, default: return -EINVAL; } - if (refcount_map[syscall_nr] == 0) + if (refcount_map[syscall_id] == 0) return -ENOENT; - if (--refcount_map[syscall_nr] == 0) - bitmap_clear(bitmap, syscall_nr, 1); + if (--refcount_map[syscall_id] == 0) + bitmap_clear(bitmap, syscall_id, 1); return 0; } @@ -1165,15 +1114,14 @@ int lttng_syscall_filter_disable_event(struct lttng_kernel_event_common *event) unsigned int syscall_id = event->priv->u.syscall.syscall_id; int ret; - /* Skip unknown syscall */ - if (syscall_id == -1U) - return 0; - - ret = lttng_syscall_filter_disable(syscall_table->sc_filter, - event->priv->desc->event_name, event->priv->u.syscall.abi, - event->priv->u.syscall.entryexit); - if (ret) - return ret; + /* Except for unknown syscall */ + if (syscall_id != -1U) { + ret = lttng_syscall_filter_disable(syscall_table->sc_filter, + event->priv->desc->event_name, event->priv->u.syscall.abi, + event->priv->u.syscall.entryexit, syscall_id); + if (ret) + return ret; + } hlist_del_rcu(&event->priv->u.syscall.node); return 0; }