mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
[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 <[email protected]> Acked-by: Paul Mackerras <[email protected]> Acked-by: Ralf Baechle <[email protected]> Acked-By: David Howells <[email protected]> Acked-by: Russell King <[email protected]> Acked-by: Paul Mundt <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
db73e9aa99
commit
481bed4542
27 changed files with 163 additions and 818 deletions
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/ptrace.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
|
@ -121,61 +122,11 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
||||
|
||||
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
{
|
||||
struct task_struct *child;
|
||||
extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
|
||||
#define WPC_DBRMODE 0x0d104008
|
||||
static int first_call = 1;
|
||||
int ret;
|
||||
|
||||
lock_kernel();
|
||||
|
||||
if (first_call) {
|
||||
/* Set WPC.DBRMODE to 0. This makes all debug events get
|
||||
* delivered through RESVEC, i.e. into the handlers in entry.S.
|
||||
* (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
|
||||
* would normally be left set to 1, which makes debug events get
|
||||
* delivered through DBRVEC, i.e. into the remote gdb's
|
||||
* handlers. This prevents ptrace getting them, and confuses
|
||||
* the remote gdb.) */
|
||||
printk("DBRMODE set to 0 to permit native debugging\n");
|
||||
poke_real_address_q(WPC_DBRMODE, 0);
|
||||
first_call = 0;
|
||||
}
|
||||
|
||||
ret = -EPERM;
|
||||
if (request == PTRACE_TRACEME) {
|
||||
/* are we already being traced? */
|
||||
if (current->ptrace & PT_PTRACED)
|
||||
goto out;
|
||||
/* set the ptrace bit in the process flags. */
|
||||
current->ptrace |= PT_PTRACED;
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
ret = -ESRCH;
|
||||
read_lock(&tasklist_lock);
|
||||
child = find_task_by_pid(pid);
|
||||
if (child)
|
||||
get_task_struct(child);
|
||||
read_unlock(&tasklist_lock);
|
||||
if (!child)
|
||||
goto out;
|
||||
|
||||
ret = -EPERM;
|
||||
if (pid == 1) /* you may not mess with init */
|
||||
goto out_tsk;
|
||||
|
||||
if (request == PTRACE_ATTACH) {
|
||||
ret = ptrace_attach(child);
|
||||
goto out_tsk;
|
||||
}
|
||||
|
||||
ret = ptrace_check_attach(child, request == PTRACE_KILL);
|
||||
if (ret < 0)
|
||||
goto out_tsk;
|
||||
|
||||
switch (request) {
|
||||
/* when I and D space are separate, these will need to be fixed. */
|
||||
case PTRACE_PEEKTEXT: /* read word at location addr. */
|
||||
|
|
@ -313,13 +264,33 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
|||
ret = ptrace_request(child, request, addr, data);
|
||||
break;
|
||||
}
|
||||
out_tsk:
|
||||
put_task_struct(child);
|
||||
out:
|
||||
unlock_kernel();
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
|
||||
{
|
||||
extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
|
||||
#define WPC_DBRMODE 0x0d104008
|
||||
static int first_call = 1;
|
||||
|
||||
lock_kernel();
|
||||
if (first_call) {
|
||||
/* Set WPC.DBRMODE to 0. This makes all debug events get
|
||||
* delivered through RESVEC, i.e. into the handlers in entry.S.
|
||||
* (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
|
||||
* would normally be left set to 1, which makes debug events get
|
||||
* delivered through DBRVEC, i.e. into the remote gdb's
|
||||
* handlers. This prevents ptrace getting them, and confuses
|
||||
* the remote gdb.) */
|
||||
printk("DBRMODE set to 0 to permit native debugging\n");
|
||||
poke_real_address_q(WPC_DBRMODE, 0);
|
||||
first_call = 0;
|
||||
}
|
||||
unlock_kernel();
|
||||
|
||||
return sys_ptrace(request, pid, addr, data);
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace(void)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ sys_call_table:
|
|||
.long sys_setuid16
|
||||
.long sys_getuid16
|
||||
.long sys_stime /* 25 */
|
||||
.long sys_ptrace
|
||||
.long sh64_ptrace
|
||||
.long sys_alarm
|
||||
.long sys_fstat
|
||||
.long sys_pause
|
||||
|
|
|
|||
Loading…
Reference in a new issue