- /*
- * 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
- */
-#ifdef DEBUG_PTRACE
- printk("%s [%d]: syscall_trace exit= %x\n", current->comm,
- current->pid, current->exit_code);
-#endif
- if (current->exit_code) {
- send_sig (current->exit_code, current, 1);
- current->exit_code = 0;
+#ifdef CONFIG_COMPAT
+static const struct ptrace_layout_segment sparc32_getregs_layout[] = {
+ { 0, offsetof(struct pt_regs32, u_regs[0]),
+ 0, GENREG32_PSR * sizeof(u32) },
+ { offsetof(struct pt_regs32, u_regs[0]),
+ offsetof(struct pt_regs32, u_regs[15]),
+ 0, 1 * sizeof(u32) },
+ { offsetof(struct pt_regs32, u_regs[15]), sizeof(struct pt_regs32),
+ -1, 0 },
+ {0, 0, -1, 0}
+};
+
+int arch_compat_ptrace(compat_long_t *request, struct task_struct *child,
+ struct utrace_attached_engine *engine,
+ compat_ulong_t addr, compat_ulong_t data,
+ compat_long_t *retval)
+{
+ void __user *uaddr = (void __user *) (unsigned long) addr;
+ int err = -ENOSYS;
+
+ switch (*request) {
+ case PTRACE_GETREGS:
+ case PTRACE_SETREGS:
+ err = ptrace_layout_access(child, engine,
+ &utrace_sparc32_view,
+ sparc32_getregs_layout,
+ 0, sizeof(struct pt_regs32),
+ uaddr, NULL,
+ (*request ==
+ PTRACE_SETREGS));
+ break;
+
+ case PTRACE_GETFPREGS:
+ case PTRACE_SETFPREGS:
+ err = ptrace_whole_regset(child, engine, addr, 1,
+ (*request == PTRACE_SETFPREGS));
+ break;
+
+ case PTRACE_SUNDETACH:
+ *request = PTRACE_DETACH;
+ break;
+
+ default:
+ break;
+ };
+ return err;
+}
+#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_PTRACE */
+
+asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
+{
+ /* do the secure computing check first */
+ if (!syscall_exit_p)
+ secure_computing(regs->u_regs[UREG_G1]);
+
+ if (unlikely(current->audit_context) && syscall_exit_p) {
+ unsigned long tstate = regs->tstate;
+ int result = AUDITSC_SUCCESS;
+
+ if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
+ result = AUDITSC_FAILURE;
+
+ audit_syscall_exit(result, regs->u_regs[UREG_I0]);