Commit 3f471126 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King

[ARM] 3262/4: allow ptraced syscalls to be overriden

Patch from Nicolas Pitre

This is needed by strace to properly handle the tracing of some system
calls. It could be useful for other applications as well.

Based on an earlier patch from Daniel Jacobowitz.
Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
Signed-off-by: default avatarDaniel Jacobowitz <dan@debian.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 6c90c872
...@@ -214,11 +214,13 @@ ENTRY(vector_swi) ...@@ -214,11 +214,13 @@ ENTRY(vector_swi)
* context switches, and waiting for our parent to respond. * context switches, and waiting for our parent to respond.
*/ */
__sys_trace: __sys_trace:
mov r2, scno
add r1, sp, #S_OFF add r1, sp, #S_OFF
mov r0, #0 @ trace entry [IP = 0] mov r0, #0 @ trace entry [IP = 0]
bl syscall_trace bl syscall_trace
adr lr, __sys_trace_return @ return address adr lr, __sys_trace_return @ return address
mov scno, r0 @ syscall number (possibly new)
add r1, sp, #S_R0 + S_OFF @ pointer to regs add r1, sp, #S_R0 + S_OFF @ pointer to regs
cmp scno, #NR_syscalls @ check upper syscall limit cmp scno, #NR_syscalls @ check upper syscall limit
ldmccia r1, {r0 - r3} @ have to reload r0 - r3 ldmccia r1, {r0 - r3} @ have to reload r0 - r3
...@@ -227,6 +229,7 @@ __sys_trace: ...@@ -227,6 +229,7 @@ __sys_trace:
__sys_trace_return: __sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
mov r2, scno
mov r1, sp mov r1, sp
mov r0, #1 @ trace exit [IP = 1] mov r0, #1 @ trace exit [IP = 1]
bl syscall_trace bl syscall_trace
......
...@@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
(unsigned long __user *) data); (unsigned long __user *) data);
break; break;
case PTRACE_SET_SYSCALL:
ret = 0;
child->ptrace_message = data;
break;
default: default:
ret = ptrace_request(child, request, addr, data); ret = ptrace_request(child, request, addr, data);
break; break;
...@@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return ret; return ret;
} }
asmlinkage void syscall_trace(int why, struct pt_regs *regs) asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
{ {
unsigned long ip; unsigned long ip;
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return; return scno;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return scno;
/* /*
* Save IP. IP is used to denote syscall entry/exit: * Save IP. IP is used to denote syscall entry/exit:
...@@ -790,6 +795,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs) ...@@ -790,6 +795,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
ip = regs->ARM_ip; ip = regs->ARM_ip;
regs->ARM_ip = why; regs->ARM_ip = why;
current->ptrace_message = scno;
/* the 0x80 provides a way for the tracing parent to distinguish /* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */ between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
...@@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs) ...@@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
current->exit_code = 0; current->exit_code = 0;
} }
regs->ARM_ip = ip; regs->ARM_ip = ip;
return current->ptrace_message;
} }
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
#define PTRACE_OLDSETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
#define PTRACE_GET_THREAD_AREA 22 #define PTRACE_GET_THREAD_AREA 22
#define PTRACE_SET_SYSCALL 23
/* /*
* PSR bits * PSR bits
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment