Re: [PATCH v5 05/12] gdb, gdbserver: Use xstate_bv for target description creation on x86.

Andrew Burgess
2025-07-14T13:53:02Z

Christina Schimpe <christina.schimpe@intel.com> writes:

> The XSAVE features set is organized in state components, which are a set
> of or parts of registers. So-called XSAVE-supported features are

Maybe here you mean: "..., which are a set of, or parts of, registers."
If not, then this sentence doesn't make sense to me.

> organized using state-component bitmaps, each bit corresponding to a
> single state component.
>
> The SDM uses the term xstate_bv for a state-component bitmap, which is

Would it be possible to define what SDM it please.

> defined as XCR0 | IA32_XSS. The control register XCR0 only contains a
> state-component bitmap that specifies user state components, while IA32_XSS
> contains a state-component bitmap that specifies supervisor state components.
>
> Until now, XCR0 is used as input for target description creation in GDB.
> However, a following patch will add userspace support for the CET shadow
> stack feature by Intel. The CET state is configured in IA32_XSS and consists
> of 2 state components:
> - State component 11 used for the 2 MSRs controlling user-mode
> functionality for CET (CET_U state)
> - State component 12 used for the 3 MSRs containing shadow-stack pointers
> for privilege levels 0-2 (CET_S state).
>
> Reading the CET shadow stack pointer register on linux requires a separate
> ptrace call using NT_X86_SHSTK. To pass the CET shadow stack enablement
> state we would like to pass the xstate_bv value instead of xcr0 for target
> description creation. To prepare for that, we rename the xcr0 mask
> values for target description creation to xstate_bv. However, this
> patch doesn't add any functional changes in GDB.
>
> Future states specified in IA32_XSS such as CET will create a combined
> xstate_bv_mask including xcr0 register value and its corresponding bit in
> the state component bitmap. This combined mask will then be used to create
> the target descriptions.
>
> Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
> Reviewed-By: Luis Machado <luis.machado@arm.com>
> ---
> gdb/amd64-tdep.c | 14 +++----
> gdb/amd64-tdep.h | 8 +++-
> gdb/arch/amd64-linux-tdesc.c | 33 ++++++++--------
> gdb/arch/amd64-linux-tdesc.h | 7 ++--
> gdb/arch/amd64.c | 15 +++-----
> gdb/arch/amd64.h | 10 ++++-
> gdb/arch/i386-linux-tdesc.c | 29 +++++++-------
> gdb/arch/i386-linux-tdesc.h | 5 ++-
> gdb/arch/i386.c | 15 ++++----
> gdb/arch/i386.h | 8 +++-
> gdb/arch/x86-linux-tdesc-features.c | 59 +++++++++++++++--------------
> gdb/arch/x86-linux-tdesc-features.h | 25 +++++++-----
> gdb/i386-tdep.c | 14 +++----
> gdb/i386-tdep.h | 7 +++-
> gdb/nat/x86-linux-tdesc.c | 18 +++++----
> gdb/nat/x86-linux-tdesc.h | 7 ++--
> gdb/x86-linux-nat.c | 11 ++++--
> gdbserver/i387-fp.cc | 40 +++++++++----------
> gdbserver/linux-amd64-ipa.cc | 10 +++--
> gdbserver/linux-i386-ipa.cc | 6 +--
> gdbserver/linux-x86-low.cc | 9 ++---
> gdbsupport/x86-xstate.h | 4 +-
> 22 files changed, 198 insertions(+), 156 deletions(-)
>
> diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
> index 82dd1e07cf3..04539dd288a 100644
> --- a/gdb/amd64-tdep.c
> +++ b/gdb/amd64-tdep.c
> @@ -3551,23 +3551,23 @@ amd64_x32_none_init_abi (gdbarch_info info, gdbarch *arch)
> amd64_target_description (X86_XSTATE_SSE_MASK, true));
> }
>
> -/* Return the target description for a specified XSAVE feature mask. */
> +/* See amd64-tdep.h. */
>
> const struct target_desc *
> -amd64_target_description (uint64_t xcr0, bool segments)
> +amd64_target_description (uint64_t xstate_bv_mask, bool segments)

I'd like to ask about the use of 'mask' in this variable name. We used
to pass in an xcr0 value, which was then combined with various masks to
extract the state bits we were interested in.

You've renamed the new variable as a mask, but continue to combine it
with the same masks (e.g. X86_XSTATE_AVX), which makes me suspect the
variable is not a mask at all.

Now, I can see where the confusion might have come from. Almost every
call to amd64_target_description passes in a *_MASK constant. But
that's OK, given these are bit sets, then the MASK constants actually
define valid values.

I am aware that this sounds like a trivial complaint over a variable
name, but I think calling this a mask is pretty confusing (at least to
me), so unless I'm not understanding this, then I think it is worth
renaming this.

The use of `mask` for the value is present throughout this patch, not
just this one function.

Thanks,
Andrew

