public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: John Baldwin <jhb@FreeBSD.org>
To: gdb-patches@sourceware.org
Cc: Aleksandar Paunovic <aleksandar.paunovic@intel.com>
Subject: [PATCH v4 01/13] x86: Add an x86_xsave_layout structure to handle variable XSAVE layouts.
Date: Fri, 17 Mar 2023 18:08:53 -0700	[thread overview]
Message-ID: <20230318010905.14294-2-jhb@FreeBSD.org> (raw)
In-Reply-To: <20230318010905.14294-1-jhb@FreeBSD.org>

The standard layout of the XSAVE extended state area consists of three
regions.  The first 512 bytes (legacy region) match the layout of the
FXSAVE instruction including floating point registers, MMX registers,
and SSE registers.  The next 64 bytes (XSAVE header) contains a header
with a fixed layout.  The final region (extended region) contains zero
or more optional state components.  Examples of these include the
upper 128 bits of YMM registers for AVX.

These optional state components generally have an
architecturally-fixed size, but they are not assigned architectural
offsets in the extended region.  Instead, processors provide
additional CPUID leafs describing the size and offset of each
component in the "standard" layout for a given CPU.  (There is also a
"compact" format which uses an alternate layout, but existing OS's
currently export the "standard" layout when exporting XSAVE data via
ptrace() and core dumps.)

To date, GDB has assumed the layout used on current Intel processors
for state components in the extended region and hardcoded those
offsets in the tables in i387-tdep.c and i387-fp.cc.  However, this
fails on recent AMD processors which use a different layout.
Specifically, AMD Ryzen 9 processors at least do not leave space for
the MPX register set in between the AVX and AVX512 register sets.  It
is not known if other AMD processors are effected, but seems probable.

To rectify this, add an x86_xsave_layout structure which contains the
total size of the XSAVE extended state area as well as the offset of
each known optional state component.  This structure is stored in
i386_gdbarch_tdep and is fetched from the current target in
i386_gdbarch_init as a TARGET_OBJECT_X86_XSAVE_LAYOUT object.

Subsequent commits will modify XSAVE parsing to use x86_xsave_layout.

Co-authored-by: Aleksandar Paunovic <aleksandar.paunovic@intel.com>
---
 gdb/i386-tdep.c         | 36 +++++++++++++++++++++++++-
 gdb/i386-tdep.h         |  4 +++
 gdb/target.h            |  2 ++
 gdbsupport/x86-xstate.h | 57 +++++++++++++++++++++++++++++++++++------
 4 files changed, 90 insertions(+), 9 deletions(-)

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 96c04c1a3d6..5c2d9e42d8d 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8493,19 +8493,51 @@ i386_type_align (struct gdbarch *gdbarch, struct type *type)
 }
 
 \f
+/* Fetch the XSAVE layout for the current target.  */
+
+static struct x86_xsave_layout
+i386_fetch_xsave_layout ()
+{
+  struct x86_xsave_layout layout;
+  LONGEST len = target_read (current_inferior ()->top_target (),
+			     TARGET_OBJECT_X86_XSAVE_LAYOUT, nullptr,
+			     (gdb_byte *) &layout, 0, sizeof (layout));
+  if (len != sizeof (layout))
+    return {};
+
+  return layout;
+}
+
 /* Note: This is called for both i386 and amd64.  */
 
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   const struct target_desc *tdesc;
+  struct x86_xsave_layout xsave_layout;
   int mm0_regnum;
   int ymm0_regnum;
   int bnd0_regnum;
   int num_bnd_cooked;
 
+  xsave_layout = i386_fetch_xsave_layout ();
+
   /* If there is already a candidate, use it.  */
-  arches = gdbarch_list_lookup_by_info (arches, &info);
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      /* Check that the XSAVE layout of ARCHES matches the layout for
+	 the current target.  */
+      i386_gdbarch_tdep *other_tdep
+	= (i386_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch);
+
+      if (other_tdep->xsave_layout != xsave_layout)
+	continue;
+
+      break;
+    }
+
   if (arches != NULL)
     return arches->gdbarch;
 
@@ -8762,6 +8794,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       gdbarch_free (gdbarch);
       return NULL;
     }
+  if (tdep->xcr0 != 0)
+    tdep->xsave_layout = xsave_layout;
 
   num_bnd_cooked = (tdep->bnd0r_regnum > 0 ? I387_NUM_BND_REGS : 0);
 
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 371bce72369..e41e0ffebed 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -23,6 +23,7 @@
 #include "gdbarch.h"
 #include "infrun.h"
 #include "expression.h"
+#include "gdbsupport/x86-xstate.h"
 
 class frame_info_ptr;
 struct gdbarch;
