aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/ptrace_32.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-07-30 06:55:30 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-08-01 15:39:33 -0400
commitab99c733ae73cce31f2a2434f7099564e5a73d95 (patch)
treec9eb381f05688b8b4e79d2ffe495b4d4b302f2d4 /arch/sh/kernel/ptrace_32.c
parentc459dbf294b4a3d70490a468a7ca3907fb2c2f57 (diff)
sh: Make syscall tracer use tracehook notifiers, add TIF_NOTIFY_RESUME.
This follows the changes in commits: 7d6d637dac2050f30a1b57b0a3dc5de4a10616ba 4f72c4279eab1e5f3ed1ac4e55d4527617582392 on powerpc. Adding in TIF_NOTIFY_RESUME, and cleaning up the syscall tracing to be more generic. This is an incremental step to turning on tracehook, as well as unifying more of the ptrace and signal code across the 32/64 split. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/ptrace_32.c')
-rw-r--r--arch/sh/kernel/ptrace_32.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index ff66f97c564d..f48769b23bd6 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -21,6 +21,7 @@
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/audit.h> 22#include <linux/audit.h>
23#include <linux/seccomp.h> 23#include <linux/seccomp.h>
24#include <linux/tracehook.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/pgtable.h> 26#include <asm/pgtable.h>
26#include <asm/system.h> 27#include <asm/system.h>
@@ -216,41 +217,38 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
216 return ret; 217 return ret;
217} 218}
218 219
219asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) 220asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
220{ 221{
221 struct task_struct *tsk = current; 222 long ret = 0;
222 223
223 secure_computing(regs->regs[0]); 224 secure_computing(regs->regs[0]);
224 225
225 if (unlikely(current->audit_context) && entryexit) 226 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
226 audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), 227 tracehook_report_syscall_entry(regs))
227 regs->regs[0]); 228 /*
228 229 * Tracing decided this syscall should not happen.
229 if (!test_thread_flag(TIF_SYSCALL_TRACE) && 230 * We'll return a bogus call number to get an ENOSYS
230 !test_thread_flag(TIF_SINGLESTEP)) 231 * error, but leave the original number in regs->regs[0].
231 goto out; 232 */
232 if (!(tsk->ptrace & PT_PTRACED)) 233 ret = -1L;
233 goto out;
234
235 /* the 0x80 provides a way for the tracing parent to distinguish
236 between a syscall stop and SIGTRAP delivery */
237 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
238 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
239
240 /*
241 * this isn't the same as continuing with a signal, but it will do
242 * for normal use. strace only continues with a signal if the
243 * stopping signal is not SIGTRAP. -brl
244 */
245 if (tsk->exit_code) {
246 send_sig(tsk->exit_code, tsk, 1);
247 tsk->exit_code = 0;
248 }
249 234
250out: 235 if (unlikely(current->audit_context))
251 if (unlikely(current->audit_context) && !entryexit)
252 audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3], 236 audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3],
253 regs->regs[4], regs->regs[5], 237 regs->regs[4], regs->regs[5],
254 regs->regs[6], regs->regs[7]); 238 regs->regs[6], regs->regs[7]);
255 239
240 return ret ?: regs->regs[0];
241}
242
243asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
244{
245 int step;
246
247 if (unlikely(current->audit_context))
248 audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
249 regs->regs[0]);
250
251 step = test_thread_flag(TIF_SINGLESTEP);
252 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
253 tracehook_report_syscall_exit(regs, step);
256} 254}