diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-07-30 06:09:31 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-08-01 15:39:33 -0400 |
commit | c459dbf294b4a3d70490a468a7ca3907fb2c2f57 (patch) | |
tree | c78866944d8e03247b6d5072987cd7f7c558caef /arch/sh/kernel/ptrace_32.c | |
parent | c4637d475170ca0d99973efd07df727012db6cd1 (diff) |
sh: ptrace single stepping cleanups.
This converts the single stepping done by sh/sh64 ptrace implementations
to use the generic user_enable/disable_single_step(), and subsequently
rips out a lot of ptrace request cases that are now handled generically.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/ptrace_32.c')
-rw-r--r-- | arch/sh/kernel/ptrace_32.c | 93 |
1 files changed, 18 insertions, 75 deletions
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index e9bd4b2aa9c2..ff66f97c564d 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c | |||
@@ -58,7 +58,23 @@ static inline int put_stack_long(struct task_struct *task, int offset, | |||
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void ptrace_disable_singlestep(struct task_struct *child) | 61 | void user_enable_single_step(struct task_struct *child) |
62 | { | ||
63 | struct pt_regs *regs = task_pt_regs(child); | ||
64 | long pc; | ||
65 | |||
66 | pc = get_stack_long(child, (long)®s->pc); | ||
67 | |||
68 | /* Next scheduling will set up UBC */ | ||
69 | if (child->thread.ubc_pc == 0) | ||
70 | ubc_usercnt += 1; | ||
71 | |||
72 | child->thread.ubc_pc = pc; | ||
73 | |||
74 | set_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
75 | } | ||
76 | |||
77 | void user_disable_single_step(struct task_struct *child) | ||
62 | { | 78 | { |
63 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | 79 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); |
64 | 80 | ||
@@ -82,7 +98,7 @@ static void ptrace_disable_singlestep(struct task_struct *child) | |||
82 | */ | 98 | */ |
83 | void ptrace_disable(struct task_struct *child) | 99 | void ptrace_disable(struct task_struct *child) |
84 | { | 100 | { |
85 | ptrace_disable_singlestep(child); | 101 | user_disable_single_step(child); |
86 | } | 102 | } |
87 | 103 | ||
88 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 104 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
@@ -91,12 +107,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
91 | int ret; | 107 | int ret; |
92 | 108 | ||
93 | switch (request) { | 109 | switch (request) { |
94 | /* when I and D space are separate, these will need to be fixed. */ | ||
95 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | ||
96 | case PTRACE_PEEKDATA: | ||
97 | ret = generic_ptrace_peekdata(child, addr, data); | ||
98 | break; | ||
99 | |||
100 | /* read the word at location addr in the USER area. */ | 110 | /* read the word at location addr in the USER area. */ |
101 | case PTRACE_PEEKUSR: { | 111 | case PTRACE_PEEKUSR: { |
102 | unsigned long tmp; | 112 | unsigned long tmp; |
@@ -126,12 +136,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
126 | break; | 136 | break; |
127 | } | 137 | } |
128 | 138 | ||
129 | /* when I and D space are separate, this will have to be fixed. */ | ||
130 | case PTRACE_POKETEXT: /* write the word at location addr. */ | ||
131 | case PTRACE_POKEDATA: | ||
132 | ret = generic_ptrace_pokedata(child, addr, data); | ||
133 | break; | ||
134 | |||
135 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 139 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
136 | ret = -EIO; | 140 | ret = -EIO; |
137 | if ((addr & 3) || addr < 0 || | 141 | if ((addr & 3) || addr < 0 || |
@@ -152,67 +156,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
152 | } | 156 | } |
153 | break; | 157 | break; |
154 | 158 | ||
155 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | ||
156 | case PTRACE_CONT: { /* restart after signal. */ | ||
157 | ret = -EIO; | ||
158 | if (!valid_signal(data)) | ||
159 | break; | ||
160 | if (request == PTRACE_SYSCALL) | ||
161 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
162 | else | ||
163 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
164 | |||
165 | ptrace_disable_singlestep(child); | ||
166 | |||
167 | child->exit_code = data; | ||
168 | wake_up_process(child); | ||
169 | ret = 0; | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * make the child exit. Best I can do is send it a sigkill. | ||
175 | * perhaps it should be put in the status that it wants to | ||
176 | * exit. | ||
177 | */ | ||
178 | case PTRACE_KILL: { | ||
179 | ret = 0; | ||
180 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | ||
181 | break; | ||
182 | ptrace_disable_singlestep(child); | ||
183 | child->exit_code = SIGKILL; | ||
184 | wake_up_process(child); | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | ||
189 | long pc; | ||
190 | struct pt_regs *regs = NULL; | ||
191 | |||
192 | ret = -EIO; | ||
193 | if (!valid_signal(data)) | ||
194 | break; | ||
195 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
196 | if ((child->ptrace & PT_DTRACE) == 0) { | ||
197 | /* Spurious delayed TF traps may occur */ | ||
198 | child->ptrace |= PT_DTRACE; | ||
199 | } | ||
200 | |||
201 | pc = get_stack_long(child, (long)®s->pc); | ||
202 | |||
203 | /* Next scheduling will set up UBC */ | ||
204 | if (child->thread.ubc_pc == 0) | ||
205 | ubc_usercnt += 1; | ||
206 | child->thread.ubc_pc = pc; | ||
207 | |||
208 | set_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
209 | child->exit_code = data; | ||
210 | /* give it a chance to run. */ | ||
211 | wake_up_process(child); | ||
212 | ret = 0; | ||
213 | break; | ||
214 | } | ||
215 | |||
216 | #ifdef CONFIG_SH_DSP | 159 | #ifdef CONFIG_SH_DSP |
217 | case PTRACE_GETDSPREGS: { | 160 | case PTRACE_GETDSPREGS: { |
218 | unsigned long dp; | 161 | unsigned long dp; |