diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h index fb7aaa2d731..8e025b73dbd 100644 --- a/sys/amd64/linux/linux.h +++ b/sys/amd64/linux/linux.h @@ -237,14 +237,32 @@ struct linux_pt_regset { l_ulong gs; }; +/* This corresponds to 'user_i387_struct' in Linux. */ +struct linux_pt_fpregset { + l_ushort cwd; + l_ushort swd; + l_ushort twd; + l_ushort fop; + uint64_t rip; + uint64_t rdp; + uint32_t mxcsr; + uint32_t mxcsr_mask; + uint32_t st_space[32]; + uint32_t xmm_space[64]; + uint32_t padding[24]; +}; + #ifdef _KERNEL struct reg; +struct fpreg; struct syscall_info; void bsd_to_linux_regset(const struct reg *b_reg, struct linux_pt_regset *l_regset); void linux_to_bsd_regset(struct reg *b_reg, const struct linux_pt_regset *l_regset); +void bsd_to_linux_fpregset(const struct fpreg *b_fpreg, + struct linux_pt_fpregset *l_fpregset); void linux_ptrace_get_syscall_info_machdep(const struct reg *reg, struct syscall_info *si); int linux_ptrace_getregs_machdep(struct thread *td, pid_t pid, diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c index 7ec1ec56bb9..e05f824cbea 100644 --- a/sys/amd64/linux/linux_machdep.c +++ b/sys/amd64/linux/linux_machdep.c @@ -281,6 +281,26 @@ linux_to_bsd_regset(struct reg *b_reg, const struct linux_pt_regset *l_regset) b_reg->r_gs = l_regset->gs; } +void +bsd_to_linux_fpregset(const struct fpreg *b_fpreg, + struct linux_pt_fpregset *l_fpregset) +{ + l_fpregset->cwd = b_fpreg->fpr_env[0]; + l_fpregset->swd = b_fpreg->fpr_env[0] >> 16; + l_fpregset->twd = b_fpreg->fpr_env[0] >> 32; + l_fpregset->fop = b_fpreg->fpr_env[0] >> 48; + l_fpregset->rip = b_fpreg->fpr_env[1]; + l_fpregset->rdp = b_fpreg->fpr_env[2]; + l_fpregset->mxcsr = b_fpreg->fpr_env[3]; + l_fpregset->mxcsr_mask = b_fpreg->fpr_env[3] >> 32; + + memcpy(l_fpregset->st_space, b_fpreg->fpr_acc, + sizeof(l_fpregset->st_space)); + memcpy(l_fpregset->xmm_space, b_fpreg->fpr_xacc, + sizeof(l_fpregset->xmm_space)); + memset(l_fpregset->padding, 0, sizeof(l_fpregset->padding)); +} + void linux_ptrace_get_syscall_info_machdep(const struct reg *reg, struct syscall_info *si)