From 24ef2641d917695470fb2d43dabb133e3ee6678f Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 28 Aug 2023 14:18:19 -0700 Subject: [PATCH] gdb: Support XSAVE layouts for the current host in the FreeBSD x86 targets. Use the CPUID instruction to fetch the offsets of supported state components. Approved-By: Simon Marchi --- gdb/amd64-fbsd-nat.c | 40 ++++++++++------------------------------ gdb/configure.nat | 5 +++-- gdb/i386-fbsd-nat.c | 39 +++++++++------------------------------ gdb/x86-fbsd-nat.c | 21 +++++++++++++++++++++ gdb/x86-fbsd-nat.h | 19 +++++++++++++++++++ 5 files changed, 62 insertions(+), 62 deletions(-) diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c index 43e83ff2485..5821d94e27e 100644 --- a/gdb/amd64-fbsd-nat.c +++ b/gdb/amd64-fbsd-nat.c @@ -31,9 +31,9 @@ #include "amd64-tdep.h" #include "amd64-fbsd-tdep.h" +#include "i387-tdep.h" #include "amd64-nat.h" #include "x86-nat.h" -#include "gdbsupport/x86-xstate.h" #include "x86-fbsd-nat.h" class amd64_fbsd_nat_target final : public x86_fbsd_nat_target @@ -47,10 +47,6 @@ public: static amd64_fbsd_nat_target the_amd64_fbsd_nat_target; -#ifdef PT_GETXSTATE_INFO -static size_t xsave_len; -#endif - /* This is a layout of the amd64 'struct reg' but with i386 registers. */ @@ -146,9 +142,9 @@ amd64_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) fetching the FPU/XSAVE state unnecessarily. */ #ifdef PT_GETXSTATE_INFO - if (xsave_len != 0) + if (m_xsave_info.xsave_len != 0) { - void *xstateregs = alloca (xsave_len); + void *xstateregs = alloca (m_xsave_info.xsave_len); if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) perror_with_name (_("Couldn't get extended state status")); @@ -223,9 +219,9 @@ amd64_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) fetching the FPU/XSAVE state unnecessarily. */ #ifdef PT_GETXSTATE_INFO - if (xsave_len != 0) + if (m_xsave_info.xsave_len != 0) { - void *xstateregs = alloca (xsave_len); + void *xstateregs = alloca (m_xsave_info.xsave_len); if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) perror_with_name (_("Couldn't get extended state status")); @@ -233,7 +229,7 @@ amd64_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) amd64_collect_xsave (regcache, regnum, xstateregs, 0); if (ptrace (PT_SETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, - xsave_len) == -1) + m_xsave_info.xsave_len) == -1) perror_with_name (_("Couldn't write extended state status")); return; } @@ -303,10 +299,6 @@ amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) const struct target_desc * amd64_fbsd_nat_target::read_description () { -#ifdef PT_GETXSTATE_INFO - static int xsave_probed; - static uint64_t xcr0; -#endif struct reg regs; int is64; @@ -318,25 +310,13 @@ amd64_fbsd_nat_target::read_description () perror_with_name (_("Couldn't get registers")); is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL)); #ifdef PT_GETXSTATE_INFO - if (!xsave_probed) - { - struct ptrace_xstate_info info; - - if (ptrace (PT_GETXSTATE_INFO, inferior_ptid.pid (), - (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0) - { - xsave_len = info.xsave_len; - xcr0 = info.xsave_mask; - } - xsave_probed = 1; - } - - if (xsave_len != 0) + probe_xsave_layout (inferior_ptid.pid ()); + if (m_xsave_info.xsave_len != 0) { if (is64) - return amd64_target_description (xcr0, true); + return amd64_target_description (m_xsave_info.xsave_mask, true); else - return i386_target_description (xcr0, true); + return i386_target_description (m_xsave_info.xsave_mask, true); } #endif if (is64) diff --git a/gdb/configure.nat b/gdb/configure.nat index aabcdeff989..b371ad89afe 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -166,7 +166,8 @@ case ${gdb_host} in i386) # Host: FreeBSD/i386 NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \ - x86-bsd-nat.o x86-fbsd-nat.o i386-fbsd-nat.o bsd-kvm.o" + nat/x86-xstate.o x86-bsd-nat.o x86-fbsd-nat.o i386-fbsd-nat.o \ + bsd-kvm.o" ;; mips) # Host: FreeBSD/mips @@ -195,7 +196,7 @@ case ${gdb_host} in # Host: FreeBSD/amd64 NATDEPFILES="${NATDEPFILES} amd64-nat.o \ amd64-fbsd-nat.o bsd-kvm.o x86-nat.o nat/x86-dregs.o \ - x86-bsd-nat.o x86-fbsd-nat.o" + nat/x86-xstate.o x86-bsd-nat.o x86-fbsd-nat.o" ;; esac ;; diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c index a2255c3c26b..e2c0e611717 100644 --- a/gdb/i386-fbsd-nat.c +++ b/gdb/i386-fbsd-nat.c @@ -31,7 +31,6 @@ #include "i386-fbsd-tdep.h" #include "i387-tdep.h" #include "x86-nat.h" -#include "gdbsupport/x86-xstate.h" #include "x86-fbsd-nat.h" class i386_fbsd_nat_target final : public x86_fbsd_nat_target @@ -47,10 +46,6 @@ public: static i386_fbsd_nat_target the_i386_fbsd_nat_target; -#ifdef PT_GETXSTATE_INFO -static size_t xsave_len; -#endif - static int have_ptrace_xmmregs; /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this @@ -102,9 +97,9 @@ i386_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) fetching the FPU/XSAVE state unnecessarily. */ #ifdef PT_GETXSTATE_INFO - if (xsave_len != 0) + if (m_xsave_info.xsave_len != 0) { - void *xstateregs = alloca (xsave_len); + void *xstateregs = alloca (m_xsave_info.xsave_len); if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) perror_with_name (_("Couldn't get extended state status")); @@ -181,17 +176,17 @@ i386_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) fetching the FPU/XSAVE state unnecessarily. */ #ifdef PT_GETXSTATE_INFO - if (xsave_len != 0) + if (m_xsave_info.xsave_len != 0) { - void *xstateregs = alloca (xsave_len); + void *xstateregs = alloca (m_xsave_info.xsave_len); if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) perror_with_name (_("Couldn't get extended state status")); i387_collect_xsave (regcache, regnum, xstateregs, 0); - if (ptrace (PT_SETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, xsave_len) - == -1) + if (ptrace (PT_SETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, + m_xsave_info.xsave_len) == -1) perror_with_name (_("Couldn't write extended state status")); return; } @@ -309,31 +304,15 @@ i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) const struct target_desc * i386_fbsd_nat_target::read_description () { -#ifdef PT_GETXSTATE_INFO - static int xsave_probed; - static uint64_t xcr0; -#endif static int xmm_probed; if (inferior_ptid == null_ptid) return this->beneath ()->read_description (); #ifdef PT_GETXSTATE_INFO - if (!xsave_probed) - { - struct ptrace_xstate_info info; - - if (ptrace (PT_GETXSTATE_INFO, inferior_ptid.pid (), - (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0) - { - xsave_len = info.xsave_len; - xcr0 = info.xsave_mask; - } - xsave_probed = 1; - } - - if (xsave_len != 0) - return i386_target_description (xcr0, true); + probe_xsave_layout (inferior_ptid.pid ()); + if (m_xsave_info.xsave_len != 0) + return i386_target_description (m_xsave_info.xsave_mask, true); #endif if (!xmm_probed) diff --git a/gdb/x86-fbsd-nat.c b/gdb/x86-fbsd-nat.c index 5d1c9fc7665..240e228976c 100644 --- a/gdb/x86-fbsd-nat.c +++ b/gdb/x86-fbsd-nat.c @@ -19,6 +19,9 @@ #include "defs.h" #include "x86-fbsd-nat.h" +#ifdef PT_GETXSTATE_INFO +#include "nat/x86-xstate.h" +#endif /* Implement the virtual fbsd_nat_target::low_new_fork method. */ @@ -43,3 +46,21 @@ x86_fbsd_nat_target::low_new_fork (ptid_t parent, pid_t child) child_state = x86_debug_reg_state (child); *child_state = *parent_state; } + +#ifdef PT_GETXSTATE_INFO +void +x86_fbsd_nat_target::probe_xsave_layout (pid_t pid) +{ + if (m_xsave_probed) + return; + + m_xsave_probed = true; + + if (ptrace (PT_GETXSTATE_INFO, pid, (PTRACE_TYPE_ARG3) &m_xsave_info, + sizeof (m_xsave_info)) != 0) + return; + if (m_xsave_info.xsave_len != 0) + m_xsave_layout = x86_fetch_xsave_layout (m_xsave_info.xsave_mask, + m_xsave_info.xsave_len); +} +#endif diff --git a/gdb/x86-fbsd-nat.h b/gdb/x86-fbsd-nat.h index a424323f399..723bb6cf305 100644 --- a/gdb/x86-fbsd-nat.h +++ b/gdb/x86-fbsd-nat.h @@ -20,6 +20,11 @@ #ifndef X86_FBSD_NAT_H #define X86_FBSD_NAT_H +#include + +#ifdef PT_GETXSTATE_INFO +#include "gdbsupport/x86-xstate.h" +#endif #include "fbsd-nat.h" #include "x86-bsd-nat.h" @@ -32,6 +37,20 @@ public: { return true; } void low_new_fork (ptid_t parent, pid_t child) override; + +#ifdef PT_GETXSTATE_INFO + x86_xsave_layout fetch_x86_xsave_layout () override + { return m_xsave_layout; } + +protected: + void probe_xsave_layout (pid_t pid); + + struct ptrace_xstate_info m_xsave_info; + x86_xsave_layout m_xsave_layout; + +private: + bool m_xsave_probed; +#endif }; #endif /* x86-bsd-nat.h */ -- 2.30.2