diff options
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 | } |