),
TP_printk()
)
+TRACE_EVENT(compat_sys_unknown,
+ TP_PROTO(unsigned int id, unsigned long *args),
+ TP_ARGS(id, args),
+ TP_STRUCT__entry(
+ __field(unsigned int, id)
+ __array(unsigned long, args, UNKNOWN_SYSCALL_NRARGS)
+ ),
+ TP_fast_assign(
+ tp_assign(id, id)
+ tp_memcpy(args, args, UNKNOWN_SYSCALL_NRARGS * sizeof(*args))
+ ),
+ TP_printk()
+)
/*
* This is going to hook on sys_exit in the kernel.
* We change the name so we don't clash with the sys_exit syscall entry
#undef CREATE_SYSCALL_TABLE
-static void syscall_entry_unknown(struct ltt_channel *chan,
+static void syscall_entry_unknown(struct ltt_event *event,
struct pt_regs *regs, unsigned int id)
{
unsigned long args[UNKNOWN_SYSCALL_NRARGS];
- struct ltt_event *event;
- event = chan->sc_unknown;
syscall_get_arguments(current, regs, 0, UNKNOWN_SYSCALL_NRARGS, args);
__event_probe__sys_unknown(event, id, args);
}
struct ltt_channel *chan = __data;
struct ltt_event *event;
- if (unlikely(is_compat_task() || id >= ARRAY_SIZE(sc_table))) {
- syscall_entry_unknown(chan, regs, id);
+ if (unlikely(is_compat_task())) {
+ syscall_entry_unknown(chan->sc_compat_unknown, regs, id);
+ return;
+ }
+ if (unlikely(id >= ARRAY_SIZE(sc_table))) {
+ syscall_entry_unknown(chan->sc_unknown, regs, id);
return;
}
event = chan->sc_table[id];
if (unlikely(!event)) {
- syscall_entry_unknown(chan, regs, id);
+ syscall_entry_unknown(chan->sc_unknown, regs, id);
return;
}
entry = &sc_table[id];
}
}
+ if (!chan->sc_compat_unknown) {
+ struct lttng_kernel_event ev;
+ const struct lttng_event_desc *desc =
+ &__event_desc___compat_sys_unknown;
+
+ memset(&ev, 0, sizeof(ev));
+ strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN);
+ ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+ ev.instrumentation = LTTNG_KERNEL_NOOP;
+ chan->sc_compat_unknown = ltt_event_create(chan, &ev, filter,
+ desc);
+ if (!chan->sc_compat_unknown) {
+ return -EINVAL;
+ }
+ }
+
if (!chan->sc_exit) {
struct lttng_kernel_event ev;
const struct lttng_event_desc *desc =