support ptrace(PTRACE_PEEKUSER, ...)

This commit is contained in:
Tomoki Shirasawa
2014-10-08 14:56:28 +09:00
parent a101aa0534
commit 4b46330624
3 changed files with 144 additions and 4 deletions

View File

@@ -143,6 +143,71 @@
#include <futex.h>
#include <rlimit.h>
struct user_fpregs_struct
{
unsigned short cwd;
unsigned short swd;
unsigned short ftw;
unsigned short fop;
unsigned long rip;
unsigned long rdp;
unsigned int mxcsr;
unsigned int mxcr_mask;
unsigned int st_space[32];
unsigned int xmm_space[64];
unsigned int padding[24];
};
struct user_regs_struct
{
unsigned long r15;
unsigned long r14;
unsigned long r13;
unsigned long r12;
unsigned long rbp;
unsigned long rbx;
unsigned long r11;
unsigned long r10;
unsigned long r9;
unsigned long r8;
unsigned long rax;
unsigned long rcx;
unsigned long rdx;
unsigned long rsi;
unsigned long rdi;
unsigned long orig_rax;
unsigned long rip;
unsigned long cs;
unsigned long eflags;
unsigned long rsp;
unsigned long ss;
unsigned long fs_base;
unsigned long gs_base;
unsigned long ds;
unsigned long es;
unsigned long fs;
unsigned long gs;
};
struct user
{
struct user_regs_struct regs;
int u_fpvalid;
struct user_fpregs_struct i387;
unsigned long int u_tsize;
unsigned long int u_dsize;
unsigned long int u_ssize;
unsigned long start_code;
unsigned long start_stack;
long int signal;
int reserved;
struct user_regs_struct* u_ar0;
struct user_fpregs_struct* u_fpstate;
unsigned long int magic;
char u_comm [32];
unsigned long int u_debugreg [8];
};
#define AUXV_LEN 14
struct vm_range {
@@ -273,6 +338,8 @@ struct process {
cpu_set_t cpu_set;
unsigned long saved_auxv[AUXV_LEN];
int pgid; /* process group id */
struct user *userp;
};
struct process_vm {

View File

@@ -1379,6 +1379,8 @@ SYSCALL_DECLARE(arch_prctl)
ihk_mc_syscall_arg1(ctx));
}
extern void peekuser(struct process *proc, void *regs);
static int ptrace_report_exec(struct process *proc)
{
dkprintf("ptrace_report_exec,enter\n");
@@ -1429,7 +1431,8 @@ static int ptrace_report_exec(struct process *proc)
/* Wake parent (if sleeping in wait4()) */
waitq_wakeup(&proc->ftn->parent->waitpid_q);
}
peekuser(proc, NULL);
/* Sleep */
dkprintf("ptrace_report_exec,sleeping\n");
proc->status = PS_TRACED;
@@ -2375,13 +2378,32 @@ out:
return error;
}
static long ptrace_peekuser(int pid, long addr)
{
long rc = -EIO;
struct process *child;
ihk_spinlock_t *savelock;
unsigned long irqstate;
if(addr > sizeof(struct user) || addr < 0)
return -EFAULT;
child = findthread_and_lock(pid, -1, &savelock, &irqstate);
if (!child)
return -ESRCH;
if(child->status == PS_TRACED)
memcpy(&rc, (char *)child->userp + addr, 8);
ihk_mc_spinlock_unlock(savelock, irqstate);
return rc;
}
SYSCALL_DECLARE(ptrace)
{
const long request = (long)ihk_mc_syscall_arg0(ctx);
const int pid = (int)ihk_mc_syscall_arg1(ctx);
const long addr = (long)ihk_mc_syscall_arg2(ctx);
const long data = (long)ihk_mc_syscall_arg3(ctx);
int error;
long error = -EOPNOTSUPP;
switch(request) {
case PTRACE_TRACEME:
@@ -2393,6 +2415,10 @@ SYSCALL_DECLARE(ptrace)
dkprintf("ptrace: PTRACE_KILL/CONT\n");
error = ptrace_wakeup_sig(pid, request, data);
break;
case PTRACE_PEEKUSER:
error = ptrace_peekuser(pid, addr);
dkprintf("PTRACE_PEEKUSER: addr=%p return=%p\n", addr, error);
break;
default:
dkprintf("ptrace: unimplemented ptrace called.\n");
break;