> {
> static target_desc *amd64_tdescs \
> [2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
> target_desc **tdesc;
>
> - tdesc = &amd64_tdescs[(xcr0 & X86_XSTATE_AVX) ? 1 : 0]
> - [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0]
> - [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]
> + tdesc = &amd64_tdescs[(xstate_bv_mask & X86_XSTATE_AVX) ? 1 : 0]
> + [(xstate_bv_mask & X86_XSTATE_AVX512) ? 1 : 0]
> + [(xstate_bv_mask & X86_XSTATE_PKRU) ? 1 : 0]
> [segments ? 1 : 0];
>
> if (*tdesc == NULL)
> - *tdesc = amd64_create_target_description (xcr0, false, false,
> - segments);
> + *tdesc = amd64_create_target_description (xstate_bv_mask, false,
> + false, segments);
>
> return *tdesc;
> }
> diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h
> index cbf8a97fa3c..82f781bf404 100644
> --- a/gdb/amd64-tdep.h
> +++ b/gdb/amd64-tdep.h
> @@ -108,8 +108,12 @@ extern void amd64_init_abi (struct gdbarch_info info,
> extern void amd64_x32_init_abi (struct gdbarch_info info,
> struct gdbarch *gdbarch,
> const target_desc *default_tdesc);
> -extern const struct target_desc *amd64_target_description (uint64_t xcr0,
> - bool segments);
> +
> +/* Return the target description for the specified xsave features as
> + defined in XSTATE_BV_MASK and SEGMENTS. */
> +
> +extern const struct target_desc *amd64_target_description
> + (uint64_t xstate_bv_mask, bool segments);
>
> /* Fill register REGNUM in REGCACHE with the appropriate
> floating-point or SSE register value from *FXSAVE. If REGNUM is
> diff --git a/gdb/arch/amd64-linux-tdesc.c b/gdb/arch/amd64-linux-tdesc.c
> index 91de75873a1..771badc0ca7 100644
> --- a/gdb/arch/amd64-linux-tdesc.c
> +++ b/gdb/arch/amd64-linux-tdesc.c
> @@ -26,41 +26,42 @@
> /* See arch/amd64-linux-tdesc.h. */
>
> const struct target_desc *
> -amd64_linux_read_description (uint64_t xcr0, bool is_x32)
> +amd64_linux_read_description (uint64_t xstate_bv_mask, bool is_x32)
> {
> /* The type used for the amd64 and x32 target description caches. */
> using tdesc_cache_type = std::unordered_map<uint64_t, const target_desc_up>;
>
> /* Caches for the previously seen amd64 and x32 target descriptions,
> - indexed by the xcr0 value that created the target description. These
> - need to be static within this function to ensure they are initialised
> - before first use. */
> + indexed by the xstate_bv_mask value that created the target
> + description. These need to be static within this function to ensure
> + they are initialised before first use. */
> static tdesc_cache_type amd64_tdesc_cache, x32_tdesc_cache;
>
> tdesc_cache_type &tdesc_cache = is_x32 ? x32_tdesc_cache : amd64_tdesc_cache;
>
> - /* Only some bits are checked when creating a tdesc, but the XCR0 value
> - contains other feature bits that are not relevant for tdesc creation.
> - When indexing into the TDESC_CACHE we need to use a consistent xcr0
> - value otherwise we might fail to find an existing tdesc which has the
> - same set of relevant bits set. */
> - xcr0 &= is_x32
> - ? x86_linux_x32_xcr0_feature_mask ()
> - : x86_linux_amd64_xcr0_feature_mask ();
> + /* Only some bits are checked when creating a tdesc, but the
> + xstate_bv_mask value contains other feature bits that are not
> + relevant for tdesc creation.
> + When indexing into the TDESC_CACHE we need to use a consistent
> + xstate_bv_mask value otherwise we might fail to find an existing
> + tdesc which has the same set of relevant bits set. */
> + xstate_bv_mask &= is_x32
> + ? x86_linux_x32_xstate_bv_feature_mask ()
> + : x86_linux_amd64_xstate_bv_feature_mask ();
>
> - const auto it = tdesc_cache.find (xcr0);
> + const auto it = tdesc_cache.find (xstate_bv_mask);
> if (it != tdesc_cache.end ())
> return it->second.get ();
>
> /* Create the previously unseen target description. */
> - target_desc_up tdesc (amd64_create_target_description (xcr0, is_x32,
> - true, true));
> + target_desc_up tdesc (amd64_create_target_description (xstate_bv_mask,
> + is_x32, true, true));
> x86_linux_post_init_tdesc (tdesc.get (), true);
>
> /* Add to the cache, and return a pointer borrowed from the
> target_desc_up. This is safe as the cache (and the pointers contained
> within it) are not deleted until GDB exits. */
> target_desc *ptr = tdesc.get ();
> - tdesc_cache.emplace (xcr0, std::move (tdesc));
> + tdesc_cache.emplace (xstate_bv_mask, std::move (tdesc));
> return ptr;
> }
> diff --git a/gdb/arch/amd64-linux-tdesc.h b/gdb/arch/amd64-linux-tdesc.h
> index 8806a132562..0d0e1bbff72 100644
> --- a/gdb/arch/amd64-linux-tdesc.h
> +++ b/gdb/arch/amd64-linux-tdesc.h
> @@ -22,9 +22,10 @@
>
> struct target_desc;
>
> -/* Return the AMD64 target descriptions corresponding to XCR0 and IS_X32. */
> +/* Return the AMD64 target descriptions corresponding to XSTATE_BV_MASK
> + and IS_X32. */
>
> -extern const target_desc *amd64_linux_read_description (uint64_t xcr0,
> - bool is_x32);
> +extern const target_desc *amd64_linux_read_description
> + (uint64_t xstate_bv_mask, bool is_x32);
>
> #endif /* GDB_ARCH_AMD64_LINUX_TDESC_H */
> diff --git a/gdb/arch/amd64.c b/gdb/arch/amd64.c
> index 252650b6390..3181f827356 100644
> --- a/gdb/arch/amd64.c
> +++ b/gdb/arch/amd64.c
> @@ -30,14 +30,11 @@
>
> #include "../features/i386/x32-core.c"
>
> -/* Create amd64 target descriptions according to XCR0. If IS_X32 is
> - true, create the x32 ones. If IS_LINUX is true, create target
> - descriptions for Linux. If SEGMENTS is true, then include
> - the "org.gnu.gdb.i386.segments" feature registers. */
> +/* See arch/amd64.h. */
>
> target_desc *
> -amd64_create_target_description (uint64_t xcr0, bool is_x32, bool is_linux,
> - bool segments)
> +amd64_create_target_description (uint64_t xstate_bv_mask, bool is_x32,
> + bool is_linux, bool segments)
> {
> target_desc_up tdesc = allocate_target_description ();
>
> @@ -62,13 +59,13 @@ amd64_create_target_description (uint64_t xcr0, bool is_x32, bool is_linux,
> if (segments)
> regnum = create_feature_i386_64bit_segments (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_AVX)
> + if (xstate_bv_mask & X86_XSTATE_AVX)
> regnum = create_feature_i386_64bit_avx (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_AVX512)
> + if (xstate_bv_mask & X86_XSTATE_AVX512)
> regnum = create_feature_i386_64bit_avx512 (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_PKRU)
> + if (xstate_bv_mask & X86_XSTATE_PKRU)
> regnum = create_feature_i386_pkeys (tdesc.get (), regnum);
>
> return tdesc.release ();
> diff --git a/gdb/arch/amd64.h b/gdb/arch/amd64.h
> index 695660c55d6..54080ee10a9 100644
> --- a/gdb/arch/amd64.h
> +++ b/gdb/arch/amd64.h
> @@ -21,7 +21,13 @@
> #include "gdbsupport/tdesc.h"
> #include <stdint.h>
>
> -target_desc *amd64_create_target_description (uint64_t xcr0, bool is_x32,
> - bool is_linux, bool segments);
> +/* Create amd64 target descriptions according to XSTATE_BV_MASK. If
> + IS_X32 is true, create the x32 ones. If IS_LINUX is true, create
> + target descriptions for Linux. If SEGMENTS is true, then include
> + the "org.gnu.gdb.i386.segments" feature registers. */
> +
> +target_desc *amd64_create_target_description (uint64_t xstate_bv_mask,
> + bool is_x32, bool is_linux,
> + bool segments);
>
> #endif /* GDB_ARCH_AMD64_H */
> diff --git a/gdb/arch/i386-linux-tdesc.c b/gdb/arch/i386-linux-tdesc.c
> index 51513176464..57cdbbfa7e5 100644
> --- a/gdb/arch/i386-linux-tdesc.c
> +++ b/gdb/arch/i386-linux-tdesc.c
> @@ -25,32 +25,35 @@
> /* See arch/i386-linux-tdesc.h. */
>
> const target_desc *
> -i386_linux_read_description (uint64_t xcr0)
> +i386_linux_read_description (uint64_t xstate_bv_mask)
> {
> - /* Cache of previously seen i386 target descriptions, indexed by the xcr0
> - value that created the target description. This needs to be static
> - within this function to ensure it is initialised before first use. */
> + /* Cache of previously seen i386 target descriptions, indexed by the
> + xstate_bv_mask value that created the target description. This
> + needs to be static within this function to ensure it is initialised
> + before first use. */
> static std::unordered_map<uint64_t, const target_desc_up> i386_tdesc_cache;
>
> - /* Only some bits are checked when creating a tdesc, but the XCR0 value
> - contains other feature bits that are not relevant for tdesc creation.
> - When indexing into the I386_TDESC_CACHE we need to use a consistent
> - xcr0 value otherwise we might fail to find an existing tdesc which has
> - the same set of relevant bits set. */
> - xcr0 &= x86_linux_i386_xcr0_feature_mask ();
> + /* Only some bits are checked when creating a tdesc, but the
> + XSTATE_BV_MASK value contains other feature bits that are not
> + relevant for tdesc creation. When indexing into the I386_TDESC_CACHE
> + we need to use a consistent XSTATE_BV_MASK value otherwise we might
> + fail to find an existing tdesc which has the same set of relevant
> + bits set. */
> + xstate_bv_mask &= x86_linux_i386_xstate_bv_feature_mask ();
>
> - const auto it = i386_tdesc_cache.find (xcr0);
> + const auto it = i386_tdesc_cache.find (xstate_bv_mask);
> if (it != i386_tdesc_cache.end ())
> return it->second.get ();
>
> /* Create the previously unseen target description. */
> - target_desc_up tdesc (i386_create_target_description (xcr0, true, false));
> + target_desc_up tdesc
> + (i386_create_target_description (xstate_bv_mask, true, false));
> x86_linux_post_init_tdesc (tdesc.get (), false);
>
> /* Add to the cache, and return a pointer borrowed from the
> target_desc_up. This is safe as the cache (and the pointers contained
> within it) are not deleted until GDB exits. */
> target_desc *ptr = tdesc.get ();
> - i386_tdesc_cache.emplace (xcr0, std::move (tdesc));
> + i386_tdesc_cache.emplace (xstate_bv_mask, std::move (tdesc));
> return ptr;
> }
> diff --git a/gdb/arch/i386-linux-tdesc.h b/gdb/arch/i386-linux-tdesc.h
> index 2c3c1740d81..3392b3fa06e 100644
> --- a/gdb/arch/i386-linux-tdesc.h
> +++ b/gdb/arch/i386-linux-tdesc.h
> @@ -22,8 +22,9 @@
>
> struct target_desc;
>
> -/* Return the i386 target description corresponding to XCR0. */
> +/* Return the i386 target description corresponding to XSTATE_BV_MASK. */
>
> -extern const struct target_desc *i386_linux_read_description (uint64_t xcr0);
> +extern const struct target_desc *i386_linux_read_description
> + (uint64_t xstate_bv_mask);
>
> #endif /* GDB_ARCH_I386_LINUX_TDESC_H */
> diff --git a/gdb/arch/i386.c b/gdb/arch/i386.c
> index 835df53c75d..e04d8c5dd94 100644
> --- a/gdb/arch/i386.c
> +++ b/gdb/arch/i386.c
> @@ -29,10 +29,11 @@
> #include "../features/i386/32bit-segments.c"
> #include "../features/i386/pkeys.c"
>
> -/* Create i386 target descriptions according to XCR0. */
> +/* See arch/i386.h. */
>
> target_desc *
> -i386_create_target_description (uint64_t xcr0, bool is_linux, bool segments)
> +i386_create_target_description (uint64_t xstate_bv_mask, bool is_linux,
> + bool segments)
> {
> target_desc_up tdesc = allocate_target_description ();
>
> @@ -44,10 +45,10 @@ i386_create_target_description (uint64_t xcr0, bool is_linux, bool segments)
>
> long regnum = 0;
>
> - if (xcr0 & X86_XSTATE_X87)
> + if (xstate_bv_mask & X86_XSTATE_X87)
> regnum = create_feature_i386_32bit_core (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_SSE)
> + if (xstate_bv_mask & X86_XSTATE_SSE)
> regnum = create_feature_i386_32bit_sse (tdesc.get (), regnum);
>
> if (is_linux)
> @@ -56,13 +57,13 @@ i386_create_target_description (uint64_t xcr0, bool is_linux, bool segments)
> if (segments)
> regnum = create_feature_i386_32bit_segments (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_AVX)
> + if (xstate_bv_mask & X86_XSTATE_AVX)
> regnum = create_feature_i386_32bit_avx (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_AVX512)
> + if (xstate_bv_mask & X86_XSTATE_AVX512)
> regnum = create_feature_i386_32bit_avx512 (tdesc.get (), regnum);
>
> - if (xcr0 & X86_XSTATE_PKRU)
> + if (xstate_bv_mask & X86_XSTATE_PKRU)
> regnum = create_feature_i386_pkeys (tdesc.get (), regnum);
>
> return tdesc.release ();
> diff --git a/gdb/arch/i386.h b/gdb/arch/i386.h
> index 1fc41014624..a23deebc366 100644
> --- a/gdb/arch/i386.h
> +++ b/gdb/arch/i386.h
> @@ -21,7 +21,13 @@
> #include "gdbsupport/tdesc.h"
> #include <stdint.h>
>
> -target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux,
> +/* Create i386 target descriptions according to XSTATE_BV_MASK. If
> + IS_LINUX is true, create target descriptions for Linux. If SEGMENTS
> + is true, then include the "org.gnu.gdb.i386.segments" feature
> + registers. */
> +
> +target_desc *i386_create_target_description (uint64_t xstate_bv_mask,
> + bool is_linux,
> bool segments);
>
> #endif /* GDB_ARCH_I386_H */
> diff --git a/gdb/arch/x86-linux-tdesc-features.c b/gdb/arch/x86-linux-tdesc-features.c
> index f65920cb95b..68f37fccaef 100644
> --- a/gdb/arch/x86-linux-tdesc-features.c
> +++ b/gdb/arch/x86-linux-tdesc-features.c
> @@ -28,18 +28,21 @@
>
> We want to cache target descriptions, and this is currently done in
> three separate caches, one each for i386, amd64, and x32. Additionally,
> - the caching we're discussing here is Linux only, and for Linux, the only
> - thing that has an impact on target description creation is the xcr0
> - value.
> -
> - In order to ensure the cache functions correctly we need to filter out
> - only those xcr0 feature bits that are relevant, we can then cache target
> - descriptions based on the relevant feature bits. Two xcr0 values might
> - be different, but have the same relevant feature bits. In this case we
> - would expect the two xcr0 values to map to the same cache entry. */
> + the caching we're discussing here is Linux only. Currently for Linux,
> + the only thing that has an impact on target description creation are
> + the supported features in xsave which are modelled by a xstate_bv_mask
> + value, which has the same format than the state component bitmap.
> +
> + In order to ensure the cache functions correctly we need to filter only
> + those xstate_bv_mask feature bits that are relevant, we can then cache
> + target descriptions based on the relevant feature bits. Two
> + xstate_bv_mask values might be different, but have the same relevant
> + feature bits. In this case we would expect the two xstate_bv_mask
> + values to map to the same cache entry. */
>
> struct x86_xstate_feature {
> - /* The xstate feature mask. This is a mask against an xcr0 value. */
> + /* The xstate feature mask. This is a mask against the state component
> + bitmap. */
> uint64_t feature;
>
> /* Is this feature checked when creating an i386 target description. */
> @@ -56,9 +59,9 @@ struct x86_xstate_feature {
> checked when building a target description for i386, amd64, or x32.
>
> If in the future, due to simplifications or refactoring, this table ever
> - ends up with 'true' for every xcr0 feature on every target type, then this
> - is an indication that this table should probably be removed, and that the
> - rest of the code in this file can be simplified. */
> + ends up with 'true' for every xsave feature on every target type, then
> + this is an indication that this table should probably be removed, and
> + that the rest of the code in this file can be simplified. */
>
> static constexpr x86_xstate_feature x86_linux_all_xstate_features[] = {
> /* Feature, i386, amd64, x32. */
> @@ -73,7 +76,7 @@ static constexpr x86_xstate_feature x86_linux_all_xstate_features[] = {
> that are checked for when building an i386 target description. */
>
> static constexpr uint64_t
> -x86_linux_i386_xcr0_feature_mask_1 ()
> +x86_linux_i386_xstate_bv_feature_mask_1 ()
> {
> uint64_t mask = 0;
>
> @@ -88,7 +91,7 @@ x86_linux_i386_xcr0_feature_mask_1 ()
> that are checked for when building an amd64 target description. */
>
> static constexpr uint64_t
> -x86_linux_amd64_xcr0_feature_mask_1 ()
> +x86_linux_amd64_xstate_bv_feature_mask_1 ()
> {
> uint64_t mask = 0;
>
> @@ -103,7 +106,7 @@ x86_linux_amd64_xcr0_feature_mask_1 ()
> that are checked for when building an x32 target description. */
>
> static constexpr uint64_t
> -x86_linux_x32_xcr0_feature_mask_1 ()
> +x86_linux_x32_xstate_bv_feature_mask_1 ()
> {
> uint64_t mask = 0;
>
> @@ -117,25 +120,25 @@ x86_linux_x32_xcr0_feature_mask_1 ()
> /* See arch/x86-linux-tdesc-features.h. */
>
> uint64_t
> -x86_linux_i386_xcr0_feature_mask ()
> +x86_linux_i386_xstate_bv_feature_mask ()
> {
> - return x86_linux_i386_xcr0_feature_mask_1 ();
> + return x86_linux_i386_xstate_bv_feature_mask_1 ();
> }
>
> /* See arch/x86-linux-tdesc-features.h. */
>
> uint64_t
> -x86_linux_amd64_xcr0_feature_mask ()
> +x86_linux_amd64_xstate_bv_feature_mask ()
> {
> - return x86_linux_amd64_xcr0_feature_mask_1 ();
> + return x86_linux_amd64_xstate_bv_feature_mask_1 ();
> }
>
> /* See arch/x86-linux-tdesc-features.h. */
>
> uint64_t
> -x86_linux_x32_xcr0_feature_mask ()
> +x86_linux_x32_xstate_bv_feature_mask ()
> {
> - return x86_linux_x32_xcr0_feature_mask_1 ();
> + return x86_linux_x32_xstate_bv_feature_mask_1 ();
> }
>
> #ifdef GDBSERVER
> @@ -143,7 +146,7 @@ x86_linux_x32_xcr0_feature_mask ()
> /* See arch/x86-linux-tdesc-features.h. */
>
> int
> -x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0)
> +x86_linux_xstate_bv_mask_to_tdesc_idx (uint64_t xstate_bv_mask)
> {
> /* The following table shows which features are checked for when creating
> the target descriptions (see nat/x86-linux-tdesc.c), the feature order
> @@ -160,7 +163,7 @@ x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0)
>
> for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i)
> {
> - if ((xcr0 & x86_linux_all_xstate_features[i].feature)
> + if ((xstate_bv_mask & x86_linux_all_xstate_features[i].feature)
> == x86_linux_all_xstate_features[i].feature)
> idx |= (1 << i);
> }
> @@ -250,17 +253,17 @@ x86_linux_i386_tdesc_count ()
> /* See arch/x86-linux-tdesc-features.h. */
>
> uint64_t
> -x86_linux_tdesc_idx_to_xcr0 (int idx)
> +x86_linux_tdesc_idx_to_xstate_bv_mask (int idx)
> {
> - uint64_t xcr0 = 0;
> + uint64_t xstate_bv_mask = 0;
>
> for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i)
> {
> if ((idx & (1 << i)) != 0)
> - xcr0 |= x86_linux_all_xstate_features[i].feature;
> + xstate_bv_mask |= x86_linux_all_xstate_features[i].feature;
> }
>
> - return xcr0;
> + return xstate_bv_mask;
> }
>
> #endif /* IN_PROCESS_AGENT */
> diff --git a/gdb/arch/x86-linux-tdesc-features.h b/gdb/arch/x86-linux-tdesc-features.h
> index 89fe7cecc68..d1d74e70df8 100644
> --- a/gdb/arch/x86-linux-tdesc-features.h
> +++ b/gdb/arch/x86-linux-tdesc-features.h
> @@ -27,17 +27,20 @@
> the set of features which are checked for when creating the target
> description for each of amd64, x32, and i386. */
>
> -extern uint64_t x86_linux_amd64_xcr0_feature_mask ();
> -extern uint64_t x86_linux_x32_xcr0_feature_mask ();
> -extern uint64_t x86_linux_i386_xcr0_feature_mask ();
> +extern uint64_t x86_linux_amd64_xstate_bv_feature_mask ();
> +extern uint64_t x86_linux_x32_xstate_bv_feature_mask ();
> +extern uint64_t x86_linux_i386_xstate_bv_feature_mask ();
>
> #ifdef GDBSERVER
>
> -/* Convert an xcr0 value into an integer. The integer will be passed from
> +/* Convert an XSTATE_BV_MASK value into an integer. XSTATE_BV_MASK has
> + the same format than the state component bitmap and does include user
> + and supervisor state components. The integer will be passed from
> gdbserver to the in-process-agent where it will then be passed through
> - x86_linux_tdesc_idx_to_xcr0 to get back the original xcr0 value. */
> + x86_linux_tdesc_idx_to_xstate_bv_mask to get back the original mask. */
>
> -extern int x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0);
> +
> +extern int x86_linux_xstate_bv_mask_to_tdesc_idx (uint64_t xstate_bv_mask);
>
> #endif /* GDBSERVER */
>
> @@ -51,11 +54,13 @@ extern int x86_linux_amd64_tdesc_count ();
> extern int x86_linux_x32_tdesc_count ();
> extern int x86_linux_i386_tdesc_count ();
>
> -/* Convert an index number (as returned from x86_linux_xcr0_to_tdesc_idx)
> - into an xcr0 value which can then be used to create a target
> - description. */
> +/* Convert an index number (as returned from
> + x86_linux_xstate_bv_mask_to_tdesc_idx) into an xstate_bv_mask
> + value which can then be used to create a target description.
> + The return mask has the same format than the state component bitmap
> + and does include user and supervisor state components.*/
>
> -extern uint64_t x86_linux_tdesc_idx_to_xcr0 (int idx);
> +extern uint64_t x86_linux_tdesc_idx_to_xstate_bv_mask (int idx);
>
> #endif /* IN_PROCESS_AGENT */
>
> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
> index 9be4748c880..90ff0c5c706 100644
> --- a/gdb/i386-tdep.c
> +++ b/gdb/i386-tdep.c
> @@ -8949,23 +8949,23 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>
> \f
>
> -/* Return the target description for a specified XSAVE feature mask. */
> +/* See i386-tdep.h. */
>
> const struct target_desc *
> -i386_target_description (uint64_t xcr0, bool segments)
> +i386_target_description (uint64_t xstate_bv_mask, bool segments)
> {
> static target_desc *i386_tdescs \
> [2/*SSE*/][2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
> target_desc **tdesc;
>
> - tdesc = &i386_tdescs[(xcr0 & X86_XSTATE_SSE) ? 1 : 0]
> - [(xcr0 & X86_XSTATE_AVX) ? 1 : 0]
> - [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0]
> - [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]
> + tdesc = &i386_tdescs[(xstate_bv_mask & X86_XSTATE_SSE) ? 1 : 0]
> + [(xstate_bv_mask & X86_XSTATE_AVX) ? 1 : 0]
> + [(xstate_bv_mask & X86_XSTATE_AVX512) ? 1 : 0]
> + [(xstate_bv_mask & X86_XSTATE_PKRU) ? 1 : 0]
> [segments ? 1 : 0];
>
> if (*tdesc == NULL)
> - *tdesc = i386_create_target_description (xcr0, false, segments);
> + *tdesc = i386_create_target_description (xstate_bv_mask, false, segments);
>
> return *tdesc;
> }
> diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
> index e849b336e12..239bc8674e8 100644
> --- a/gdb/i386-tdep.h
> +++ b/gdb/i386-tdep.h
> @@ -450,8 +450,11 @@ extern int i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg);
>
> extern int i386_process_record (struct gdbarch *gdbarch,
> struct regcache *regcache, CORE_ADDR addr);
> -extern const struct target_desc *i386_target_description (uint64_t xcr0,
> - bool segments);
> +
> +/* Return the target description for the specified xsave features as
> + defined in XSTATE_BV_MASK and SEGMENTS. */
> +extern const struct target_desc *i386_target_description
> + (uint64_t xstate_bv_mask, bool segments);
>
> /* Functions and variables exported from i386-bsd-tdep.c. */
>
> diff --git a/gdb/nat/x86-linux-tdesc.c b/gdb/nat/x86-linux-tdesc.c
> index 80e4337a270..e9cf2527c5f 100644
> --- a/gdb/nat/x86-linux-tdesc.c
> +++ b/gdb/nat/x86-linux-tdesc.c
> @@ -43,7 +43,7 @@
> /* See nat/x86-linux-tdesc.h. */
>
> const target_desc *
> -x86_linux_tdesc_for_tid (int tid, uint64_t *xcr0_storage,
> +x86_linux_tdesc_for_tid (int tid, uint64_t *xstate_bv_storage,
> x86_xsave_layout *xsave_layout_storage)
> {
> #ifdef __x86_64__
> @@ -96,30 +96,32 @@ x86_linux_tdesc_for_tid (int tid, uint64_t *xcr0_storage,
> these bits being set we generate a completely empty tdesc for
> i386 which will be rejected by GDB. */
> have_ptrace_getregset = TRIBOOL_FALSE;
> - *xcr0_storage = X86_XSTATE_SSE_MASK;
> + *xstate_bv_storage = X86_XSTATE_SSE_MASK;
> }
> else
> {
> have_ptrace_getregset = TRIBOOL_TRUE;
>
> /* Get XCR0 from XSAVE extended state. */
> - *xcr0_storage = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
> + uint64_t xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
> / sizeof (uint64_t))];
>
> *xsave_layout_storage
> - = x86_fetch_xsave_layout (*xcr0_storage, x86_xsave_length ());
> + = x86_fetch_xsave_layout (xcr0, x86_xsave_length ());
> +
> + *xstate_bv_storage = xcr0;
> }
> }
>
> - /* Use cached xcr0 value. */
> - uint64_t xcr0_features_bits = *xcr0_storage & X86_XSTATE_ALL_MASK;
> + /* Use cached XSTATE_BV_STORAGE value. */
> + uint64_t xstate_bv_features_bits = *xstate_bv_storage & X86_XSTATE_ALL_MASK;
>
> #ifdef __x86_64__
> if (is_64bit)
> - return amd64_linux_read_description (xcr0_features_bits, is_x32);
> + return amd64_linux_read_description (xstate_bv_features_bits, is_x32);
> else
> #endif
> - return i386_linux_read_description (xcr0_features_bits);
> + return i386_linux_read_description (xstate_bv_features_bits);
> }
>
> #endif /* !IN_PROCESS_AGENT */
> diff --git a/gdb/nat/x86-linux-tdesc.h b/gdb/nat/x86-linux-tdesc.h
> index 38c71f10df2..19aa84f6b3f 100644
> --- a/gdb/nat/x86-linux-tdesc.h
> +++ b/gdb/nat/x86-linux-tdesc.h
> @@ -27,9 +27,9 @@ struct x86_xsave_layout;
>
> /* Return the target description for Linux thread TID.
>
> - The storage pointed to by XCR0_STORAGE and XSAVE_LAYOUT_STORAGE must
> + The storage pointed to by XSTATE_BV_STORAGE and XSAVE_LAYOUT_STORAGE must
> exist until the program (GDB or gdbserver) terminates, this storage is
> - used to cache the xcr0 and xsave layout values. The values pointed to
> + used to cache the xstate_bv and xsave layout values. The values pointed to
> by these arguments are only updated at most once, the first time this
> function is called if the have_ptrace_getregset global is set to
> TRIBOOL_UNKNOWN.
> @@ -45,6 +45,7 @@ struct x86_xsave_layout;
> returned. */
>
> extern const target_desc *x86_linux_tdesc_for_tid
> - (int tid, uint64_t *xcr0_storage, x86_xsave_layout *xsave_layout_storage);
> + (int tid, uint64_t *xstate_bv_storage,
> + x86_xsave_layout *xsave_layout_storage);
>
> #endif /* GDB_NAT_X86_LINUX_TDESC_H */
> diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
> index 81db5d86a5e..1b7dd8506dd 100644
> --- a/gdb/x86-linux-nat.c
> +++ b/gdb/x86-linux-nat.c
> @@ -97,15 +97,20 @@ const struct target_desc *
> x86_linux_nat_target::read_description ()
> {
> /* The x86_linux_tdesc_for_tid call only reads xcr0 the first time it is
> - called, the xcr0 value is stored here and reused on subsequent calls. */
> - static uint64_t xcr0_storage;
> + called. The mask is stored in XSTATE_BV_STORAGE and reused on
> + subsequent calls. Note that GDB currently supports features for user
> + state components only. However, once supervisor state components are
> + supported in GDB, the value XSTATE_BV_STORAGE will not be configured
> + based on xcr0 only. */
> + static uint64_t xstate_bv_storage;
>
> if (inferior_ptid == null_ptid)
> return this->beneath ()->read_description ();
>
> int tid = inferior_ptid.pid ();
>
> - return x86_linux_tdesc_for_tid (tid, &xcr0_storage, &this->m_xsave_layout);
> + return x86_linux_tdesc_for_tid (tid, &xstate_bv_storage,
> + &this->m_xsave_layout);
> }
> \f
>
> diff --git a/gdbserver/i387-fp.cc b/gdbserver/i387-fp.cc
> index 4be0083a6fb..90824bdaee5 100644
> --- a/gdbserver/i387-fp.cc
> +++ b/gdbserver/i387-fp.cc
> @@ -21,7 +21,7 @@
> #include "nat/x86-xstate.h"
>
> /* Default to SSE. */
> -static uint64_t x86_xcr0 = X86_XSTATE_SSE_MASK;
> +static uint64_t x86_xstate_bv = X86_XSTATE_SSE_MASK;
>
> static const int num_avx512_k_registers = 8;
> static const int num_pkeys_registers = 1;
> @@ -265,7 +265,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
>
> /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
> vector registers if its bit in xstat_bv is zero. */
> - clear_bv = (~fp->xstate_bv) & x86_xcr0;
> + clear_bv = (~fp->xstate_bv) & x86_xstate_bv;
>
> /* Clear part in x87 and vector registers if its bit in xstat_bv is
> zero. */
> @@ -315,7 +315,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any x87 registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_X87))
> + if ((x86_xstate_bv & X86_XSTATE_X87))
> {
> int st0_regnum = find_regno (regcache->tdesc, "st0");
>
> @@ -332,7 +332,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any SSE registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_SSE))
> + if ((x86_xstate_bv & X86_XSTATE_SSE))
> {
> int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
>
> @@ -349,7 +349,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any AVX registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_AVX))
> + if ((x86_xstate_bv & X86_XSTATE_AVX))
> {
> int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
>
> @@ -366,7 +366,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any K registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_K))
> + if ((x86_xstate_bv & X86_XSTATE_K))
> {
> int k0_regnum = find_regno (regcache->tdesc, "k0");
>
> @@ -383,7 +383,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any of ZMM0H-ZMM15H registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_ZMM_H))
> + if ((x86_xstate_bv & X86_XSTATE_ZMM_H))
> {
> int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
>
> @@ -400,7 +400,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any of ZMM16-ZMM31 registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_ZMM) && num_zmm_high_registers != 0)
> + if ((x86_xstate_bv & X86_XSTATE_ZMM) && num_zmm_high_registers != 0)
> {
> int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
> int ymm16h_regnum = find_regno (regcache->tdesc, "ymm16h");
> @@ -437,7 +437,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
>
> /* Check if any PKEYS registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_PKRU))
> + if ((x86_xstate_bv & X86_XSTATE_PKRU))
> {
> int pkru_regnum = find_regno (regcache->tdesc, "pkru");
>
> @@ -453,7 +453,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_SSE) || (x86_xcr0 & X86_XSTATE_AVX))
> + if ((x86_xstate_bv & X86_XSTATE_SSE) || (x86_xstate_bv & X86_XSTATE_AVX))
> {
> collect_register_by_name (regcache, "mxcsr", raw);
> if (memcmp (raw, &fp->mxcsr, 4) != 0)
> @@ -465,7 +465,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
> }
> }
>
> - if (x86_xcr0 & X86_XSTATE_X87)
> + if (x86_xstate_bv & X86_XSTATE_X87)
> {
> collect_register_by_name (regcache, "fioff", raw);
> if (memcmp (raw, &fp->fioff, 4) != 0)
> @@ -658,10 +658,10 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
>
> /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
> vector registers if its bit in xstat_bv is zero. */
> - clear_bv = (~fp->xstate_bv) & x86_xcr0;
> + clear_bv = (~fp->xstate_bv) & x86_xstate_bv;
>
> /* Check if any x87 registers are changed. */
> - if ((x86_xcr0 & X86_XSTATE_X87) != 0)
> + if ((x86_xstate_bv & X86_XSTATE_X87) != 0)
> {
> int st0_regnum = find_regno (regcache->tdesc, "st0");
>
> @@ -678,7 +678,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_SSE) != 0)
> + if ((x86_xstate_bv & X86_XSTATE_SSE) != 0)
> {
> int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
>
> @@ -695,7 +695,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_AVX) != 0)
> + if ((x86_xstate_bv & X86_XSTATE_AVX) != 0)
> {
> int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
>
> @@ -712,7 +712,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_K) != 0)
> + if ((x86_xstate_bv & X86_XSTATE_K) != 0)
> {
> int k0_regnum = find_regno (regcache->tdesc, "k0");
>
> @@ -729,7 +729,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_ZMM_H) != 0)
> + if ((x86_xstate_bv & X86_XSTATE_ZMM_H) != 0)
> {
> int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
>
> @@ -746,7 +746,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_ZMM) != 0 && num_zmm_high_registers != 0)
> + if ((x86_xstate_bv & X86_XSTATE_ZMM) != 0 && num_zmm_high_registers != 0)
> {
> int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
> int ymm16h_regnum = find_regno (regcache->tdesc, "ymm16h");
> @@ -773,7 +773,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> }
> }
>
> - if ((x86_xcr0 & X86_XSTATE_PKRU) != 0)
> + if ((x86_xstate_bv & X86_XSTATE_PKRU) != 0)
> {
> int pkru_regnum = find_regno (regcache->tdesc, "pkru");
>
> @@ -858,5 +858,5 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
> std::pair<uint64_t *, x86_xsave_layout *>
> i387_get_xsave_storage ()
> {
> - return { &x86_xcr0, &xsave_layout };
> + return { &x86_xstate_bv, &xsave_layout };
> }
> diff --git a/gdbserver/linux-amd64-ipa.cc b/gdbserver/linux-amd64-ipa.cc
> index af4eb03b9b8..75d70a8787c 100644
> --- a/gdbserver/linux-amd64-ipa.cc
> +++ b/gdbserver/linux-amd64-ipa.cc
> @@ -82,7 +82,7 @@ get_raw_reg (const unsigned char *raw_regs, int regnum)
> const struct target_desc *
> get_ipa_tdesc (int idx)
> {
> - uint64_t xcr0 = x86_linux_tdesc_idx_to_xcr0 (idx);
> + uint64_t xstate_bv_mask = x86_linux_tdesc_idx_to_xstate_bv_mask (idx);
>
> #if defined __ILP32__
> bool is_x32 = true;
> @@ -90,7 +90,7 @@ get_ipa_tdesc (int idx)
> bool is_x32 = false;
> #endif
>
> - return amd64_linux_read_description (xcr0, is_x32);
> + return amd64_linux_read_description (xstate_bv_mask, is_x32);
> }
>
> /* Allocate buffer for the jump pads. The branch instruction has a
> @@ -159,9 +159,11 @@ initialize_low_tracepoint (void)
> {
> #if defined __ILP32__
> for (int i = 0; i < x86_linux_x32_tdesc_count (); i++)
> - amd64_linux_read_description (x86_linux_tdesc_idx_to_xcr0 (i), true);
> + amd64_linux_read_description
> + (x86_linux_tdesc_idx_to_xstate_bv_mask (i), true);
> #else
> for (int i = 0; i < x86_linux_amd64_tdesc_count (); i++)
> - amd64_linux_read_description (x86_linux_tdesc_idx_to_xcr0 (i), false);
> + amd64_linux_read_description
> + (x86_linux_tdesc_idx_to_xstate_bv_mask (i), false);
> #endif
> }
> diff --git a/gdbserver/linux-i386-ipa.cc b/gdbserver/linux-i386-ipa.cc
> index 17af6eb3610..1a0393d127c 100644
> --- a/gdbserver/linux-i386-ipa.cc
> +++ b/gdbserver/linux-i386-ipa.cc
> @@ -174,9 +174,9 @@ initialize_fast_tracepoint_trampoline_buffer (void)
> const struct target_desc *
> get_ipa_tdesc (int idx)
> {
> - uint64_t xcr0 = x86_linux_tdesc_idx_to_xcr0 (idx);
> + uint64_t xstate_bv_mask = x86_linux_tdesc_idx_to_xstate_bv_mask (idx);
>
> - return i386_linux_read_description (xcr0);
> + return i386_linux_read_description (xstate_bv_mask);
> }
>
> /* Allocate buffer for the jump pads. On i386, we can reach an arbitrary
> @@ -199,5 +199,5 @@ initialize_low_tracepoint (void)
> {
> initialize_fast_tracepoint_trampoline_buffer ();
> for (int i = 0; i < x86_linux_i386_tdesc_count (); i++)
> - i386_linux_read_description (x86_linux_tdesc_idx_to_xcr0 (i));
> + i386_linux_read_description (x86_linux_tdesc_idx_to_xstate_bv_mask (i));
> }
> diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
> index 24920e71a53..dbc11d6856d 100644
> --- a/gdbserver/linux-x86-low.cc
> +++ b/gdbserver/linux-x86-low.cc
> @@ -873,7 +873,7 @@ x86_linux_read_description ()
> bool have_ptrace_getregset_was_unknown
> = have_ptrace_getregset == TRIBOOL_UNKNOWN;
>
> - /* Get pointers to where we should store the xcr0 and xsave_layout
> + /* Get pointers to where we should store the xstate_bv and xsave_layout
> values. These will be filled in by x86_linux_tdesc_for_tid the first
> time that the function is called. Subsequent calls will not modify
> the stored values. */
> @@ -2892,17 +2892,16 @@ x86_target::get_ipa_tdesc_idx ()
> || tdesc == tdesc_amd64_linux_no_xml.get ()
> #endif /* __x86_64__ */
> );
> - return x86_linux_xcr0_to_tdesc_idx (X86_XSTATE_SSE_MASK);
> + return x86_linux_xstate_bv_mask_to_tdesc_idx (X86_XSTATE_SSE_MASK);
> }
>
> - /* The xcr0 value and xsave layout value are cached when the target
> + /* The xstate_bv value and xsave layout value are cached when the target
> description is read. Grab their cache location, and use the cached
> value to calculate a tdesc index. */
> std::pair<uint64_t *, x86_xsave_layout *> storage
> = i387_get_xsave_storage ();
> - uint64_t xcr0 = *storage.first;
>
> - return x86_linux_xcr0_to_tdesc_idx (xcr0);
> + return x86_linux_xstate_bv_mask_to_tdesc_idx (*storage.first);
> }
>
> /* The linux target ops object. */
> diff --git a/gdbsupport/x86-xstate.h b/gdbsupport/x86-xstate.h
> index 5d563ff4622..9bb373c3100 100644
> --- a/gdbsupport/x86-xstate.h
> +++ b/gdbsupport/x86-xstate.h
> @@ -83,8 +83,10 @@ constexpr bool operator!= (const x86_xsave_layout &lhs,
> #define X86_XSTATE_AVX_AVX512_PKU_MASK (X86_XSTATE_AVX_MASK\
> | X86_XSTATE_AVX512 | X86_XSTATE_PKRU)
>
> -#define X86_XSTATE_ALL_MASK (X86_XSTATE_AVX_AVX512_PKU_MASK)
> +/* Supported mask of state-component bitmap xstate_bv. The SDM defines
> + xstate_bv as XCR0 | IA32_XSS. */
>
> +#define X86_XSTATE_ALL_MASK (X86_XSTATE_AVX_AVX512_PKU_MASK)
>
> #define X86_XSTATE_SSE_SIZE 576
> #define X86_XSTATE_AVX_SIZE 832
> --
> 2.43.0