From 8c179d506a86d19e8652f63b0b73e79f2528fac7 Mon Sep 17 00:00:00 2001 From: Susumu Komae Date: Tue, 3 Mar 2015 14:22:57 +0900 Subject: [PATCH] support PTRACE_ARCH_PRCTL. refs #420 --- kernel/syscall.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/kernel/syscall.c b/kernel/syscall.c index 1ce3f055..513e8357 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2856,6 +2856,62 @@ static long ptrace_setregs(int pid, long data) return rc; } +static long ptrace_arch_prctl(int pid, long code, long addr) +{ + 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->ftn->status == PS_TRACED) { + switch (code) { + case ARCH_GET_FS: { + struct process *proc = cpu_local_var(current); + unsigned long value; + unsigned long *p = (unsigned long *)addr; + rc = ptrace_read_user(child, + offsetof(struct user_regs_struct, fs_base), + &value); + if (rc == 0) { + rc = copy_to_user(proc, p, (char *)&value, sizeof(value)); + } + break; + } + case ARCH_GET_GS: { + struct process *proc = cpu_local_var(current); + unsigned long value; + unsigned long *p = (unsigned long *)addr; + rc = ptrace_read_user(child, + offsetof(struct user_regs_struct, gs_base), + &value); + if (rc == 0) { + rc = copy_to_user(proc, p, (char *)&value, sizeof(value)); + } + break; + } + case ARCH_SET_FS: + rc = ptrace_write_user(child, + offsetof(struct user_regs_struct, fs_base), + (unsigned long)addr); + break; + case ARCH_SET_GS: + rc = ptrace_write_user(child, + offsetof(struct user_regs_struct, gs_base), + (unsigned long)addr); + break; + default: + rc = -EINVAL; + break; + } + } + ihk_mc_spinlock_unlock(savelock, irqstate); + + return rc; +} + static long ptrace_peektext(int pid, long addr, long data) { long rc = -EIO; @@ -3356,7 +3412,8 @@ SYSCALL_DECLARE(ptrace) dkprintf("ptrace: unimplemented ptrace(PTRACE_GET_THREAD_AREA) called.\n"); break; case PTRACE_ARCH_PRCTL: - dkprintf("ptrace: unimplemented ptrace(PTRACE_ARCH_PRCTL) called.\n"); + error = ptrace_arch_prctl(pid, data, addr); + dkprintf("PTRACE_ARCH_PRCTL: data=%p addr=%p return=%p\n", data, addr, error); break; case PTRACE_GETEVENTMSG: dkprintf("ptrace: PTRACE_GETEVENTMSG: data=%p\n", data);