diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-07-30 06:55:30 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-08-01 15:39:33 -0400 |
commit | ab99c733ae73cce31f2a2434f7099564e5a73d95 (patch) | |
tree | c9eb381f05688b8b4e79d2ffe495b4d4b302f2d4 /arch/sh/kernel/ptrace_32.c | |
parent | c459dbf294b4a3d70490a468a7ca3907fb2c2f57 (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.c | 54 |
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 | ||
219 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | 220 | asmlinkage 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 | ||
250 | out: | 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 | |||
243 | asmlinkage 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 | } |