diff options
Diffstat (limited to 'arch/mips64/kernel/ptrace.c')
-rw-r--r-- | arch/mips64/kernel/ptrace.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c index 579fc8855..86e17a009 100644 --- a/arch/mips64/kernel/ptrace.c +++ b/arch/mips64/kernel/ptrace.c @@ -5,7 +5,7 @@ * * Copyright (C) 1992 Ross Biro * Copyright (C) Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle * Copyright (C) 1996 David S. Miller * Copyright (C) 2000 Ulf Carlsson * @@ -268,7 +268,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); + child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); REMOVE_LINKS(child); @@ -280,6 +280,15 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) break; } + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + default: ret = -EIO; break; @@ -534,7 +543,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); + child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); REMOVE_LINKS(child); @@ -546,6 +555,15 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) break; } + case PTRACE_SETOPTIONS: { + if (data & PTRACE_O_TRACESYSGOOD) + child->ptrace |= PT_TRACESYSGOOD; + else + child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + default: ret = -EIO; break; @@ -564,7 +582,10 @@ asmlinkage void syscall_trace(void) != (PT_PTRACED|PT_TRACESYS)) return; - current->exit_code = SIGTRAP; + /* The 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0); current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); |