diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/entry-common.S | 14 | ||||
-rw-r--r-- | arch/arm/kernel/ptrace.c | 37 |
2 files changed, 31 insertions, 20 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 10911c93fbf1..49d9f9305247 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -442,10 +442,9 @@ ENDPROC(vector_swi) | |||
442 | * context switches, and waiting for our parent to respond. | 442 | * context switches, and waiting for our parent to respond. |
443 | */ | 443 | */ |
444 | __sys_trace: | 444 | __sys_trace: |
445 | mov r2, scno | 445 | mov r1, scno |
446 | add r1, sp, #S_OFF | 446 | add r0, sp, #S_OFF |
447 | mov r0, #0 @ trace entry [IP = 0] | 447 | bl syscall_trace_enter |
448 | bl syscall_trace | ||
449 | 448 | ||
450 | adr lr, BSYM(__sys_trace_return) @ return address | 449 | adr lr, BSYM(__sys_trace_return) @ return address |
451 | mov scno, r0 @ syscall number (possibly new) | 450 | mov scno, r0 @ syscall number (possibly new) |
@@ -457,10 +456,9 @@ __sys_trace: | |||
457 | 456 | ||
458 | __sys_trace_return: | 457 | __sys_trace_return: |
459 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 | 458 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 |
460 | mov r2, scno | 459 | mov r1, scno |
461 | mov r1, sp | 460 | mov r0, sp |
462 | mov r0, #1 @ trace exit [IP = 1] | 461 | bl syscall_trace_exit |
463 | bl syscall_trace | ||
464 | b ret_slow_syscall | 462 | b ret_slow_syscall |
465 | 463 | ||
466 | .align 5 | 464 | .align 5 |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 592a39d0ef31..dab711e6e1ca 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -907,12 +907,18 @@ long arch_ptrace(struct task_struct *child, long request, | |||
907 | return ret; | 907 | return ret; |
908 | } | 908 | } |
909 | 909 | ||
910 | asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) | 910 | enum ptrace_syscall_dir { |
911 | PTRACE_SYSCALL_ENTER = 0, | ||
912 | PTRACE_SYSCALL_EXIT, | ||
913 | }; | ||
914 | |||
915 | static int ptrace_syscall_trace(struct pt_regs *regs, int scno, | ||
916 | enum ptrace_syscall_dir dir) | ||
911 | { | 917 | { |
912 | unsigned long ip; | 918 | unsigned long ip; |
913 | 919 | ||
914 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 920 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
915 | goto out_no_trace; | 921 | return scno; |
916 | 922 | ||
917 | current_thread_info()->syscall = scno; | 923 | current_thread_info()->syscall = scno; |
918 | 924 | ||
@@ -921,21 +927,28 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) | |||
921 | * IP = 0 -> entry, =1 -> exit | 927 | * IP = 0 -> entry, =1 -> exit |
922 | */ | 928 | */ |
923 | ip = regs->ARM_ip; | 929 | ip = regs->ARM_ip; |
924 | regs->ARM_ip = why; | 930 | regs->ARM_ip = dir; |
925 | 931 | ||
926 | if (why) | 932 | if (dir == PTRACE_SYSCALL_EXIT) |
927 | tracehook_report_syscall_exit(regs, 0); | 933 | tracehook_report_syscall_exit(regs, 0); |
928 | else if (tracehook_report_syscall_entry(regs)) | 934 | else if (tracehook_report_syscall_entry(regs)) |
929 | current_thread_info()->syscall = -1; | 935 | current_thread_info()->syscall = -1; |
930 | 936 | ||
931 | regs->ARM_ip = ip; | 937 | regs->ARM_ip = ip; |
932 | scno = current_thread_info()->syscall; | 938 | return current_thread_info()->syscall; |
939 | } | ||
933 | 940 | ||
934 | out_no_trace: | 941 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) |
935 | if (why) | 942 | { |
936 | audit_syscall_exit(regs); | 943 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); |
937 | else | 944 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, |
938 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, | 945 | regs->ARM_r2, regs->ARM_r3); |
939 | regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); | 946 | return ret; |
940 | return scno; | 947 | } |
948 | |||
949 | asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) | ||
950 | { | ||
951 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); | ||
952 | audit_syscall_exit(regs); | ||
953 | return ret; | ||
941 | } | 954 | } |