/*
* lttng-syscalls.c
*
- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright 2010-2011 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * LTTng sched probes.
+ * LTTng syscall probes.
*
* Dual LGPL v2.1/GPL v2 license.
*/
}
#endif
-static void syscall_entry_probe(void *__data, struct pt_regs *regs, long id);
+static
+void syscall_entry_probe(void *__data, struct pt_regs *regs, long id);
/*
* Take care of NOARGS not supported by mainline.
#define TP_MODULE_OVERRIDE
#define TRACE_INCLUDE_PATH ../instrumentation/syscalls/headers
+#define PARAMS(args...) args
+
/* Hijack probe callback for system calls */
+#undef TP_PROBE_CB
#define TP_PROBE_CB(_template) &syscall_entry_probe
+#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \
+ TRACE_EVENT(_name, PARAMS(_proto), PARAMS(_args),\
+ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk))
+#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \
+ DECLARE_EVENT_CLASS_NOARGS(_name, PARAMS(_struct), PARAMS(_assign),\
+ PARAMS(_printk))
+#define SC_DEFINE_EVENT_NOARGS(_template, _name) \
+ DEFINE_EVENT_NOARGS(_template, _name)
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM syscalls_integers
#include "instrumentation/syscalls/headers/syscalls_integers.h"
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM syscalls_pointers
#include "instrumentation/syscalls/headers/syscalls_pointers.h"
-#undef TP_PROBE_CB
+#undef TRACE_SYSTEM
+#undef SC_TRACE_EVENT
+#undef SC_DECLARE_EVENT_CLASS_NOARGS
+#undef SC_DEFINE_EVENT_NOARGS
+#define TRACE_SYSTEM syscalls_unknown
#include "instrumentation/syscalls/headers/syscalls_unknown.h"
+#undef TRACE_SYSTEM
+
+/* For compat syscalls */
+#undef _TRACE_SYSCALLS_integers_H
+#undef _TRACE_SYSCALLS_pointers_H
+
+/* Hijack probe callback for system calls */
+#undef TP_PROBE_CB
+#define TP_PROBE_CB(_template) &syscall_entry_probe
+#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \
+ TRACE_EVENT(compat_##_name, PARAMS(_proto), PARAMS(_args), \
+ PARAMS(_struct), PARAMS(_assign), \
+ PARAMS(_printk))
+#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \
+ DECLARE_EVENT_CLASS_NOARGS(compat_##_name, PARAMS(_struct), \
+ PARAMS(_assign), PARAMS(_printk))
+#define SC_DEFINE_EVENT_NOARGS(_template, _name) \
+ DEFINE_EVENT_NOARGS(compat_##_template, compat_##_name)
+#define TRACE_SYSTEM compat_syscalls_integers
+#include "instrumentation/syscalls/headers/compat_syscalls_integers.h"
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM compat_syscalls_pointers
+#include "instrumentation/syscalls/headers/compat_syscalls_pointers.h"
+#undef TRACE_SYSTEM
+#undef SC_TRACE_EVENT
+#undef SC_DECLARE_EVENT_CLASS_NOARGS
+#undef SC_DEFINE_EVENT_NOARGS
+#undef TP_PROBE_CB
#undef TP_MODULE_OVERRIDE
#undef LTTNG_PACKAGE_BUILD
unsigned int nrargs;
};
+#define CREATE_SYSCALL_TABLE
+
#undef TRACE_SYSCALL_TABLE
#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
[ _nr ] = { \
.desc = &__event_desc___##_name, \
},
-#define CREATE_SYSCALL_TABLE
-
static const struct trace_syscall_entry sc_table[] = {
#include "instrumentation/syscalls/headers/syscalls_integers.h"
#include "instrumentation/syscalls/headers/syscalls_pointers.h"
};
+#undef TRACE_SYSCALL_TABLE
+#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
+ [ _nr ] = { \
+ .func = __event_probe__##compat_##_template, \
+ .nrargs = (_nrargs), \
+ .fields = __event_fields___##compat_##_template,\
+ .desc = &__event_desc___##compat_##_name, \
+ },
+
/* Create compatibility syscall table */
-static const struct trace_syscall_entry compat_sc_table[] = {
+const struct trace_syscall_entry compat_sc_table[] = {
#include "instrumentation/syscalls/headers/compat_syscalls_integers.h"
#include "instrumentation/syscalls/headers/compat_syscalls_pointers.h"
};
unsigned long args[UNKNOWN_SYSCALL_NRARGS];
syscall_get_arguments(current, regs, 0, UNKNOWN_SYSCALL_NRARGS, args);
- __event_probe__sys_unknown(event, id, args);
+ if (unlikely(is_compat_task()))
+ __event_probe__compat_sys_unknown(event, id, args);
+ else
+ __event_probe__sys_unknown(event, id, args);
}
-/*
- * Currently, given that the kernel syscall metadata extraction only
- * considers native system calls (not 32-bit compability ones), we
- * fall-back on the "unknown" system call tracing for 32-bit compat.
- */
-static void syscall_entry_probe(void *__data, struct pt_regs *regs, long id)
+void syscall_entry_probe(void *__data, struct pt_regs *regs, long id)
{
struct ltt_channel *chan = __data;
struct ltt_event *event, *unknown_event;
}
}
+/* noinline to diminish caller stack size */
static
int fill_table(const struct trace_syscall_entry *table, size_t table_len,
struct ltt_event **chan_table, struct ltt_channel *chan, void *filter)
{
+ const struct lttng_event_desc *desc;
unsigned int i;
/* Allocate events for each syscall, insert into table */
for (i = 0; i < table_len; i++) {
struct lttng_kernel_event ev;
- const struct lttng_event_desc *desc = table[i].desc;
+ desc = table[i].desc;
if (!desc) {
/* Unknown syscall */
int lttng_syscalls_register(struct ltt_channel *chan, void *filter)
{
+ struct lttng_kernel_event ev;
int ret;
wrapper_vmalloc_sync_all();
}
#endif
if (!chan->sc_unknown) {
- struct lttng_kernel_event ev;
const struct lttng_event_desc *desc =
&__event_desc___sys_unknown;
}
if (!chan->sc_compat_unknown) {
- struct lttng_kernel_event ev;
const struct lttng_event_desc *desc =
&__event_desc___compat_sys_unknown;
}
if (!chan->sc_exit) {
- struct lttng_kernel_event ev;
const struct lttng_event_desc *desc =
&__event_desc___exit_syscall;