Skip to content

Commit

Permalink
[ARM] 3262/4: allow ptraced syscalls to be overriden
Browse files Browse the repository at this point in the history
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: Nicolas Pitre <nico@cam.org>
Signed-off-by: Daniel Jacobowitz <dan@debian.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Nicolas Pitre authored and Russell King committed Jan 14, 2006
1 parent 6c90c87 commit 3f47112
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
3 changes: 3 additions & 0 deletions arch/arm/kernel/entry-common.S
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,13 @@ ENTRY(vector_swi)
* context switches, and waiting for our parent to respond.
*/
__sys_trace:
mov r2, scno
add r1, sp, #S_OFF
mov r0, #0 @ trace entry [IP = 0]
bl syscall_trace

adr lr, __sys_trace_return @ return address
mov scno, r0 @ syscall number (possibly new)
add r1, sp, #S_R0 + S_OFF @ pointer to regs
cmp scno, #NR_syscalls @ check upper syscall limit
ldmccia r1, {r0 - r3} @ have to reload r0 - r3
Expand All @@ -227,6 +229,7 @@ __sys_trace:

__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
mov r2, scno
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
bl syscall_trace
Expand Down
15 changes: 12 additions & 3 deletions arch/arm/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
(unsigned long __user *) data);
break;

case PTRACE_SET_SYSCALL:
ret = 0;
child->ptrace_message = data;
break;

default:
ret = ptrace_request(child, request, addr, data);
break;
Expand All @@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
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;

if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
return scno;
if (!(current->ptrace & PT_PTRACED))
return;
return scno;

/*
* Save IP. IP is used to denote syscall entry/exit:
Expand All @@ -790,6 +795,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
ip = regs->ARM_ip;
regs->ARM_ip = why;

current->ptrace_message = scno;

/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
Expand All @@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
current->exit_code = 0;
}
regs->ARM_ip = ip;

return current->ptrace_message;
}
3 changes: 3 additions & 0 deletions include/asm-arm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#define PTRACE_OLDSETOPTIONS 21

#define PTRACE_GET_THREAD_AREA 22

#define PTRACE_SET_SYSCALL 23

/*
* PSR bits
*/
Expand Down

0 comments on commit 3f47112

Please sign in to comment.