aboutsummaryrefslogtreecommitdiff
path: root/gdb/i386-tdep.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2023-11-27 13:53:22 -0800
committerJohn Baldwin <jhb@FreeBSD.org>2023-11-27 13:53:22 -0800
commit66637e209cc836c19a21a28e91046649c7702037 (patch)
tree98f333ed40a872165690234001683d1aca5652db /gdb/i386-tdep.c
parentf1b8ee6f2b4381bc46a0ad4c233b6eddc1e135b5 (diff)
downloadgdb-66637e209cc836c19a21a28e91046649c7702037.zip
gdb-66637e209cc836c19a21a28e91046649c7702037.tar.gz
gdb-66637e209cc836c19a21a28e91046649c7702037.tar.bz2
i386: Use a fallback XSAVE layout for remote targets
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>
Diffstat (limited to 'gdb/i386-tdep.c')
-rw-r--r--gdb/i386-tdep.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index f5ff55d..8efd858 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8297,6 +8297,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 (i386_gdbarch_tdep *tdep,
struct tdesc_arch_data *tdesc_data)
@@ -8508,6 +8574,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;