diff options
Diffstat (limited to 'sys/i386/i386/ptrace_machdep.c')
-rw-r--r-- | sys/i386/i386/ptrace_machdep.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/sys/i386/i386/ptrace_machdep.c b/sys/i386/i386/ptrace_machdep.c index e6248a2..12bafe5 100644 --- a/sys/i386/i386/ptrace_machdep.c +++ b/sys/i386/i386/ptrace_machdep.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/proc.h> #include <sys/ptrace.h> +#include <machine/frame.h> #include <machine/md_var.h> #include <machine/pcb.h> @@ -115,8 +116,8 @@ cpu_ptrace_xstate(struct thread *td, int req, void *addr, int data) } #endif -int -cpu_ptrace(struct thread *td, int req, void *addr, int data) +static int +cpu_ptrace_xmm(struct thread *td, int req, void *addr, int data) { #ifdef CPU_ENABLE_SSE struct savexmm *fpstate; @@ -155,3 +156,51 @@ cpu_ptrace(struct thread *td, int req, void *addr, int data) return (EINVAL); #endif } + +int +cpu_ptrace(struct thread *td, int req, void *addr, int data) +{ + struct segment_descriptor *sdp, sd; + register_t r; + int error; + + switch (req) { + case PT_GETXMMREGS: + case PT_SETXMMREGS: + case PT_GETXSTATE_OLD: + case PT_SETXSTATE_OLD: + case PT_GETXSTATE_INFO: + case PT_GETXSTATE: + case PT_SETXSTATE: + error = cpu_ptrace_xmm(td, req, addr, data); + break; + + case PT_GETFSBASE: + case PT_GETGSBASE: + sdp = req == PT_GETFSBASE ? &td->td_pcb->pcb_fsd : + &td->td_pcb->pcb_gsd; + r = sdp->sd_hibase << 24 | sdp->sd_lobase; + error = copyout(&r, addr, sizeof(r)); + break; + + case PT_SETFSBASE: + case PT_SETGSBASE: + error = copyin(addr, &r, sizeof(r)); + if (error != 0) + break; + fill_based_sd(&sd, r); + if (req == PT_SETFSBASE) { + td->td_pcb->pcb_fsd = sd; + td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL); + } else { + td->td_pcb->pcb_gsd = sd; + td->td_pcb->pcb_gs = GSEL(GUGS_SEL, SEL_UPL); + } + break; + + default: + return (EINVAL); + } + + return (error); +} |