diff options
author | Nicolas Pitre <nico@cam.org> | 2006-01-14 14:30:04 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-01-14 14:30:04 -0500 |
commit | 3f471126ee53feb5e9b210ea2f525ed3bb9b7a7f (patch) | |
tree | 3f7567343a892d02e758bcd1c07557af43d5aa1b /arch/arm/kernel/ptrace.c | |
parent | 6c90c872017773cde70a51432cb28f253451b967 (diff) |
[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: Nicolas Pitre <nico@cam.org>
Signed-off-by: Daniel Jacobowitz <dan@debian.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/ptrace.c')
-rw-r--r-- | arch/arm/kernel/ptrace.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index e591f72bcdeb..7b6256bb590e 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
766 | (unsigned long __user *) data); | 766 | (unsigned long __user *) data); |
767 | break; | 767 | break; |
768 | 768 | ||
769 | case PTRACE_SET_SYSCALL: | ||
770 | ret = 0; | ||
771 | child->ptrace_message = data; | ||
772 | break; | ||
773 | |||
769 | default: | 774 | default: |
770 | ret = ptrace_request(child, request, addr, data); | 775 | ret = ptrace_request(child, request, addr, data); |
771 | break; | 776 | break; |
@@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
774 | return ret; | 779 | return ret; |
775 | } | 780 | } |
776 | 781 | ||
777 | asmlinkage void syscall_trace(int why, struct pt_regs *regs) | 782 | asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) |
778 | { | 783 | { |
779 | unsigned long ip; | 784 | unsigned long ip; |
780 | 785 | ||
781 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 786 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
782 | return; | 787 | return scno; |
783 | if (!(current->ptrace & PT_PTRACED)) | 788 | if (!(current->ptrace & PT_PTRACED)) |
784 | return; | 789 | return scno; |
785 | 790 | ||
786 | /* | 791 | /* |
787 | * Save IP. IP is used to denote syscall entry/exit: | 792 | * 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 | ip = regs->ARM_ip; | 795 | ip = regs->ARM_ip; |
791 | regs->ARM_ip = why; | 796 | regs->ARM_ip = why; |
792 | 797 | ||
798 | current->ptrace_message = scno; | ||
799 | |||
793 | /* the 0x80 provides a way for the tracing parent to distinguish | 800 | /* the 0x80 provides a way for the tracing parent to distinguish |
794 | between a syscall stop and SIGTRAP delivery */ | 801 | between a syscall stop and SIGTRAP delivery */ |
795 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | 802 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) |
@@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs) | |||
804 | current->exit_code = 0; | 811 | current->exit_code = 0; |
805 | } | 812 | } |
806 | regs->ARM_ip = ip; | 813 | regs->ARM_ip = ip; |
814 | |||
815 | return current->ptrace_message; | ||
807 | } | 816 | } |