gdbserver: Add a function to set the XSAVE mask and size.
authorJohn Baldwin <jhb@FreeBSD.org>
Mon, 28 Aug 2023 21:18:19 +0000 (14:18 -0700)
committerJohn Baldwin <jhb@FreeBSD.org>
Mon, 28 Aug 2023 21:18:19 +0000 (14:18 -0700)
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 <simon.marchi@efficios.com>
gdbserver/configure.srv
gdbserver/i387-fp.cc
gdbserver/i387-fp.h
gdbserver/linux-x86-low.cc

index f0101994529bd252f41073b84ce0069feec43f90..72256f828716dcfe4acc9c9689607f55325f7b26 100644 (file)
@@ -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"
index 49795ace9a9fb8346225373064e310213c4a0231..b8d7a912f2609c9ebf05c0e5d732f2dc1d8f6748 100644 (file)
 #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);
+}
index f536a2be15a717f99d7fa183cf45c686f472beaa..09b6a91aa25353437703c958ab1f74c0c9edebe4 100644 (file)
@@ -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 */
index 4a538b107bef1929f27baee570d9a97478eb8282..1483e2a66d77ff655cc04b864c9bbc5f210013d4 100644 (file)
@@ -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)
     {