189 lines
5.6 KiB
Diff
189 lines
5.6 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:46 -0700
|
|
Subject: gdb-rhel-10464-xsave-update-17of21.patch
|
|
|
|
;; Backport "i386: Use a fallback XSAVE layout for remote targets"
|
|
;; (John Baldwin, RHEL-10464)
|
|
|
|
If a target provides a target description including registers from the
|
|
XSAVE extended region, but does not provide an XSAVE layout, use a
|
|
fallback XSAVE layout based on the included registers. This fallback
|
|
layout matches GDB's behavior in earlier releases which assumes the
|
|
layout from Intel CPUs.
|
|
|
|
This fallback layout is currently only used for remote targets since
|
|
native targets which support XSAVE provide an explicit layout derived
|
|
from CPUID.
|
|
|
|
PR gdb/30912
|
|
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30912
|
|
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
|
|
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
|
|
--- a/gdb/i386-tdep.c
|
|
+++ b/gdb/i386-tdep.c
|
|
@@ -8244,6 +8244,72 @@ i386_floatformat_for_type (struct gdbarch *gdbarch,
|
|
return default_floatformat_for_type (gdbarch, name, len);
|
|
}
|
|
|
|
+/* Compute an XCR0 mask based on a target description. */
|
|
+
|
|
+static uint64_t
|
|
+i386_xcr0_from_tdesc (const struct target_desc *tdesc)
|
|
+{
|
|
+ if (! tdesc_has_registers (tdesc))
|
|
+ return 0;
|
|
+
|
|
+ const struct tdesc_feature *feature_core;
|
|
+
|
|
+ const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx,
|
|
+ *feature_avx512, *feature_pkeys;
|
|
+
|
|
+ /* Get core registers. */
|
|
+ feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core");
|
|
+ if (feature_core == NULL)
|
|
+ return 0;
|
|
+
|
|
+ /* Get SSE registers. */
|
|
+ feature_sse = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse");
|
|
+
|
|
+ /* Try AVX registers. */
|
|
+ feature_avx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx");
|
|
+
|
|
+ /* Try MPX registers. */
|
|
+ feature_mpx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx");
|
|
+
|
|
+ /* Try AVX512 registers. */
|
|
+ feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
|
|
+
|
|
+ /* Try PKEYS */
|
|
+ feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys");
|
|
+
|
|
+ /* The XCR0 bits. */
|
|
+ uint64_t xcr0 = X86_XSTATE_X87;
|
|
+
|
|
+ if (feature_sse)
|
|
+ xcr0 |= X86_XSTATE_SSE;
|
|
+
|
|
+ if (feature_avx)
|
|
+ {
|
|
+ /* AVX register description requires SSE register description. */
|
|
+ if (!feature_sse)
|
|
+ return 0;
|
|
+
|
|
+ xcr0 |= X86_XSTATE_AVX;
|
|
+ }
|
|
+
|
|
+ if (feature_mpx)
|
|
+ xcr0 |= X86_XSTATE_MPX_MASK;
|
|
+
|
|
+ if (feature_avx512)
|
|
+ {
|
|
+ /* AVX512 register description requires AVX register description. */
|
|
+ if (!feature_avx)
|
|
+ return 0;
|
|
+
|
|
+ xcr0 |= X86_XSTATE_AVX512;
|
|
+ }
|
|
+
|
|
+ if (feature_pkeys)
|
|
+ xcr0 |= X86_XSTATE_PKRU;
|
|
+
|
|
+ return xcr0;
|
|
+}
|
|
+
|
|
static int
|
|
i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
|
|
struct tdesc_arch_data *tdesc_data)
|
|
@@ -8458,6 +8524,15 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|
|
|
x86_xsave_layout xsave_layout = target_fetch_x86_xsave_layout ();
|
|
|
|
+ /* If the target did not provide an XSAVE layout but the target
|
|
+ description includes registers from the XSAVE extended region,
|
|
+ use a fallback XSAVE layout. Specifically, this fallback layout
|
|
+ is used when writing out a local core dump for a remote
|
|
+ target. */
|
|
+ if (xsave_layout.sizeof_xsave == 0)
|
|
+ xsave_layout
|
|
+ = i387_fallback_xsave_layout (i386_xcr0_from_tdesc (info.target_desc));
|
|
+
|
|
/* If there is already a candidate, use it. */
|
|
for (arches = gdbarch_list_lookup_by_info (arches, &info);
|
|
arches != NULL;
|
|
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
|
|
--- a/gdb/i387-tdep.c
|
|
+++ b/gdb/i387-tdep.c
|
|
@@ -982,6 +982,55 @@ i387_guess_xsave_layout (uint64_t xcr0, size_t xsave_size,
|
|
return true;
|
|
}
|
|
|
|
+/* See i387-tdep.h. */
|
|
+
|
|
+x86_xsave_layout
|
|
+i387_fallback_xsave_layout (uint64_t xcr0)
|
|
+{
|
|
+ x86_xsave_layout layout;
|
|
+ memset (&layout, 0, sizeof (x86_xsave_layout));
|
|
+
|
|
+ if (HAS_PKRU (xcr0))
|
|
+ {
|
|
+ /* Intel CPUs supporting PKRU. */
|
|
+ layout.avx_offset = 576;
|
|
+ layout.bndregs_offset = 960;
|
|
+ layout.bndcfg_offset = 1024;
|
|
+ layout.k_offset = 1088;
|
|
+ layout.zmm_h_offset = 1152;
|
|
+ layout.zmm_offset = 1664;
|
|
+ layout.pkru_offset = 2688;
|
|
+ layout.sizeof_xsave = 2696;
|
|
+ }
|
|
+ else if (HAS_AVX512 (xcr0))
|
|
+ {
|
|
+ /* Intel CPUs supporting AVX512. */
|
|
+ layout.avx_offset = 576;
|
|
+ layout.bndregs_offset = 960;
|
|
+ layout.bndcfg_offset = 1024;
|
|
+ layout.k_offset = 1088;
|
|
+ layout.zmm_h_offset = 1152;
|
|
+ layout.zmm_offset = 1664;
|
|
+ layout.sizeof_xsave = 2688;
|
|
+ }
|
|
+ else if (HAS_MPX (xcr0))
|
|
+ {
|
|
+ /* Intel CPUs supporting MPX. */
|
|
+ layout.avx_offset = 576;
|
|
+ layout.bndregs_offset = 960;
|
|
+ layout.bndcfg_offset = 1024;
|
|
+ layout.sizeof_xsave = 1088;
|
|
+ }
|
|
+ else if (HAS_AVX (xcr0))
|
|
+ {
|
|
+ /* Intel and AMD CPUs supporting AVX. */
|
|
+ layout.avx_offset = 576;
|
|
+ layout.sizeof_xsave = 832;
|
|
+ }
|
|
+
|
|
+ return layout;
|
|
+}
|
|
+
|
|
/* Extract from XSAVE a bitset of the features that are available on the
|
|
target, but which have not yet been enabled. */
|
|
|
|
diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h
|
|
--- a/gdb/i387-tdep.h
|
|
+++ b/gdb/i387-tdep.h
|
|
@@ -148,6 +148,11 @@ extern bool i387_guess_xsave_layout (uint64_t xcr0, size_t xsave_size,
|
|
x86_xsave_layout &layout);
|
|
|
|
|
|
+/* Compute an XSAVE layout based on the XCR0 bitmask. This is used
|
|
+ as a fallback if a target does not provide an XSAVE layout. */
|
|
+
|
|
+extern x86_xsave_layout i387_fallback_xsave_layout (uint64_t xcr0);
|
|
+
|
|
/* Similar to i387_supply_fxsave, but use XSAVE extended state. */
|
|
|
|
extern void i387_supply_xsave (struct regcache *regcache, int regnum,
|