Changeset View
Changeset View
Standalone View
Standalone View
head/sys/i386/i386/ptrace_machdep.c
Show All 26 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_cpu.h" | #include "opt_cpu.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/malloc.h> | |||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/ptrace.h> | #include <sys/ptrace.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/pcb.h> | #include <machine/pcb.h> | ||||
#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU) | #if !defined(CPU_DISABLE_SSE) && defined(I686_CPU) | ||||
#define CPU_ENABLE_SSE | #define CPU_ENABLE_SSE | ||||
#endif | #endif | ||||
#ifdef CPU_ENABLE_SSE | |||||
static int | |||||
cpu_ptrace_xstate(struct thread *td, int req, void *addr, int data) | |||||
{ | |||||
char *savefpu; | |||||
int error; | |||||
if (!use_xsave) | |||||
return (EOPNOTSUPP); | |||||
switch (req) { | |||||
case PT_GETXSTATE: | |||||
npxgetregs(td); | |||||
savefpu = (char *)(get_pcb_user_save_td(td) + 1); | |||||
error = copyout(savefpu, addr, | |||||
cpu_max_ext_state_size - sizeof(union savefpu)); | |||||
break; | |||||
case PT_SETXSTATE: | |||||
if (data > cpu_max_ext_state_size - sizeof(union savefpu)) { | |||||
error = EINVAL; | |||||
break; | |||||
} | |||||
savefpu = malloc(data, M_TEMP, M_WAITOK); | |||||
error = copyin(addr, savefpu, data); | |||||
if (error == 0) { | |||||
npxgetregs(td); | |||||
error = npxsetxstate(td, savefpu, data); | |||||
} | |||||
free(savefpu, M_TEMP); | |||||
break; | |||||
default: | |||||
error = EINVAL; | |||||
break; | |||||
} | |||||
return (error); | |||||
} | |||||
#endif | |||||
int | int | ||||
cpu_ptrace(struct thread *td, int req, void *addr, int data) | cpu_ptrace(struct thread *td, int req, void *addr, int data) | ||||
{ | { | ||||
#ifdef CPU_ENABLE_SSE | #ifdef CPU_ENABLE_SSE | ||||
struct savexmm *fpstate; | struct savexmm *fpstate; | ||||
int error; | int error; | ||||
if (!cpu_fxsr) | if (!cpu_fxsr) | ||||
return (EINVAL); | return (EINVAL); | ||||
fpstate = &td->td_pcb->pcb_user_save.sv_xmm; | fpstate = &get_pcb_user_save_td(td)->sv_xmm; | ||||
switch (req) { | switch (req) { | ||||
case PT_GETXMMREGS: | case PT_GETXMMREGS: | ||||
npxgetregs(td); | npxgetregs(td); | ||||
error = copyout(fpstate, addr, sizeof(*fpstate)); | error = copyout(fpstate, addr, sizeof(*fpstate)); | ||||
break; | break; | ||||
case PT_SETXMMREGS: | case PT_SETXMMREGS: | ||||
npxgetregs(td); | npxgetregs(td); | ||||
error = copyin(addr, fpstate, sizeof(*fpstate)); | error = copyin(addr, fpstate, sizeof(*fpstate)); | ||||
fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask; | fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask; | ||||
break; | |||||
case PT_GETXSTATE: | |||||
case PT_SETXSTATE: | |||||
error = cpu_ptrace_xstate(td, req, addr, data); | |||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
return (error); | return (error); | ||||
#else | #else | ||||
return (EINVAL); | return (EINVAL); | ||||
#endif | #endif | ||||
} | } |