From 03e6fe7e0a6fc4adccf59681962490a10fb31f7c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 28 Aug 2023 14:18:19 -0700 Subject: [PATCH] gdbserver: Add a function to set the XSAVE mask and size. Make x86_xcr0 private to i387-fp.cc and use i387_set_xsave_mask to set the value instead. Add a static global instance of x86_xsave_layout and initialize it in the new function as well to be used in a future commit to parse XSAVE extended state regions. Update the Linux port to use this function rather than setting x86_xcr0 directly. In the case that XML is not supported, don't bother setting x86_xcr0 to the default value but just omit the call to i387_set_xsave_mask as i387-fp.cc defaults to the SSE case used for non-XML. In addition, use x86_xsave_length to determine the size of the XSAVE register set via CPUID. Approved-By: Simon Marchi --- gdbserver/configure.srv | 12 ++++++++---- gdbserver/i387-fp.cc | 16 ++++++++++++++-- gdbserver/i387-fp.h | 4 +++- gdbserver/linux-x86-low.cc | 10 ++++++---- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index f0101994529..72256f82871 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -102,7 +102,8 @@ case "${gdbserver_host}" in i[34567]86-*-linux*) srv_tgtobj="${srv_tgtobj} arch/i386.o" srv_tgtobj="${srv_tgtobj} $srv_linux_obj" srv_tgtobj="${srv_tgtobj} linux-x86-low.o x86-low.o" - srv_tgtobj="${srv_tgtobj} nat/x86-dregs.o i387-fp.o" + srv_tgtobj="${srv_tgtobj} nat/x86-dregs.o" + srv_tgtobj="${srv_tgtobj} nat/x86-xstate.o i387-fp.o" srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o" srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux.o" @@ -362,7 +363,8 @@ case "${gdbserver_host}" in srv_linux_thread_db=yes ;; x86_64-*-linux*) srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o" - srv_tgtobj="${srv_tgtobj} nat/x86-dregs.o i387-fp.o" + srv_tgtobj="${srv_tgtobj} nat/x86-dregs.o" + srv_tgtobj="${srv_tgtobj} nat/x86-xstate.o i387-fp.o" srv_tgtobj="${srv_tgtobj} arch/i386.o arch/amd64.o" srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o" srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o" @@ -377,14 +379,16 @@ case "${gdbserver_host}" in ipa_obj="${ipa_obj} arch/amd64-ipa.o" ;; x86_64-*-mingw*) srv_regobj="" - srv_tgtobj="x86-low.o nat/x86-dregs.o i387-fp.o" + srv_tgtobj="x86-low.o nat/x86-dregs.o" + srv_tgtobj="${srv_tgtobj} nat/x86-xstate.o i387-fp.o" srv_tgtobj="${srv_tgtobj} win32-low.o win32-i386-low.o" srv_tgtobj="${srv_tgtobj} nat/windows-nat.o" srv_tgtobj="${srv_tgtobj} arch/amd64.o arch/i386.o" srv_mingw=yes ;; x86_64-*-cygwin*) srv_regobj="" - srv_tgtobj="x86-low.o nat/x86-dregs.o i387-fp.o" + srv_tgtobj="x86-low.o nat/x86-dregs.o" + srv_tgtobj="${srv_tgtobj} nat/x86-xstate.o i387-fp.o" srv_tgtobj="${srv_tgtobj} win32-low.o win32-i386-low.o" srv_tgtobj="${srv_tgtobj} nat/windows-nat.o" srv_tgtobj="${srv_tgtobj} arch/amd64.o arch/i386.o" diff --git a/gdbserver/i387-fp.cc b/gdbserver/i387-fp.cc index 49795ace9a9..b8d7a912f26 100644 --- a/gdbserver/i387-fp.cc +++ b/gdbserver/i387-fp.cc @@ -19,12 +19,18 @@ #include "server.h" #include "i387-fp.h" #include "gdbsupport/x86-xstate.h" +#include "nat/x86-xstate.h" + +/* Default to SSE. */ +static unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK; static const int num_mpx_bnd_registers = 4; static const int num_mpx_cfg_registers = 2; static const int num_avx512_k_registers = 8; static const int num_pkeys_registers = 1; +static x86_xsave_layout xsave_layout; + /* Note: These functions preserve the reserved bits in control registers. However, gdbserver promptly throws away that information. */ @@ -974,5 +980,11 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) } } -/* Default to SSE. */ -unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK; +/* See i387-fp.h. */ + +void +i387_set_xsave_mask (uint64_t xcr0, int len) +{ + x86_xcr0 = xcr0; + xsave_layout = x86_fetch_xsave_layout (xcr0, len); +} diff --git a/gdbserver/i387-fp.h b/gdbserver/i387-fp.h index f536a2be15a..09b6a91aa25 100644 --- a/gdbserver/i387-fp.h +++ b/gdbserver/i387-fp.h @@ -28,6 +28,8 @@ void i387_fxsave_to_cache (struct regcache *regcache, const void *buf); void i387_cache_to_xsave (struct regcache *regcache, void *buf); void i387_xsave_to_cache (struct regcache *regcache, const void *buf); -extern unsigned long long x86_xcr0; +/* Set the XSAVE mask and fetch the XSAVE layout via CPUID. */ + +void i387_set_xsave_mask (uint64_t xcr0, int len); #endif /* GDBSERVER_I387_FP_H */ diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index 4a538b107be..1483e2a66d7 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -25,6 +25,7 @@ #include "i387-fp.h" #include "x86-low.h" #include "gdbsupport/x86-xstate.h" +#include "nat/x86-xstate.h" #include "nat/gdb_ptrace.h" #ifdef __x86_64__ @@ -873,6 +874,7 @@ x86_linux_read_description (void) int xcr0_features; int tid; static uint64_t xcr0; + static int xsave_len; struct regset_info *regset; tid = lwpid_of (current_thread); @@ -907,8 +909,6 @@ x86_linux_read_description (void) if (!use_xml) { - x86_xcr0 = X86_XSTATE_SSE_MASK; - /* Don't use XML. */ #ifdef __x86_64__ if (machine == EM_X86_64) @@ -938,11 +938,13 @@ x86_linux_read_description (void) xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET / sizeof (uint64_t))]; + xsave_len = x86_xsave_length (); + /* Use PTRACE_GETREGSET if it is available. */ for (regset = x86_regsets; regset->fill_function != NULL; regset++) if (regset->get_request == PTRACE_GETREGSET) - regset->size = X86_XSTATE_SIZE (xcr0); + regset->size = xsave_len; else if (regset->type != GENERAL_REGS) regset->size = 0; } @@ -953,7 +955,7 @@ x86_linux_read_description (void) && (xcr0 & X86_XSTATE_ALL_MASK)); if (xcr0_features) - x86_xcr0 = xcr0; + i387_set_xsave_mask (xcr0, xsave_len); if (machine == EM_X86_64) { -- 2.30.2