aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh64/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh64/kernel/ptrace.c')
-rw-r--r--arch/sh64/kernel/ptrace.c83
1 files changed, 27 insertions, 56 deletions
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 71f2eec00b99..cd22e9471316 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -28,6 +28,7 @@
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/user.h> 29#include <linux/user.h>
30#include <linux/signal.h> 30#include <linux/signal.h>
31#include <linux/syscalls.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
@@ -121,61 +122,11 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
121 return 0; 122 return 0;
122} 123}
123 124
124asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 125
126long arch_ptrace(struct task_struct *child, long request, long addr, long data)
125{ 127{
126 struct task_struct *child;
127 extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
128#define WPC_DBRMODE 0x0d104008
129 static int first_call = 1;
130 int ret; 128 int ret;
131 129
132 lock_kernel();
133
134 if (first_call) {
135 /* Set WPC.DBRMODE to 0. This makes all debug events get
136 * delivered through RESVEC, i.e. into the handlers in entry.S.
137 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
138 * would normally be left set to 1, which makes debug events get
139 * delivered through DBRVEC, i.e. into the remote gdb's
140 * handlers. This prevents ptrace getting them, and confuses
141 * the remote gdb.) */
142 printk("DBRMODE set to 0 to permit native debugging\n");
143 poke_real_address_q(WPC_DBRMODE, 0);
144 first_call = 0;
145 }
146
147 ret = -EPERM;
148 if (request == PTRACE_TRACEME) {
149 /* are we already being traced? */
150 if (current->ptrace & PT_PTRACED)
151 goto out;
152 /* set the ptrace bit in the process flags. */
153 current->ptrace |= PT_PTRACED;
154 ret = 0;
155 goto out;
156 }
157 ret = -ESRCH;
158 read_lock(&tasklist_lock);
159 child = find_task_by_pid(pid);
160 if (child)
161 get_task_struct(child);
162 read_unlock(&tasklist_lock);
163 if (!child)
164 goto out;
165
166 ret = -EPERM;
167 if (pid == 1) /* you may not mess with init */
168 goto out_tsk;
169
170 if (request == PTRACE_ATTACH) {
171 ret = ptrace_attach(child);
172 goto out_tsk;
173 }
174
175 ret = ptrace_check_attach(child, request == PTRACE_KILL);
176 if (ret < 0)
177 goto out_tsk;
178
179 switch (request) { 130 switch (request) {
180 /* when I and D space are separate, these will need to be fixed. */ 131 /* when I and D space are separate, these will need to be fixed. */
181 case PTRACE_PEEKTEXT: /* read word at location addr. */ 132 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
313 ret = ptrace_request(child, request, addr, data); 264 ret = ptrace_request(child, request, addr, data);
314 break; 265 break;
315 } 266 }
316out_tsk:
317 put_task_struct(child);
318out:
319 unlock_kernel();
320 return ret; 267 return ret;
321} 268}
322 269
270asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
271{
272 extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
273#define WPC_DBRMODE 0x0d104008
274 static int first_call = 1;
275
276 lock_kernel();
277 if (first_call) {
278 /* Set WPC.DBRMODE to 0. This makes all debug events get
279 * delivered through RESVEC, i.e. into the handlers in entry.S.
280 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
281 * would normally be left set to 1, which makes debug events get
282 * delivered through DBRVEC, i.e. into the remote gdb's
283 * handlers. This prevents ptrace getting them, and confuses
284 * the remote gdb.) */
285 printk("DBRMODE set to 0 to permit native debugging\n");
286 poke_real_address_q(WPC_DBRMODE, 0);
287 first_call = 0;
288 }
289 unlock_kernel();
290
291 return sys_ptrace(request, pid, addr, data);
292}
293
323asmlinkage void syscall_trace(void) 294asmlinkage void syscall_trace(void)
324{ 295{
325 struct task_struct *tsk = current; 296 struct task_struct *tsk = current;