support PTRACE_GETREGS
This commit is contained in:
@@ -195,6 +195,45 @@ do_setpgid(int pid, int pgid)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pokeuser(struct process *proc, void *regs0)
|
||||
{
|
||||
struct x86_regs *regs = regs0;
|
||||
|
||||
if(regs == NULL){
|
||||
asm("movq %%gs:132, %0" : "=r" (regs));
|
||||
--regs;
|
||||
}
|
||||
asm("mov %0, %%db0" ::"r" (proc->userp->u_debugreg[0]));
|
||||
asm("mov %0, %%db1" ::"r" (proc->userp->u_debugreg[1]));
|
||||
asm("mov %0, %%db2" ::"r" (proc->userp->u_debugreg[2]));
|
||||
asm("mov %0, %%db3" ::"r" (proc->userp->u_debugreg[3]));
|
||||
// asm("mov %0, %%db4" ::"r" (proc->userp->u_debugreg[4]));
|
||||
// asm("mov %0, %%db5" ::"r" (proc->userp->u_debugreg[5]));
|
||||
asm("mov %0, %%db6" ::"r" (proc->userp->u_debugreg[6]));
|
||||
asm("mov %0, %%db7" ::"r" (proc->userp->u_debugreg[7]));
|
||||
regs->r15 = proc->userp->regs.r15;
|
||||
regs->r14 = proc->userp->regs.r14;
|
||||
regs->r13 = proc->userp->regs.r13;
|
||||
regs->r12 = proc->userp->regs.r12;
|
||||
regs->rbp = proc->userp->regs.rbp;
|
||||
regs->rbx = proc->userp->regs.rbx;
|
||||
regs->r11 = proc->userp->regs.r11;
|
||||
regs->r10 = proc->userp->regs.r10;
|
||||
regs->r9 = proc->userp->regs.r9;
|
||||
regs->r8 = proc->userp->regs.r8;
|
||||
regs->rax = proc->userp->regs.rax;
|
||||
regs->rcx = proc->userp->regs.rcx;
|
||||
regs->rdx = proc->userp->regs.rdx;
|
||||
regs->rsi = proc->userp->regs.rsi;
|
||||
regs->rdi = proc->userp->regs.rdi;
|
||||
regs->rip = proc->userp->regs.rip;
|
||||
regs->cs = proc->userp->regs.cs;
|
||||
regs->rflags = proc->userp->regs.eflags;
|
||||
regs->rsp = proc->userp->regs.rsp;
|
||||
regs->ss = proc->userp->regs.ss;
|
||||
}
|
||||
|
||||
void
|
||||
peekuser(struct process *proc, void *regs0)
|
||||
{
|
||||
|
||||
@@ -2378,6 +2378,27 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static long ptrace_pokeuser(int pid, long addr, long data)
|
||||
{
|
||||
long rc = -EIO;
|
||||
struct process *child;
|
||||
ihk_spinlock_t *savelock;
|
||||
unsigned long irqstate;
|
||||
|
||||
if(addr > sizeof(struct user) - 8 || addr < 0)
|
||||
return -EFAULT;
|
||||
child = findthread_and_lock(pid, -1, &savelock, &irqstate);
|
||||
if (!child)
|
||||
return -ESRCH;
|
||||
if(child->status == PS_TRACED){
|
||||
memcpy((char *)child->userp + addr, &data, 8);
|
||||
rc = 0;
|
||||
}
|
||||
ihk_mc_spinlock_unlock(savelock, irqstate);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long ptrace_peekuser(int pid, long addr)
|
||||
{
|
||||
long rc = -EIO;
|
||||
@@ -2385,7 +2406,7 @@ static long ptrace_peekuser(int pid, long addr)
|
||||
ihk_spinlock_t *savelock;
|
||||
unsigned long irqstate;
|
||||
|
||||
if(addr > sizeof(struct user) || addr < 0)
|
||||
if(addr > sizeof(struct user) - 8|| addr < 0)
|
||||
return -EFAULT;
|
||||
child = findthread_and_lock(pid, -1, &savelock, &irqstate);
|
||||
if (!child)
|
||||
@@ -2397,6 +2418,28 @@ static long ptrace_peekuser(int pid, long addr)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long ptrace_getregs(int pid, long data)
|
||||
{
|
||||
struct user_regs_struct *regs = (struct user_regs_struct *)data;
|
||||
long rc = -EIO;
|
||||
struct process *child;
|
||||
ihk_spinlock_t *savelock;
|
||||
unsigned long irqstate;
|
||||
|
||||
child = findthread_and_lock(pid, -1, &savelock, &irqstate);
|
||||
if (!child)
|
||||
return -ESRCH;
|
||||
if(child->status == PS_TRACED){
|
||||
if(copy_to_user(child, regs, child->userp, sizeof(struct user_regs_struct)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
ihk_mc_spinlock_unlock(savelock, irqstate);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(ptrace)
|
||||
{
|
||||
const long request = (long)ihk_mc_syscall_arg0(ctx);
|
||||
@@ -2415,10 +2458,18 @@ SYSCALL_DECLARE(ptrace)
|
||||
dkprintf("ptrace: PTRACE_KILL/CONT\n");
|
||||
error = ptrace_wakeup_sig(pid, request, data);
|
||||
break;
|
||||
case PTRACE_GETREGS:
|
||||
error = ptrace_getregs(pid, data);
|
||||
dkprintf("PTRACE_GETREGS: data=%p return=%p\n", data, error);
|
||||
break;
|
||||
case PTRACE_PEEKUSER:
|
||||
error = ptrace_peekuser(pid, addr);
|
||||
dkprintf("PTRACE_PEEKUSER: addr=%p return=%p\n", addr, error);
|
||||
break;
|
||||
case PTRACE_POKEUSER:
|
||||
error = ptrace_pokeuser(pid, addr, data);
|
||||
dkprintf("PTRACE_POKEUSER: addr=%p data=%p return=%p\n", addr, data, error);
|
||||
break;
|
||||
default:
|
||||
dkprintf("ptrace: unimplemented ptrace called.\n");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user