diff options
Diffstat (limited to 'arch/um/kernel/ptrace.c')
-rw-r--r-- | arch/um/kernel/ptrace.c | 70 |
1 files changed, 16 insertions, 54 deletions
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 8e3d69e4fcb5..484509948ee9 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -12,16 +12,25 @@ | |||
12 | #endif | 12 | #endif |
13 | #include "skas_ptrace.h" | 13 | #include "skas_ptrace.h" |
14 | 14 | ||
15 | static inline void set_singlestepping(struct task_struct *child, int on) | 15 | |
16 | |||
17 | void user_enable_single_step(struct task_struct *child) | ||
16 | { | 18 | { |
17 | if (on) | 19 | child->ptrace |= PT_DTRACE; |
18 | child->ptrace |= PT_DTRACE; | ||
19 | else | ||
20 | child->ptrace &= ~PT_DTRACE; | ||
21 | child->thread.singlestep_syscall = 0; | 20 | child->thread.singlestep_syscall = 0; |
22 | 21 | ||
23 | #ifdef SUBARCH_SET_SINGLESTEPPING | 22 | #ifdef SUBARCH_SET_SINGLESTEPPING |
24 | SUBARCH_SET_SINGLESTEPPING(child, on); | 23 | SUBARCH_SET_SINGLESTEPPING(child, 1); |
24 | #endif | ||
25 | } | ||
26 | |||
27 | void user_disable_single_step(struct task_struct *child) | ||
28 | { | ||
29 | child->ptrace &= ~PT_DTRACE; | ||
30 | child->thread.singlestep_syscall = 0; | ||
31 | |||
32 | #ifdef SUBARCH_SET_SINGLESTEPPING | ||
33 | SUBARCH_SET_SINGLESTEPPING(child, 0); | ||
25 | #endif | 34 | #endif |
26 | } | 35 | } |
27 | 36 | ||
@@ -30,7 +39,7 @@ static inline void set_singlestepping(struct task_struct *child, int on) | |||
30 | */ | 39 | */ |
31 | void ptrace_disable(struct task_struct *child) | 40 | void ptrace_disable(struct task_struct *child) |
32 | { | 41 | { |
33 | set_singlestepping(child,0); | 42 | user_disable_single_step(child); |
34 | } | 43 | } |
35 | 44 | ||
36 | extern int peek_user(struct task_struct * child, long addr, long data); | 45 | extern int peek_user(struct task_struct * child, long addr, long data); |
@@ -69,53 +78,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
69 | ret = -EIO; | 78 | ret = -EIO; |
70 | break; | 79 | break; |
71 | 80 | ||
72 | /* continue and stop at next (return from) syscall */ | ||
73 | case PTRACE_SYSCALL: | ||
74 | /* restart after signal. */ | ||
75 | case PTRACE_CONT: { | ||
76 | ret = -EIO; | ||
77 | if (!valid_signal(data)) | ||
78 | break; | ||
79 | |||
80 | set_singlestepping(child, 0); | ||
81 | if (request == PTRACE_SYSCALL) | ||
82 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
83 | else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
84 | child->exit_code = data; | ||
85 | wake_up_process(child); | ||
86 | ret = 0; | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * make the child exit. Best I can do is send it a sigkill. | ||
92 | * perhaps it should be put in the status that it wants to | ||
93 | * exit. | ||
94 | */ | ||
95 | case PTRACE_KILL: { | ||
96 | ret = 0; | ||
97 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | ||
98 | break; | ||
99 | |||
100 | set_singlestepping(child, 0); | ||
101 | child->exit_code = SIGKILL; | ||
102 | wake_up_process(child); | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | ||
107 | ret = -EIO; | ||
108 | if (!valid_signal(data)) | ||
109 | break; | ||
110 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
111 | set_singlestepping(child, 1); | ||
112 | child->exit_code = data; | ||
113 | /* give it a chance to run. */ | ||
114 | wake_up_process(child); | ||
115 | ret = 0; | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | #ifdef PTRACE_GETREGS | 81 | #ifdef PTRACE_GETREGS |
120 | case PTRACE_GETREGS: { /* Get all gp regs from the child. */ | 82 | case PTRACE_GETREGS: { /* Get all gp regs from the child. */ |
121 | if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { | 83 | if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { |