mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
gdb, gdbserver: Use xstate_bv for target description creation on x86.
The XSAVE function set is organized in state components, which are a set of registers or parts of registers. So-called XSAVE-supported features are organized using state-component bitmaps, each bit corresponding to a single state component. The Intel Software Developer's Manual uses the term xstate_bv for a state-component bitmap, which is 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> Approved-By: Luis Machado <luis.machado@arm.com>
This commit is contained in:
@@ -3568,23 +3568,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, bool segments)
|
||||
{
|
||||
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 & X86_XSTATE_AVX) ? 1 : 0]
|
||||
[(xstate_bv & X86_XSTATE_AVX512) ? 1 : 0]
|
||||
[(xstate_bv & 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, false,
|
||||
false, segments);
|
||||
|
||||
return *tdesc;
|
||||
}
|
||||
|
||||
@@ -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 and SEGMENTS. */
|
||||
|
||||
extern const struct target_desc *amd64_target_description
|
||||
(uint64_t xstate_bv, bool segments);
|
||||
|
||||
/* Fill register REGNUM in REGCACHE with the appropriate
|
||||
floating-point or SSE register value from *FXSAVE. If REGNUM is
|
||||
|
||||
@@ -26,34 +26,35 @@
|
||||
/* 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, 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 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 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 value otherwise we might fail to find an existing
|
||||
tdesc which has the same set of relevant bits set. */
|
||||
xstate_bv &= 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);
|
||||
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,
|
||||
target_desc_up tdesc (amd64_create_target_description (xstate_bv, is_x32,
|
||||
true, true));
|
||||
x86_linux_post_init_tdesc (tdesc.get (), true);
|
||||
|
||||
@@ -61,6 +62,6 @@ amd64_linux_read_description (uint64_t xcr0, bool is_x32)
|
||||
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, std::move (tdesc));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -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 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, bool is_x32);
|
||||
|
||||
#endif /* GDB_ARCH_AMD64_LINUX_TDESC_H */
|
||||
|
||||
@@ -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, 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 & X86_XSTATE_AVX)
|
||||
regnum = create_feature_i386_64bit_avx (tdesc.get (), regnum);
|
||||
|
||||
if (xcr0 & X86_XSTATE_AVX512)
|
||||
if (xstate_bv & X86_XSTATE_AVX512)
|
||||
regnum = create_feature_i386_64bit_avx512 (tdesc.get (), regnum);
|
||||
|
||||
if (xcr0 & X86_XSTATE_PKRU)
|
||||
if (xstate_bv & X86_XSTATE_PKRU)
|
||||
regnum = create_feature_i386_pkeys (tdesc.get (), regnum);
|
||||
|
||||
return tdesc.release ();
|
||||
|
||||
@@ -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. 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,
|
||||
bool is_x32, bool is_linux,
|
||||
bool segments);
|
||||
|
||||
#endif /* GDB_ARCH_AMD64_H */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
/* 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 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 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 value otherwise we might fail
|
||||
to find an existing tdesc which has the same set of relevant bits
|
||||
set. */
|
||||
xstate_bv &= x86_linux_i386_xstate_bv_feature_mask ();
|
||||
|
||||
const auto it = i386_tdesc_cache.find (xcr0);
|
||||
const auto it = i386_tdesc_cache.find (xstate_bv);
|
||||
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, 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, std::move (tdesc));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
|
||||
struct target_desc;
|
||||
|
||||
/* Return the i386 target description corresponding to XCR0. */
|
||||
/* Return the i386 target description corresponding to XSTATE_BV. */
|
||||
|
||||
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);
|
||||
|
||||
#endif /* GDB_ARCH_I386_LINUX_TDESC_H */
|
||||
|
||||
@@ -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, 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 & X86_XSTATE_X87)
|
||||
regnum = create_feature_i386_32bit_core (tdesc.get (), regnum);
|
||||
|
||||
if (xcr0 & X86_XSTATE_SSE)
|
||||
if (xstate_bv & 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 & X86_XSTATE_AVX)
|
||||
regnum = create_feature_i386_32bit_avx (tdesc.get (), regnum);
|
||||
|
||||
if (xcr0 & X86_XSTATE_AVX512)
|
||||
if (xstate_bv & X86_XSTATE_AVX512)
|
||||
regnum = create_feature_i386_32bit_avx512 (tdesc.get (), regnum);
|
||||
|
||||
if (xcr0 & X86_XSTATE_PKRU)
|
||||
if (xstate_bv & X86_XSTATE_PKRU)
|
||||
regnum = create_feature_i386_pkeys (tdesc.get (), regnum);
|
||||
|
||||
return tdesc.release ();
|
||||
|
||||
@@ -21,7 +21,12 @@
|
||||
#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. 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,
|
||||
bool is_linux,
|
||||
bool segments);
|
||||
|
||||
#endif /* GDB_ARCH_I386_H */
|
||||
|
||||
@@ -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.
|
||||
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
|
||||
value, which has the same format than the state component bitmap.
|
||||
|
||||
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. */
|
||||
In order to ensure the cache functions correctly we need to filter only
|
||||
those xstate_bv feature bits that are relevant, we can then cache
|
||||
target descriptions based on the relevant feature bits. Two xstate_bv
|
||||
values might be different, but have the same relevant feature bits. In
|
||||
this case we would expect the two xstate_bv 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_to_tdesc_idx (uint64_t xstate_bv)
|
||||
{
|
||||
/* 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 & 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 (int idx)
|
||||
{
|
||||
uint64_t xcr0 = 0;
|
||||
uint64_t xstate_bv = 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 |= x86_linux_all_xstate_features[i].feature;
|
||||
}
|
||||
|
||||
return xcr0;
|
||||
return xstate_bv;
|
||||
}
|
||||
|
||||
#endif /* IN_PROCESS_AGENT */
|
||||
|
||||
@@ -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
|
||||
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. */
|
||||
/* Convert an XSTATE_BV value into an integer. XSTATE_BV 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_xstate_bv to get back the original value. */
|
||||
|
||||
extern int x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0);
|
||||
|
||||
extern int x86_linux_xstate_bv_to_tdesc_idx (uint64_t xstate_bv);
|
||||
|
||||
#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_to_tdesc_idx) into an xstate_bv 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 (int idx);
|
||||
|
||||
#endif /* IN_PROCESS_AGENT */
|
||||
|
||||
|
||||
@@ -9097,23 +9097,23 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
|
||||
|
||||
|
||||
/* 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, 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 & X86_XSTATE_SSE) ? 1 : 0]
|
||||
[(xstate_bv & X86_XSTATE_AVX) ? 1 : 0]
|
||||
[(xstate_bv & X86_XSTATE_AVX512) ? 1 : 0]
|
||||
[(xstate_bv & 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, false, segments);
|
||||
|
||||
return *tdesc;
|
||||
}
|
||||
|
||||
@@ -454,8 +454,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 and SEGMENTS. */
|
||||
extern const struct target_desc *i386_target_description
|
||||
(uint64_t xstate_bv, bool segments);
|
||||
|
||||
/* Functions and variables exported from i386-bsd-tdep.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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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 = x86_linux_tdesc_idx_to_xstate_bv (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, 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 (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 (i), false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -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 = x86_linux_tdesc_idx_to_xstate_bv (idx);
|
||||
|
||||
return i386_linux_read_description (xcr0);
|
||||
return i386_linux_read_description (xstate_bv);
|
||||
}
|
||||
|
||||
/* 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 (i));
|
||||
}
|
||||
|
||||
@@ -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_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_to_tdesc_idx (*storage.first);
|
||||
}
|
||||
|
||||
/* The linux target ops object. */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user