Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 217622
b: refs/heads/master
c: ce7f2a3
h: refs/heads/master
v: v3
  • Loading branch information
Chris Metcalf committed Oct 15, 2010
1 parent d8e297a commit 4b63a79
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c569cac8b69397d8bc80f95bc6edf13ed902e28b
refs/heads/master: ce7f2a39675ea5e8e27b3f3bb03e5041c7d10412
4 changes: 2 additions & 2 deletions trunk/arch/tile/kernel/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ long tile_compat_sys_msgrcv(int msqid,
#define compat_sys_fstat64 sys_newfstat
#define compat_sys_fstatat64 sys_newfstatat

/* Pass full 64-bit values through ptrace. */
#define compat_sys_ptrace tile_compat_sys_ptrace
/* The native sys_ptrace dynamically handles compat binaries. */
#define compat_sys_ptrace sys_ptrace

/* Call the trampolines to manage pt_regs where necessary. */
#define compat_sys_execve _compat_sys_execve
Expand Down
78 changes: 36 additions & 42 deletions trunk/arch/tile/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,6 @@ void user_disable_single_step(struct task_struct *child)
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
}

/*
* This routine will put a word on the process's privileged stack.
*/
static void putreg(struct task_struct *task,
unsigned long addr, unsigned long value)
{
unsigned int regno = addr / sizeof(unsigned long);
struct pt_regs *childregs = task_pt_regs(task);
childregs->regs[regno] = value;
childregs->flags |= PT_FLAGS_RESTORE_REGS;
}

static unsigned long getreg(struct task_struct *task, unsigned long addr)
{
unsigned int regno = addr / sizeof(unsigned long);
struct pt_regs *childregs = task_pt_regs(task);
return childregs->regs[regno];
}

/*
* Called by kernel/ptrace.c when detaching..
*/
Expand All @@ -66,59 +47,72 @@ void ptrace_disable(struct task_struct *child)

long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long __user *datap;
unsigned long __user *datap = (long __user __force *)data;
unsigned long tmp;
int i;
long ret = -EIO;

#ifdef CONFIG_COMPAT
if (task_thread_info(current)->status & TS_COMPAT)
data = (u32)data;
if (task_thread_info(child)->status & TS_COMPAT)
addr = (u32)addr;
#endif
datap = (unsigned long __user __force *)data;
unsigned long *childregs;
char *childreg;

switch (request) {

case PTRACE_PEEKUSR: /* Read register from pt_regs. */
if (addr & (sizeof(data)-1))
break;
if (addr < 0 || addr >= PTREGS_SIZE)
break;
tmp = getreg(child, addr); /* Read register */
ret = put_user(tmp, datap);
childreg = (char *)task_pt_regs(child) + addr;
#ifdef CONFIG_COMPAT
if (is_compat_task()) {
if (addr & (sizeof(compat_long_t)-1))
break;
ret = put_user(*(compat_long_t *)childreg,
(compat_long_t __user *)datap);
} else
#endif
{
if (addr & (sizeof(long)-1))
break;
ret = put_user(*(long *)childreg, datap);
}
break;

case PTRACE_POKEUSR: /* Write register in pt_regs. */
if (addr & (sizeof(data)-1))
break;
if (addr < 0 || addr >= PTREGS_SIZE)
break;
putreg(child, addr, data); /* Write register */
childreg = (char *)task_pt_regs(child) + addr;
#ifdef CONFIG_COMPAT
if (is_compat_task()) {
if (addr & (sizeof(compat_long_t)-1))
break;
*(compat_long_t *)childreg = data;
} else
#endif
{
if (addr & (sizeof(long)-1))
break;
*(long *)childreg = data;
}
ret = 0;
break;

case PTRACE_GETREGS: /* Get all registers from the child. */
if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
break;
for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
ret = __put_user(getreg(child, i), datap);
childregs = (long *)task_pt_regs(child);
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) {
ret = __put_user(childregs[i], &datap[i]);
if (ret != 0)
break;
datap++;
}
break;

case PTRACE_SETREGS: /* Set all registers in the child. */
if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
break;
for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
ret = __get_user(tmp, datap);
childregs = (long *)task_pt_regs(child);
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) {
ret = __get_user(childregs[i], &datap[i]);
if (ret != 0)
break;
putreg(child, i, tmp);
datap++;
}
break;

Expand Down

0 comments on commit 4b63a79

Please sign in to comment.