From 235754834b6818e727d6b8e240c4ec7f79e2f457 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 24 Aug 2009 13:26:04 +0200 Subject: microblaze: Support ptrace syscall tracing. Signed-off-by: Edgar E. Iglesias Signed-off-by: Michal Simek --- arch/microblaze/kernel/ptrace.c | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'arch/microblaze/kernel/ptrace.c') diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c index 53ff39af6a5..4b3ac32754d 100644 --- a/arch/microblaze/kernel/ptrace.c +++ b/arch/microblaze/kernel/ptrace.c @@ -29,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -174,6 +178,64 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return rval; } +asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) +{ + long ret = 0; + + secure_computing(regs->r12); + + if (test_thread_flag(TIF_SYSCALL_TRACE) && + tracehook_report_syscall_entry(regs)) + /* + * Tracing decided this syscall should not happen. + * We'll return a bogus call number to get an ENOSYS + * error, but leave the original number in regs->regs[0]. + */ + ret = -1L; + + if (unlikely(current->audit_context)) + audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12, + regs->r5, regs->r6, + regs->r7, regs->r8); + + return ret ?: regs->r12; +} + +asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) +{ + int step; + + if (unlikely(current->audit_context)) + audit_syscall_exit(AUDITSC_RESULT(regs->r3), regs->r3); + + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); +} + +#if 0 +static asmlinkage void syscall_trace(void) +{ + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (!(current->ptrace & PT_PTRACED)) + return; + /* The 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (current->exit_code) { + send_sig(current->exit_code, current, 1); + current->exit_code = 0; + } +} +#endif + void ptrace_disable(struct task_struct *child) { /* nothing to do */ -- cgit v1.2.3-70-g09d2