@@ -145,6 +146,9 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base
   /* Offset of XCR0 in XSAVE extended state.  */
   int xsave_xcr0_offset = 0;
 
+  /* Layout of the XSAVE area extended region.  */
+  x86_xsave_layout xsave_layout;
+
   /* Register names.  */
   const char * const *register_names = nullptr;
 
diff --git a/gdb/target.h b/gdb/target.h
index 2dac86c394d..779e111daef 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -205,6 +205,8 @@ enum target_object
   TARGET_OBJECT_FREEBSD_VMMAP,
   /* FreeBSD process strings.  */
   TARGET_OBJECT_FREEBSD_PS_STRINGS,
+  /* x86 XSAVE area layout.  */
+  TARGET_OBJECT_X86_XSAVE_LAYOUT,
   /* Possible future objects: TARGET_OBJECT_FILE, ...  */
 };
 
diff --git a/gdbsupport/x86-xstate.h b/gdbsupport/x86-xstate.h
index b8740fd8701..2b517a6dce3 100644
--- a/gdbsupport/x86-xstate.h
+++ b/gdbsupport/x86-xstate.h
@@ -20,23 +20,64 @@
 #ifndef COMMON_X86_XSTATE_H
 #define COMMON_X86_XSTATE_H
 
+/* The extended state feature IDs in the state component bitmap.  */
+#define X86_XSTATE_X87_ID	0
+#define X86_XSTATE_SSE_ID	1
+#define X86_XSTATE_AVX_ID	2
+#define X86_XSTATE_BNDREGS_ID	3
+#define X86_XSTATE_BNDCFG_ID	4
+#define X86_XSTATE_K_ID		5
+#define X86_XSTATE_ZMM_H_ID	6
+#define X86_XSTATE_ZMM_ID	7
+#define X86_XSTATE_PT_ID	8
+#define X86_XSTATE_PKRU_ID	9
+
 /* The extended state feature bits.  */
-#define X86_XSTATE_X87		(1ULL << 0)
-#define X86_XSTATE_SSE		(1ULL << 1)
-#define X86_XSTATE_AVX		(1ULL << 2)
-#define X86_XSTATE_BNDREGS	(1ULL << 3)
-#define X86_XSTATE_BNDCFG	(1ULL << 4)
+#define X86_XSTATE_X87		(1ULL << X86_XSTATE_X87_ID)
+#define X86_XSTATE_SSE		(1ULL << X86_XSTATE_SSE_ID)
+#define X86_XSTATE_AVX		(1ULL << X86_XSTATE_AVX_ID)
+#define X86_XSTATE_BNDREGS	(1ULL << X86_XSTATE_BNDREGS_ID)
+#define X86_XSTATE_BNDCFG	(1ULL << X86_XSTATE_BNDCFG_ID)
 #define X86_XSTATE_MPX		(X86_XSTATE_BNDREGS | X86_XSTATE_BNDCFG)
 
 /* AVX 512 adds three feature bits.  All three must be enabled.  */
-#define X86_XSTATE_K		(1ULL << 5)
-#define X86_XSTATE_ZMM_H	(1ULL << 6)
-#define X86_XSTATE_ZMM		(1ULL << 7)
+#define X86_XSTATE_K		(1ULL << X86_XSTATE_K_ID)
+#define X86_XSTATE_ZMM_H	(1ULL << X86_XSTATE_ZMM_H_ID)
+#define X86_XSTATE_ZMM		(1ULL << X86_XSTATE_ZMM_ID)
 #define X86_XSTATE_AVX512	(X86_XSTATE_K | X86_XSTATE_ZMM_H \
 				 | X86_XSTATE_ZMM)
 
 #define X86_XSTATE_PKRU		(1ULL << 9)
 
+/* Size and offsets of register states in the XSAVE area extended
+   region.  Offsets are set to 0 to indicate the absence of the
+   associated registers.  */
+
+struct x86_xsave_layout
+{
+  int sizeof_xsave = 0;
+  int avx_offset = 0;
+  int bndregs_offset = 0;
+  int bndcfg_offset = 0;
+  int k_offset = 0;
+  int zmm_h_offset = 0;
+  int zmm_offset = 0;
+  int pkru_offset = 0;
+
+  bool operator!= (const x86_xsave_layout &other)
+  {
+    return sizeof_xsave != other.sizeof_xsave
+      || avx_offset != other.avx_offset
+      || bndregs_offset != other.bndregs_offset
+      || bndcfg_offset != other.bndcfg_offset
+      || k_offset != other.k_offset
+      || zmm_h_offset != other.zmm_h_offset
+      || zmm_offset != other.zmm_offset
+      || pkru_offset != other.pkru_offset;
+  }
+};
+
+
 /* Supported mask and size of the extended state.  */
 #define X86_XSTATE_X87_MASK	X86_XSTATE_X87
 #define X86_XSTATE_SSE_MASK	(X86_XSTATE_X87 | X86_XSTATE_SSE)
