mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
linux: Add linux_pt_fpregset and bsd_to_linux_fpregset() for amd64
Add struct linux_pt_fpregset, the amd64 Linux NT_PRFPREG payload,
corresponding to user_i387_struct in Linux. The struct describes
the 512-byte FXSAVE area as exposed by PTRACE_GETREGSET.
Add bsd_to_linux_fpregset() to translate from FreeBSD's struct fpreg
to struct linux_pt_fpregset. Fields are extracted from the fpr_env[]
array which stores the FXSAVE environment packed as four 64-bit words.
The FP and XMM register banks are bulk-copied as opaque byte arrays.
Signed-off-by: Ricardo Branco <[email protected]>
Reviewed by: kib
Pull-Request: https://github.com/freebsd/freebsd-src/pull/2165
(cherry picked from commit b84d31ee74)
This commit is contained in:
1 parent
29b79c586b
commit
d8f8031923
2 files changed
+38
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user