diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-23 00:18:33 -0400 |
|---|---|---|
| committer | Richard Weinberger <richard@nod.at> | 2012-08-01 18:25:38 -0400 |
| commit | 1bfa2317b21750f739b59ab6df2c8efb12875045 (patch) | |
| tree | 1526554a2507948d881db1f415014bf2b66ad54d | |
| parent | a3170d2ec25f841bee1b52487693ac1a2f191ba6 (diff) | |
um: split syscall_trace(), pass pt_regs to it
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[richard@nod.at: Fixed some minor build issues]
Signed-off-by: Richard Weinberger <richard@nod.at>
| -rw-r--r-- | arch/um/include/asm/ptrace-generic.h | 2 | ||||
| -rw-r--r-- | arch/um/kernel/ptrace.c | 71 | ||||
| -rw-r--r-- | arch/um/kernel/skas/syscall.c | 4 |
3 files changed, 34 insertions, 43 deletions
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index e786a6a3ec5e..442f1d025dc2 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h | |||
| @@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value); | |||
| 37 | 37 | ||
| 38 | extern int arch_copy_tls(struct task_struct *new); | 38 | extern int arch_copy_tls(struct task_struct *new); |
| 39 | extern void clear_flushed_tls(struct task_struct *task); | 39 | extern void clear_flushed_tls(struct task_struct *task); |
| 40 | extern void syscall_trace_enter(struct pt_regs *regs); | ||
| 41 | extern void syscall_trace_leave(struct pt_regs *regs); | ||
| 40 | 42 | ||
| 41 | #endif | 43 | #endif |
| 42 | 44 | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 06b190390505..694d551c8899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
| @@ -3,11 +3,12 @@ | |||
| 3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include "linux/audit.h" | 6 | #include <linux/audit.h> |
| 7 | #include "linux/ptrace.h" | 7 | #include <linux/ptrace.h> |
| 8 | #include "linux/sched.h" | 8 | #include <linux/sched.h> |
| 9 | #include "asm/uaccess.h" | 9 | #include <linux/tracehook.h> |
| 10 | #include "skas_ptrace.h" | 10 | #include <asm/uaccess.h> |
| 11 | #include <skas_ptrace.h> | ||
| 11 | 12 | ||
| 12 | 13 | ||
| 13 | 14 | ||
| @@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | |||
| 162 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | 163 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and |
| 163 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check | 164 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check |
| 164 | */ | 165 | */ |
| 165 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) | 166 | void syscall_trace_enter(struct pt_regs *regs) |
| 166 | { | 167 | { |
| 167 | int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; | 168 | audit_syscall_entry(HOST_AUDIT_ARCH, |
| 168 | int tracesysgood; | 169 | UPT_SYSCALL_NR(®s->regs), |
| 169 | 170 | UPT_SYSCALL_ARG1(®s->regs), | |
| 170 | if (!entryexit) | 171 | UPT_SYSCALL_ARG2(®s->regs), |
| 171 | audit_syscall_entry(HOST_AUDIT_ARCH, | 172 | UPT_SYSCALL_ARG3(®s->regs), |
| 172 | UPT_SYSCALL_NR(regs), | 173 | UPT_SYSCALL_ARG4(®s->regs)); |
| 173 | UPT_SYSCALL_ARG1(regs), | ||
| 174 | UPT_SYSCALL_ARG2(regs), | ||
| 175 | UPT_SYSCALL_ARG3(regs), | ||
| 176 | UPT_SYSCALL_ARG4(regs)); | ||
| 177 | else | ||
| 178 | audit_syscall_exit(regs); | ||
| 179 | |||
| 180 | /* Fake a debug trap */ | ||
| 181 | if (is_singlestep) | ||
| 182 | send_sigtrap(current, regs, 0); | ||
| 183 | 174 | ||
| 184 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 175 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
| 185 | return; | 176 | return; |
| 186 | 177 | ||
| 187 | if (!(current->ptrace & PT_PTRACED)) | 178 | tracehook_report_syscall_entry(regs); |
| 188 | return; | 179 | } |
| 189 | 180 | ||
| 190 | /* | 181 | void syscall_trace_leave(struct pt_regs *regs) |
| 191 | * the 0x80 provides a way for the tracing parent to distinguish | 182 | { |
| 192 | * between a syscall stop and SIGTRAP delivery | 183 | int ptraced = current->ptrace; |
| 193 | */ | ||
| 194 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); | ||
| 195 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); | ||
| 196 | 184 | ||
| 197 | if (entryexit) /* force do_signal() --> is_syscall() */ | 185 | audit_syscall_exit(regs); |
| 198 | set_thread_flag(TIF_SIGPENDING); | ||
| 199 | 186 | ||
| 200 | /* | 187 | /* Fake a debug trap */ |
| 201 | * this isn't the same as continuing with a signal, but it will do | 188 | if (ptraced & PT_DTRACE) |
| 202 | * for normal use. strace only continues with a signal if the | 189 | send_sigtrap(current, ®s->regs, 0); |
| 203 | * stopping signal is not SIGTRAP. -brl | 190 | |
| 204 | */ | 191 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
| 205 | if (current->exit_code) { | 192 | return; |
| 206 | send_sig(current->exit_code, current, 1); | 193 | |
| 207 | current->exit_code = 0; | 194 | tracehook_report_syscall_exit(regs, 0); |
| 208 | } | 195 | /* force do_signal() --> is_syscall() */ |
| 196 | if (ptraced & PT_PTRACED) | ||
| 197 | set_thread_flag(TIF_SIGPENDING); | ||
| 209 | } | 198 | } |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 800551a29dbf..86368a025a96 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
| @@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
| 18 | long result; | 18 | long result; |
| 19 | int syscall; | 19 | int syscall; |
| 20 | 20 | ||
| 21 | syscall_trace(r, 0); | 21 | syscall_trace_enter(regs); |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | * This should go in the declaration of syscall, but when I do that, | 24 | * This should go in the declaration of syscall, but when I do that, |
| @@ -36,5 +36,5 @@ void handle_syscall(struct uml_pt_regs *r) | |||
| 36 | 36 | ||
| 37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); | 37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); |
| 38 | 38 | ||
| 39 | syscall_trace(r, 1); | 39 | syscall_trace_leave(regs); |
| 40 | } | 40 | } |
