169 lines
5.8 KiB
Diff
169 lines
5.8 KiB
Diff
|
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||
|
From: John Baldwin <jhb@FreeBSD.org>
|
||
|
Date: Thu, 11 Apr 2024 14:05:44 -0700
|
||
|
Subject: gdb-rhel-10464-xsave-update-9of21.patch
|
||
|
|
||
|
;; Backport "gdbserver: Add a function to set the XSAVE mask and size."
|
||
|
;; (John Baldwin, RHEL-10464)
|
||
|
|
||
|
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>
|
||
|
|
||
|
diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
|
||
|
--- a/gdbserver/configure.srv
|
||
|
+++ b/gdbserver/configure.srv
|
||
|
@@ -93,7 +93,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"
|
||
|
@@ -333,7 +334,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"
|
||
|
@@ -348,14 +350,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
|
||
|
--- a/gdbserver/i387-fp.cc
|
||
|
+++ b/gdbserver/i387-fp.cc
|
||
|
@@ -19,6 +19,10 @@
|
||
|
#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;
|
||
|
@@ -29,6 +33,8 @@ static const int num_avx512_ymmh_registers = 16;
|
||
|
static const int num_avx512_xmm_registers = 16;
|
||
|
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. */
|
||
|
|
||
|
@@ -950,5 +956,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
|
||
|
--- 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
|
||
|
--- 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__
|
||
|
@@ -871,6 +872,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);
|
||
|
@@ -905,8 +907,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)
|
||
|
@@ -936,11 +936,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;
|
||
|
}
|
||
|
@@ -951,7 +953,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)
|
||
|
{
|