-- 
2.39.1


  reply	other threads:[~2023-03-18  1:09 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-18  1:08 [PATCH v4 00/13] Handle " John Baldwin
2023-03-18  1:08 ` John Baldwin [this message]
2023-03-28 11:35   ` [PATCH v4 01/13] x86: Add an x86_xsave_layout structure to handle " George, Jini Susan
2023-04-10 19:28     ` John Baldwin
2023-04-06 19:09   ` Simon Marchi
2023-04-10 20:03     ` John Baldwin
2023-04-11  1:19       ` Simon Marchi
2023-04-11 14:23     ` Pedro Alves
2023-04-11 16:02       ` John Baldwin
2023-03-18  1:08 ` [PATCH v4 02/13] core: Support fetching TARGET_OBJECT_X86_XSAVE_LAYOUT from architectures John Baldwin
2023-04-06 19:28   ` Simon Marchi
2023-04-10 20:42     ` John Baldwin
2023-04-11  1:49       ` Simon Marchi
2023-04-11 16:06         ` John Baldwin
2023-04-11 16:21           ` Simon Marchi
2023-04-11 23:59             ` John Baldwin
2023-03-18  1:08 ` [PATCH v4 03/13] nat/x86-cpuid.h: Add x86_cpuid_count wrapper around __get_cpuid_count John Baldwin
2023-04-06 19:33   ` Simon Marchi
2023-04-10 20:49     ` John Baldwin
2023-04-11  1:49       ` Simon Marchi
2023-03-18  1:08 ` [PATCH v4 04/13] x86 nat: Add helper functions to save the XSAVE layout for the host John Baldwin
2023-04-06 19:40   ` Simon Marchi
2023-04-10 21:00     ` John Baldwin
2023-04-11  1:51       ` Simon Marchi
2023-03-18  1:08 ` [PATCH v4 05/13] gdb: Update x86 FreeBSD architectures to support XSAVE layouts John Baldwin
2023-04-06 19:54   ` Simon Marchi
2023-04-10 21:02     ` John Baldwin
2023-04-11  1:55       ` Simon Marchi
2023-03-18  1:08 ` [PATCH v4 06/13] gdb: Support XSAVE layouts for the current host in the FreeBSD x86 targets John Baldwin
2023-04-06 20:18   ` Simon Marchi
2023-04-10 21:27     ` John Baldwin
2023-04-11  2:23       ` Simon Marchi
2023-04-11 16:19         ` John Baldwin
2023-04-11 16:46           ` Simon Marchi
2023-04-11 21:37             ` John Baldwin
2023-04-11 22:35               ` John Baldwin
2023-04-12 14:35                 ` Simon Marchi
2023-03-18  1:08 ` [PATCH v4 07/13] gdb: Update x86 Linux architectures to support XSAVE layouts John Baldwin
2023-04-07  1:43   ` Simon Marchi
2023-04-10 21:29     ` John Baldwin
2023-03-18  1:09 ` [PATCH v4 08/13] gdb: Support XSAVE layouts for the current host in the Linux x86 targets John Baldwin
2023-04-07  1:54   ` Simon Marchi
2023-03-18  1:09 ` [PATCH v4 09/13] gdb: Use x86_xstate_layout to parse the XSAVE extended state area John Baldwin
2023-04-07  2:13   ` Simon Marchi
2023-04-10 21:40     ` John Baldwin
2023-03-18  1:09 ` [PATCH v4 10/13] gdbserver: Add a function to set the XSAVE mask and size John Baldwin
2023-04-12 15:08   ` Simon Marchi
2023-04-27 17:24     ` John Baldwin
2023-03-18  1:09 ` [PATCH v4 11/13] gdbserver: Refactor the legacy region within the xsave struct John Baldwin
2023-04-12 18:34   ` Simon Marchi
2023-04-27 19:51     ` John Baldwin
2023-03-18  1:09 ` [PATCH v4 12/13] gdbserver: Read offsets of the XSAVE extended region via CPUID John Baldwin
2023-04-11 14:46   ` Pedro Alves
2023-04-11 16:25     ` John Baldwin
2023-04-12 19:11   ` Simon Marchi
2023-04-12 21:07     ` John Baldwin
2023-04-13 15:07       ` Simon Marchi
2023-03-18  1:09 ` [PATCH v4 13/13] x86: Remove X86_XSTATE_SIZE and related constants John Baldwin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230318010905.14294-2-jhb@FreeBSD.org \
    --to=jhb@freebsd.org \
    --cc=aleksandar.paunovic@intel.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).