From 2d2464bd8910c4c8a090675338159f6642c83f41 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 12 Sep 2014 14:12:43 -0400 Subject: [PATCH] Implement syscall listing Signed-off-by: Mathieu Desnoyers --- lttng-abi.c | 39 ++++++++++++++++++++++ lttng-abi.h | 1 + lttng-events.h | 1 + lttng-syscalls.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) diff --git a/lttng-abi.c b/lttng-abi.c index 6dc59aed..ab0a1128 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -143,6 +143,43 @@ fd_error: return ret; } +static +int lttng_abi_syscall_list(void) +{ + struct file *syscall_list_file; + int file_fd, ret; + + file_fd = get_unused_fd(); + if (file_fd < 0) { + ret = file_fd; + goto fd_error; + } + + syscall_list_file = anon_inode_getfile("[lttng_syscall_list]", + <tng_syscall_list_fops, + NULL, O_RDWR); + if (IS_ERR(syscall_list_file)) { + ret = PTR_ERR(syscall_list_file); + goto file_error; + } + ret = lttng_syscall_list_fops.open(NULL, syscall_list_file); + if (ret < 0) + goto open_error; + fd_install(file_fd, syscall_list_file); + if (file_fd < 0) { + ret = file_fd; + goto fd_error; + } + return file_fd; + +open_error: + fput(syscall_list_file); +file_error: + put_unused_fd(file_fd); +fd_error: + return ret; +} + static void lttng_abi_tracer_version(struct lttng_kernel_tracer_version *v) { @@ -249,6 +286,8 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LTTNG_KERNEL_OLD_TRACEPOINT_LIST: case LTTNG_KERNEL_TRACEPOINT_LIST: return lttng_abi_tracepoint_list(); + case LTTNG_KERNEL_SYSCALL_LIST: + return lttng_abi_syscall_list(); case LTTNG_KERNEL_OLD_WAIT_QUIESCENT: case LTTNG_KERNEL_WAIT_QUIESCENT: synchronize_trace(); diff --git a/lttng-abi.h b/lttng-abi.h index b626b88e..27943579 100644 --- a/lttng-abi.h +++ b/lttng-abi.h @@ -157,6 +157,7 @@ struct lttng_kernel_context { #define LTTNG_KERNEL_WAIT_QUIESCENT _IO(0xF6, 0x48) #define LTTNG_KERNEL_CALIBRATE \ _IOWR(0xF6, 0x49, struct lttng_kernel_calibrate) +#define LTTNG_KERNEL_SYSCALL_LIST _IO(0xF6, 0x49) /* Session FD ioctl */ #define LTTNG_KERNEL_METADATA \ diff --git a/lttng-events.h b/lttng-events.h index cf5acafa..92a61789 100644 --- a/lttng-events.h +++ b/lttng-events.h @@ -556,6 +556,7 @@ void lttng_ftrace_destroy_private(struct lttng_event *event) int lttng_calibrate(struct lttng_kernel_calibrate *calibrate); extern const struct file_operations lttng_tracepoint_list_fops; +extern const struct file_operations lttng_syscall_list_fops; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) #define TRACEPOINT_HAS_DATA_ARG diff --git a/lttng-syscalls.c b/lttng-syscalls.c index c23f1d9e..25b8431a 100644 --- a/lttng-syscalls.c +++ b/lttng-syscalls.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1070,3 +1071,86 @@ error: kfree(filter); return ret; } + +static +const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos) +{ + const struct trace_syscall_entry *entry; + int iter = 0; + + for (entry = sc_table; + entry < sc_table + ARRAY_SIZE(sc_table); + entry++) { + if (iter++ >= *pos) + return entry; + } + for (entry = compat_sc_table; + entry < compat_sc_table + ARRAY_SIZE(compat_sc_table); + entry++) { + if (iter++ >= *pos) + return entry; + } + /* End of list */ + return NULL; +} + +static +void *syscall_list_start(struct seq_file *m, loff_t *pos) +{ + return (void *) syscall_list_get_entry(pos); +} + +static +void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos) +{ + (*ppos)++; + return (void *) syscall_list_get_entry(ppos); +} + +static +void syscall_list_stop(struct seq_file *m, void *p) +{ +} + +static +int syscall_list_show(struct seq_file *m, void *p) +{ + const struct trace_syscall_entry *table, *entry = p; + unsigned int bitness; + + if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) { + bitness = BITS_PER_LONG; + table = sc_table; + } else { + bitness = 32; + table = compat_sc_table; + WARN_ON_ONCE(!(entry >= compat_sc_table + && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))); + } + seq_printf(m, "syscall { name = %s; bitness = %u; };\n", + entry->desc->name, + bitness); + return 0; +} + +static +const struct seq_operations lttng_syscall_list_seq_ops = { + .start = syscall_list_start, + .next = syscall_list_next, + .stop = syscall_list_stop, + .show = syscall_list_show, +}; + +static +int lttng_syscall_list_open(struct inode *inode, struct file *file) +{ + return seq_open(file, <tng_syscall_list_seq_ops); +} + +const struct file_operations lttng_syscall_list_fops = { + .owner = THIS_MODULE, + .open = lttng_syscall_list_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; -- 2.34.1