diff options
author | Christoph Hellwig <hch@lst.de> | 2005-11-07 03:59:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:42 -0500 |
commit | 481bed454247538e9f57d4ea37b153ccba24ba7b (patch) | |
tree | bb4198296962c08dbf52e8f377dc27206f621640 /arch/sh64 | |
parent | db73e9aa99bf093427b79877f9475392724fd5e5 (diff) |
[PATCH] consolidate sys_ptrace()
The sys_ptrace boilerplate code (everything outside the big switch
statement for the arch-specific requests) is shared by most architectures.
This patch moves it to kernel/ptrace.c and leaves the arch-specific code as
arch_ptrace.
Some architectures have a too different ptrace so we have to exclude them.
They continue to keep their implementations. For sh64 I had to add a
sh64_ptrace wrapper because it does some initialization on the first call.
For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block, but
SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Paul Mackerras <paulus@samba.org>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-By: David Howells <dhowells@redhat.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/sh64')
-rw-r--r-- | arch/sh64/kernel/ptrace.c | 83 | ||||
-rw-r--r-- | arch/sh64/kernel/syscalls.S | 2 |
2 files changed, 28 insertions, 57 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 | ||
124 | asmlinkage long sys_ptrace(long request, long pid, long addr, long data) | 125 | |
126 | long 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 | } |
316 | out_tsk: | ||
317 | put_task_struct(child); | ||
318 | out: | ||
319 | unlock_kernel(); | ||
320 | return ret; | 267 | return ret; |
321 | } | 268 | } |
322 | 269 | ||
270 | asmlinkage 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 | |||
323 | asmlinkage void syscall_trace(void) | 294 | asmlinkage void syscall_trace(void) |
324 | { | 295 | { |
325 | struct task_struct *tsk = current; | 296 | struct task_struct *tsk = current; |
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S index a3d037805f1c..c0079d54c850 100644 --- a/arch/sh64/kernel/syscalls.S +++ b/arch/sh64/kernel/syscalls.S | |||
@@ -46,7 +46,7 @@ sys_call_table: | |||
46 | .long sys_setuid16 | 46 | .long sys_setuid16 |
47 | .long sys_getuid16 | 47 | .long sys_getuid16 |
48 | .long sys_stime /* 25 */ | 48 | .long sys_stime /* 25 */ |
49 | .long sys_ptrace | 49 | .long sh64_ptrace |
50 | .long sys_alarm | 50 | .long sys_alarm |
51 | .long sys_fstat | 51 | .long sys_fstat |
52 | .long sys_pause | 52 | .long sys_pause |