aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-07-27 02:51:03 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-28 02:30:49 -0400
commit4f72c4279eab1e5f3ed1ac4e55d4527617582392 (patch)
tree5a170211e0206d4d17a008dec9c88827c95c1152 /arch/powerpc/kernel/ptrace.c
parent6558ba2b5cc3a2f22039db30616fcd07c1b28ac8 (diff)
powerpc: Make syscall tracing use tracehook.h helpers
This changes powerpc syscall tracing to use the new tracehook.h entry points. There is no change, only cleanup. In addition, the assembly changes allow do_syscall_trace_enter() to abort the syscall without losing the information about the original r0 value. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r--arch/powerpc/kernel/ptrace.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 66204cb51a1a..6b66cd85b433 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -22,6 +22,7 @@
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/regset.h> 24#include <linux/regset.h>
25#include <linux/tracehook.h>
25#include <linux/elf.h> 26#include <linux/elf.h>
26#include <linux/user.h> 27#include <linux/user.h>
27#include <linux/security.h> 28#include <linux/security.h>
@@ -1014,31 +1015,24 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
1014 return ret; 1015 return ret;
1015} 1016}
1016 1017
1017static void do_syscall_trace(void) 1018/*
1019 * We must return the syscall number to actually look up in the table.
1020 * This can be -1L to skip running any syscall at all.
1021 */
1022long do_syscall_trace_enter(struct pt_regs *regs)
1018{ 1023{
1019 /* the 0x80 provides a way for the tracing parent to distinguish 1024 long ret = 0;
1020 between a syscall stop and SIGTRAP delivery */
1021 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
1022 ? 0x80 : 0));
1023
1024 /*
1025 * this isn't the same as continuing with a signal, but it will do
1026 * for normal use. strace only continues with a signal if the
1027 * stopping signal is not SIGTRAP. -brl
1028 */
1029 if (current->exit_code) {
1030 send_sig(current->exit_code, current, 1);
1031 current->exit_code = 0;
1032 }
1033}
1034 1025
1035void do_syscall_trace_enter(struct pt_regs *regs)
1036{
1037 secure_computing(regs->gpr[0]); 1026 secure_computing(regs->gpr[0]);
1038 1027
1039 if (test_thread_flag(TIF_SYSCALL_TRACE) 1028 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
1040 && (current->ptrace & PT_PTRACED)) 1029 tracehook_report_syscall_entry(regs))
1041 do_syscall_trace(); 1030 /*
1031 * Tracing decided this syscall should not happen.
1032 * We'll return a bogus call number to get an ENOSYS
1033 * error, but leave the original number in regs->gpr[0].
1034 */
1035 ret = -1L;
1042 1036
1043 if (unlikely(current->audit_context)) { 1037 if (unlikely(current->audit_context)) {
1044#ifdef CONFIG_PPC64 1038#ifdef CONFIG_PPC64
@@ -1056,16 +1050,19 @@ void do_syscall_trace_enter(struct pt_regs *regs)
1056 regs->gpr[5] & 0xffffffff, 1050 regs->gpr[5] & 0xffffffff,
1057 regs->gpr[6] & 0xffffffff); 1051 regs->gpr[6] & 0xffffffff);
1058 } 1052 }
1053
1054 return ret ?: regs->gpr[0];
1059} 1055}
1060 1056
1061void do_syscall_trace_leave(struct pt_regs *regs) 1057void do_syscall_trace_leave(struct pt_regs *regs)
1062{ 1058{
1059 int step;
1060
1063 if (unlikely(current->audit_context)) 1061 if (unlikely(current->audit_context))
1064 audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, 1062 audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
1065 regs->result); 1063 regs->result);
1066 1064
1067 if ((test_thread_flag(TIF_SYSCALL_TRACE) 1065 step = test_thread_flag(TIF_SINGLESTEP);
1068 || test_thread_flag(TIF_SINGLESTEP)) 1066 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
1069 && (current->ptrace & PT_PTRACED)) 1067 tracehook_report_syscall_exit(regs, step);
1070 do_syscall_trace();
1071} 1068}