From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 2GpMIH2pX2hqXyMAWB0awg (envelope-from ) for ; Sat, 28 Jun 2025 04:36:13 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=E/cMzBbe; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 807361E11E; Sat, 28 Jun 2025 04:36:13 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-10.1 required=5.0 tests=ARC_SIGNED,ARC_VALID, BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED, RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 718541E089 for ; Sat, 28 Jun 2025 04:36:11 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 221B63856DF0 for ; Sat, 28 Jun 2025 08:36:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 221B63856DF0 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=E/cMzBbe Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.14]) by sourceware.org (Postfix) with ESMTPS id 91040385781B for ; Sat, 28 Jun 2025 08:28:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 91040385781B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 91040385781B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=192.198.163.14 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1751099335; cv=none; b=deg48JiRJyJ3XYlczNwmbVliQSKy5Ipqno6xrmZLsP7xOVjfcXbyPLRVzBTMluqYNLwduBbgXsXuzqu/t8pYFa5ceDK7y1LIk8cKNnfPBDaSPwcI8IICgaARAXAYIHWtOoG6QLxRELp6cGtM8pKD/86yr5N5zN8Qo520MsxK2W0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1751099335; c=relaxed/simple; bh=fO0/Jh3Wx5V7JuiIEjz7kAZJmOyTT7ai4RqfceddWWY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DkcmNLPFFo/KAC4/TsDuIpo9h5/FPvOR8OHB1tcGjYcAvAj27Jn6KVqRN3S+10EfJZ8Ob4leKvn3v5JA10GKrcXGUcFEcMQTSBT//wYjJgAjB/qZJpgnslhHVo3dbCmYG3Xf0rx90Vz9paYSNFHYgQ2dTkrc65JYaa2SOPxPjbY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 91040385781B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1751099335; x=1782635335; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fO0/Jh3Wx5V7JuiIEjz7kAZJmOyTT7ai4RqfceddWWY=; b=E/cMzBbengY9oqkyNfdbI3JFvQXS/JIaMoF+Jm3pnZcTcobYQlqeAqkZ i/u+HnE4v/xAyTVS843NOIlP1obuKJ15v3ezOyVOVHZEX8lKpdjcgUcyp iXdnv5+oZPwfjCZXha8hD61WU8L0dwABWzqDw1soj8rQgwr2fiWxOE5aH 98NPVUzfWOM0ZuWqi7T209G02oJS/n/nycUrGIMH0RDPh5Rtn069st0Lz wdd5wa4y2GEGN0lQk4do0b+yrgIXXwZi38/KVL0/ODDMyAhrm4OWCKMP3 vWMC97DFZS5I0X8kFxbzXxtO+aLn+jFogvgLyvlxtOkeQg9UxmooJcqUp g==; X-CSE-ConnectionGUID: 8GA7O3pZQrOiuX5Ri44WNQ== X-CSE-MsgGUID: F1ybQcFnQzyAF4KRKyrTfg== X-IronPort-AV: E=McAfee;i="6800,10657,11477"; a="53491479" X-IronPort-AV: E=Sophos;i="6.16,272,1744095600"; d="scan'208";a="53491479" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2025 01:28:54 -0700 X-CSE-ConnectionGUID: Yty1PlZ9Tl+gRvvIjx/nfg== X-CSE-MsgGUID: 6MomyjSSTG6deETgSYlpqw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,272,1744095600"; d="scan'208";a="152734138" Received: from 0007e934a912.jf.intel.com (HELO localhost) ([10.165.58.208]) by orviesa009-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2025 01:28:53 -0700 From: Christina Schimpe To: gdb-patches@sourceware.org Cc: thiago.bauermann@linaro.org, luis.machado@arm.com Subject: [PATCH v5 05/12] gdb, gdbserver: Use xstate_bv for target description creation on x86. Date: Sat, 28 Jun 2025 01:28:03 -0700 Message-ID: <20250628082810.332526-6-christina.schimpe@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250628082810.332526-1-christina.schimpe@intel.com> References: <20250628082810.332526-1-christina.schimpe@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org The XSAVE features set is organized in state components, which are a set of or parts of registers. So-called XSAVE-supported features are 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 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 Reviewed-By: Luis Machado --- 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) { 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; /* 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 -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 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 -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) -/* 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); } 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 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 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