From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 3qznBeTsmGhbWgkAWB0awg (envelope-from ) for ; Sun, 10 Aug 2025 15:03:00 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=if9Dj/yL; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 05B5D1E10A; Sun, 10 Aug 2025 15:03:00 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-9.1 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,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 44FF41E091 for ; Sun, 10 Aug 2025 15:02:58 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C0AD53858C41 for ; Sun, 10 Aug 2025 19:02:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C0AD53858C41 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=if9Dj/yL Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by sourceware.org (Postfix) with ESMTPS id DCE543858D21 for ; Sun, 10 Aug 2025 19:02:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DCE543858D21 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DCE543858D21 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::112b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1754852525; cv=none; b=TZuTzfQlZzJ9bIr0t32v2Ubx66BRdkaJsXqmP8JjY+di9QMg7QbF3z2h/2Boq6nv8AKTRNiZ0bb8zbdml+629BIFYqNjKn8KkU1CUCMBDIW8x4J/utN2pSfAgbifAlbqg6ePs/RMjoZsIGMn4cDFK+ePyqDFQ2KQXVvoy1OQSYA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1754852525; c=relaxed/simple; bh=XSusAGKVfls4lbrcnhjmWTv79jadlA+MHTFyy/UB9gk=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=PkvAC4KCSzk2hOmweQyCn/VI5OUtP+5l5GNcdr8RwwchRTlxli/Tx+tacC3GPxtPdGFsJwRePlOBzTPxVEtRjIs8lMBItU+9QiExrinQaOk360lOaXzHQ8Kzv3m5APrRZdXtU0KR2a1PECk5rcpRQheYXuhPgrcTQXWAyfDyrZw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DCE543858D21 Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-71a379cecd5so19510237b3.1 for ; Sun, 10 Aug 2025 12:02:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1754852524; x=1755457324; darn=sourceware.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=RDzQqGSAyQ6c9yBfTBL4+JZIUy+ruVD/esI+Lk2WsWE=; b=if9Dj/yL6SMZE8neufitXFHAvnpezklzdUEGeH5CMftJVtR1uLO4QjXgvB1CrIODh/ 6XwBJnMBfrbXLq+LLbtOWxSVS+M9EpeK2EWJ+qr66jx62A4vBsNIklWHZfw62rLpNXnD YsswM30HhoDegK4T9FBvrbTgz9gSHrmdYxtqtx2D3t0+nfSBgxyUP44VhDgZa2NMYXnd 5f8eldRxF78/v0pHhTwkb6Ee2EPwRC6zmbHDLPPrqJ39rfCjkVgdGRfwloqHzBlH+fLj zZvN6TOUHleqicmPBOL8wnhedm8f19e/CQyNuIQem5155+9L2h+p8qHMw7dJ0p0y1iAG F6vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754852524; x=1755457324; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RDzQqGSAyQ6c9yBfTBL4+JZIUy+ruVD/esI+Lk2WsWE=; b=pVUkA/wX7+aMfutwCsYSEz7mZlRpmDhHXe1bzEZiVxtvqW/e9/hN501N+KtcoL6uN2 gg43vccHrRhh9eHotYT00Zr5yDGTrVr/JCqhU+NXZVRC+PIE80Y8/jZwyz6Hcm7jc13U JqDuqcziCQhM/jjuTdymel07LLx8yhhAVdSCzB2NI2KHK/i9pg9GJe3nlwNPt3laDg+R 9ieezrz2262hIDPSLt2tJKo2It7Yb0/pyVAauM5em5ZDuZvZzzAvzMDKcL5Si3b3il2j zt5vmnf1cjMhvWywzXCQyee6M6W22lnwC74575/NF848y3q1SHXxszp5Z5FCIEKB2Xz0 JrAA== X-Gm-Message-State: AOJu0Yz+QQM/qHC1qcRM2dyaCU/O3MU4w+TaBWSu+X2tGEyUaatkuq2d 2/9G4DFtxLNX0ZvK6lePsbevmuwg+mxoLt2Z0APKTr8h4ehTH2iHHrtYXHXAsFBtLVItqRrGRdW 0Pfy+ge/PamyFzgvj7kcr7NkktvAXQpg= X-Gm-Gg: ASbGncucapwOWISrOFfs0j+J7bGc0DgDFzMU8DRw8ISU7Ui9+2IYgynuYJtTVzkQN1o lKRNeeIPHNueVcKRQr6Nt2VfSaAo5gi8QinfHg8LiguLA2KEV6lRpibo8L6GyQ6actx0mHRSyPd eXQiJIC71/nHqdlH70MPhoLSGNNAOird87hGRbQEIUikXjOIlvARcicCsD/7oTRBVysM5lSnUeW 63fRhzr X-Google-Smtp-Source: AGHT+IEtJvUbFa7cV3gF/5RST4FnllwPOSBVAKU3w/UTJeZDKJhM0PBWewvqQ/+mWFS6WmtO3GNv5+ZVrYQsBGUtCdc= X-Received: by 2002:a05:690c:4441:b0:71a:3484:abfe with SMTP id 00721157ae682-71bf0ec5153mr114957827b3.38.1754852523656; Sun, 10 Aug 2025 12:02:03 -0700 (PDT) MIME-Version: 1.0 References: <20250628082810.332526-1-christina.schimpe@intel.com> <20250628082810.332526-7-christina.schimpe@intel.com> In-Reply-To: <20250628082810.332526-7-christina.schimpe@intel.com> From: "H.J. Lu" Date: Sun, 10 Aug 2025 12:01:27 -0700 X-Gm-Features: Ac12FXygPgYIrvVE8hOCPZn50kICdwE6j_VALN9J_riPWtIyuDfjxRn4ZaoF370 Message-ID: Subject: Re: [PATCH v5 06/12] gdb, gdbserver: Add support of Intel shadow stack pointer register. To: Christina Schimpe Cc: gdb-patches@sourceware.org, thiago.bauermann@linaro.org, luis.machado@arm.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 On Sat, Jun 28, 2025 at 1:32=E2=80=AFAM Christina Schimpe wrote: > > This patch adds the user mode register PL3_SSP which is part of the > Intel(R) Control-Flow Enforcement Technology (CET) feature for support > of shadow stack. > For now, only native and remote debugging support for shadow stack > userspace on amd64 linux are covered by this patch including 64 bit and > x32 support. 32 bit support is not covered due to missing Linux kernel > support. > > This patch requires fixing the test gdb.base/inline-frame-cycle-unwind > which is failing in case the shadow stack pointer is unavailable. > Such a state is possible if shadow stack is disabled for the current thre= ad > but supported by HW. > > This test uses the Python unwinder inline-frame-cycle-unwind.py which fak= es > the cyclic stack cycle by reading the pending frame's registers and addin= g > them to the unwinder: > > ~~~ > for reg in pending_frame.architecture().registers("general"): > val =3D pending_frame.read_register(reg) > unwinder.add_saved_register(reg, val) > return unwinder > ~~~ > > However, in case the python unwinder is used we add a register (pl3_ssp) = that is > unavailable. This leads to a NOT_AVAILABLE_ERROR caught in > gdb/frame-unwind.c:frame_unwind_try_unwinder and it is continued with sta= ndard > unwinders. This destroys the faked cyclic behavior and the stack is > further unwinded after frame 5. > > In the working scenario an error should be triggered: > ~~~ > bt > 0 inline_func () at /tmp/gdb.base/inline-frame-cycle-unwind.c:49^M > 1 normal_func () at /tmp/gdb.base/inline-frame-cycle-unwind.c:32^M > 2 0x000055555555516e in inline_func () at /tmp/gdb.base/inline-frame-cyc= le-unwind.c:45^M > 3 normal_func () at /tmp/gdb.base/inline-frame-cycle-unwind.c:32^M > 4 0x000055555555516e in inline_func () at /tmp/gdb.base/inline-frame-cyc= le-unwind.c:45^M > 5 normal_func () at /tmp/gdb.base/inline-frame-cycle-unwind.c:32^M > Backtrace stopped: previous frame identical to this frame (corrupt stack?= ) > (gdb) PASS: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 5: bac= ktrace when the unwind is broken at frame 5 > ~~~ > > To fix the Python unwinder, we simply skip the unavailable registers. > > Reviewed-by: Thiago Jung Bauermann > Reviewed-By: Eli Zaretskii > Reviewed-By: Luis Machado > --- > gdb/NEWS | 3 + > gdb/amd64-linux-nat.c | 17 +++++ > gdb/amd64-linux-tdep.c | 1 + > gdb/amd64-tdep.c | 6 +- > gdb/amd64-tdep.h | 1 + > gdb/arch/amd64.c | 10 +++ > gdb/arch/i386.c | 4 ++ > gdb/arch/x86-linux-tdesc-features.c | 1 + > gdb/doc/gdb.texinfo | 4 ++ > gdb/features/Makefile | 2 + > gdb/features/i386/32bit-ssp.c | 14 ++++ > gdb/features/i386/32bit-ssp.xml | 11 +++ > gdb/features/i386/64bit-ssp.c | 14 ++++ > gdb/features/i386/64bit-ssp.xml | 11 +++ > gdb/i386-tdep.c | 22 +++++- > gdb/i386-tdep.h | 4 ++ > gdb/nat/x86-linux-tdesc.c | 2 + > gdb/nat/x86-linux.c | 57 +++++++++++++++ > gdb/nat/x86-linux.h | 4 ++ > gdb/testsuite/gdb.arch/amd64-shadow-stack.c | 22 ++++++ > gdb/testsuite/gdb.arch/amd64-ssp.exp | 50 +++++++++++++ > .../gdb.base/inline-frame-cycle-unwind.py | 4 ++ > gdb/testsuite/lib/gdb.exp | 70 +++++++++++++++++++ > gdb/x86-linux-nat.c | 49 +++++++++++-- > gdb/x86-linux-nat.h | 11 +++ > gdb/x86-tdep.c | 21 ++++++ > gdb/x86-tdep.h | 9 +++ > gdbserver/linux-x86-low.cc | 28 +++++++- > gdbsupport/x86-xstate.h | 5 +- > 29 files changed, 447 insertions(+), 10 deletions(-) > create mode 100644 gdb/features/i386/32bit-ssp.c > create mode 100644 gdb/features/i386/32bit-ssp.xml > create mode 100644 gdb/features/i386/64bit-ssp.c > create mode 100644 gdb/features/i386/64bit-ssp.xml > create mode 100644 gdb/testsuite/gdb.arch/amd64-shadow-stack.c > create mode 100644 gdb/testsuite/gdb.arch/amd64-ssp.exp > > diff --git a/gdb/NEWS b/gdb/NEWS > index 6c8a008d39d..ba555f0dea1 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -3,6 +3,9 @@ > > *** Changes since GDB 16 > > +* Support for the shadow stack pointer register on x86-64 or x86-64 with > + 32-bit pointer size (X32) GNU/Linux. > + > * Debugger Adapter Protocol changes > > ** GDB now supports the "completions" request. > diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c > index dbb9b3223cb..4df99ccca54 100644 > --- a/gdb/amd64-linux-nat.c > +++ b/gdb/amd64-linux-nat.c > @@ -32,6 +32,7 @@ > #include "amd64-tdep.h" > #include "amd64-linux-tdep.h" > #include "i386-linux-tdep.h" > +#include "x86-tdep.h" > #include "gdbsupport/x86-xstate.h" > > #include "x86-linux-nat.h" > @@ -237,6 +238,14 @@ amd64_linux_nat_target::fetch_registers (struct regc= ache *regcache, int regnum) > > if (have_ptrace_getregset =3D=3D TRIBOOL_TRUE) > { > + if ((regnum =3D=3D -1 && tdep->ssp_regnum > 0) > + || (regnum !=3D -1 && regnum =3D=3D tdep->ssp_regnum)) > + { > + x86_linux_fetch_ssp (regcache, tid); > + if (regnum !=3D -1) > + return; > + } > + > /* Pre-4.14 kernels have a bug (fixed by commit 0852b374173b > "x86/fpu: Add FPU state copying quirk to handle XRSTOR failu= re on > Intel Skylake CPUs") that sometimes causes the mxcsr locatio= n in > @@ -302,6 +311,14 @@ amd64_linux_nat_target::store_registers (struct regc= ache *regcache, int regnum) > if (have_ptrace_getregset =3D=3D TRIBOOL_TRUE) > { > gdb::byte_vector xstateregs (tdep->xsave_layout.sizeof_xsave); > + if ((regnum =3D=3D -1 && tdep->ssp_regnum > 0) > + || (regnum !=3D -1 && regnum =3D=3D tdep->ssp_regnum)) > + { > + x86_linux_store_ssp (regcache, tid); > + if (regnum !=3D -1) > + return; > + } > + > struct iovec iov; > > iov.iov_base =3D xstateregs.data (); > diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c > index 13e9c0e86ea..edb7d8da6ab 100644 > --- a/gdb/amd64-linux-tdep.c > +++ b/gdb/amd64-linux-tdep.c > @@ -108,6 +108,7 @@ int amd64_linux_gregset_reg_offset[] =3D > -1, -1, -1, -1, -1, -1, -1, -1, > -1, -1, -1, -1, -1, -1, -1, -1, > -1, /* PKEYS register pkru */ > + -1, /* CET user mode register PL3_SSP. */ > > /* End of hardware registers */ > 21 * 8, 22 * 8, /* fs_base and gs_base. */ > diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c > index 04539dd288a..450dbc38047 100644 > --- a/gdb/amd64-tdep.c > +++ b/gdb/amd64-tdep.c > @@ -3395,6 +3395,9 @@ amd64_init_abi (struct gdbarch_info info, struct gd= barch *gdbarch, > tdep->num_pkeys_regs =3D 1; > } > > + if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pl3_ssp") !=3D nullpt= r) > + tdep->ssp_regnum =3D AMD64_PL3_SSP_REGNUM; > + > tdep->num_byte_regs =3D 20; > tdep->num_word_regs =3D 16; > tdep->num_dword_regs =3D 16; > @@ -3557,12 +3560,13 @@ const struct target_desc * > amd64_target_description (uint64_t xstate_bv_mask, bool segments) > { > static target_desc *amd64_tdescs \ > - [2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] =3D {}; > + [2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*CET_U*/][2/*segments*/] =3D {}= ; > target_desc **tdesc; > > tdesc =3D &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] > + [(xstate_bv_mask & X86_XSTATE_CET_U) ? 1 : 0] > [segments ? 1 : 0]; > > if (*tdesc =3D=3D NULL) > diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h > index 82f781bf404..eb294f3dfbe 100644 > --- a/gdb/amd64-tdep.h > +++ b/gdb/amd64-tdep.h > @@ -81,6 +81,7 @@ enum amd64_regnum > AMD64_ZMM0H_REGNUM, > AMD64_ZMM31H_REGNUM =3D AMD64_ZMM0H_REGNUM + 31, > AMD64_PKRU_REGNUM, > + AMD64_PL3_SSP_REGNUM, > AMD64_FSBASE_REGNUM, > AMD64_GSBASE_REGNUM > }; > diff --git a/gdb/arch/amd64.c b/gdb/arch/amd64.c > index 3181f827356..c9925fa6b66 100644 > --- a/gdb/arch/amd64.c > +++ b/gdb/arch/amd64.c > @@ -28,6 +28,8 @@ > #include "../features/i386/64bit-sse.c" > #include "../features/i386/pkeys.c" > > +#include "../features/i386/64bit-ssp.c" > +#include "../features/i386/32bit-ssp.c" > #include "../features/i386/x32-core.c" > > /* See arch/amd64.h. */ > @@ -68,5 +70,13 @@ amd64_create_target_description (uint64_t xstate_bv_ma= sk, bool is_x32, > if (xstate_bv_mask & X86_XSTATE_PKRU) > regnum =3D create_feature_i386_pkeys (tdesc.get (), regnum); > > + if (xstate_bv_mask & X86_XSTATE_CET_U) > + { > + if (!is_x32) > + regnum =3D create_feature_i386_64bit_ssp (tdesc.get (), regnum); > + else > + regnum =3D create_feature_i386_32bit_ssp (tdesc.get (), regnum); > + } > + > return tdesc.release (); > } > diff --git a/gdb/arch/i386.c b/gdb/arch/i386.c > index e04d8c5dd94..87058e32dcb 100644 > --- a/gdb/arch/i386.c > +++ b/gdb/arch/i386.c > @@ -28,6 +28,7 @@ > #include "../features/i386/32bit-avx512.c" > #include "../features/i386/32bit-segments.c" > #include "../features/i386/pkeys.c" > +#include "../features/i386/32bit-ssp.c" > > /* See arch/i386.h. */ > > @@ -66,5 +67,8 @@ i386_create_target_description (uint64_t xstate_bv_mask= , bool is_linux, > if (xstate_bv_mask & X86_XSTATE_PKRU) > regnum =3D create_feature_i386_pkeys (tdesc.get (), regnum); > > + if (xstate_bv_mask & X86_XSTATE_CET_U) > + regnum =3D create_feature_i386_32bit_ssp (tdesc.get (), regnum); > + > return tdesc.release (); > } > diff --git a/gdb/arch/x86-linux-tdesc-features.c b/gdb/arch/x86-linux-tde= sc-features.c > index 68f37fccaef..f288f120cfb 100644 > --- a/gdb/arch/x86-linux-tdesc-features.c > +++ b/gdb/arch/x86-linux-tdesc-features.c > @@ -65,6 +65,7 @@ struct x86_xstate_feature { > > static constexpr x86_xstate_feature x86_linux_all_xstate_features[] =3D = { > /* Feature, i386, amd64, x32. */ > + { X86_XSTATE_CET_U, false, true, true }, > { X86_XSTATE_PKRU, true, true, true }, > { X86_XSTATE_AVX512, true, true, true }, > { X86_XSTATE_AVX, true, true, true }, > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 4ef640698bd..0881ac4aee5 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -49959,6 +49959,10 @@ The @samp{org.gnu.gdb.i386.pkeys} feature is opt= ional. It should > describe a single register, @samp{pkru}. It is a 32-bit register > valid for i386 and amd64. > > +The @samp{org.gnu.gdb.i386.pl3_ssp} feature is optional. It should desc= ribe the > +user mode register @samp{pl3_ssp} which has 64 bits on amd64. Following= the > +restriction of the Linux kernel, only amd64 is supported for now. > + > @node LoongArch Features > @subsection LoongArch Features > @cindex target descriptions, LoongArch Features > diff --git a/gdb/features/Makefile b/gdb/features/Makefile > index 7a8c7999733..2afda1ccd00 100644 > --- a/gdb/features/Makefile > +++ b/gdb/features/Makefile > @@ -225,6 +225,7 @@ FEATURE_XMLFILES =3D aarch64-core.xml \ > i386/32bit-avx.xml \ > i386/32bit-avx512.xml \ > i386/32bit-segments.xml \ > + i386/32bit-ssp.xml \ > i386/64bit-avx512.xml \ > i386/64bit-core.xml \ > i386/64bit-segments.xml \ > @@ -232,6 +233,7 @@ FEATURE_XMLFILES =3D aarch64-core.xml \ > i386/64bit-linux.xml \ > i386/64bit-sse.xml \ > i386/pkeys.xml \ > + i386/64bit-ssp.xml \ > i386/x32-core.xml \ > loongarch/base32.xml \ > loongarch/base64.xml \ > diff --git a/gdb/features/i386/32bit-ssp.c b/gdb/features/i386/32bit-ssp.= c > new file mode 100644 > index 00000000000..991bae3c1e6 > --- /dev/null > +++ b/gdb/features/i386/32bit-ssp.c > @@ -0,0 +1,14 @@ > +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: > + Original: 32bit-ssp.xml */ > + > +#include "gdbsupport/tdesc.h" > + > +static int > +create_feature_i386_32bit_ssp (struct target_desc *result, long regnum) > +{ > + struct tdesc_feature *feature; > + > + feature =3D tdesc_create_feature (result, "org.gnu.gdb.i386.pl3_ssp"); > + tdesc_create_reg (feature, "pl3_ssp", regnum++, 1, NULL, 32, "data_ptr= "); > + return regnum; > +} > diff --git a/gdb/features/i386/32bit-ssp.xml b/gdb/features/i386/32bit-ss= p.xml > new file mode 100644 > index 00000000000..d17e7004eec > --- /dev/null > +++ b/gdb/features/i386/32bit-ssp.xml > @@ -0,0 +1,11 @@ > + > + > + > + > + > + > + > diff --git a/gdb/features/i386/64bit-ssp.c b/gdb/features/i386/64bit-ssp.= c > new file mode 100644 > index 00000000000..5468099ddf6 > --- /dev/null > +++ b/gdb/features/i386/64bit-ssp.c > @@ -0,0 +1,14 @@ > +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: > + Original: 64bit-ssp.xml */ > + > +#include "gdbsupport/tdesc.h" > + > +static int > +create_feature_i386_64bit_ssp (struct target_desc *result, long regnum) > +{ > + struct tdesc_feature *feature; > + > + feature =3D tdesc_create_feature (result, "org.gnu.gdb.i386.pl3_ssp"); > + tdesc_create_reg (feature, "pl3_ssp", regnum++, 1, NULL, 64, "data_ptr= "); > + return regnum; > +} > diff --git a/gdb/features/i386/64bit-ssp.xml b/gdb/features/i386/64bit-ss= p.xml > new file mode 100644 > index 00000000000..a0688d018a5 > --- /dev/null > +++ b/gdb/features/i386/64bit-ssp.xml > @@ -0,0 +1,11 @@ > + > + > + > + > + > + > + > diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c > index 90ff0c5c706..8eb5b4fac86 100644 > --- a/gdb/i386-tdep.c > +++ b/gdb/i386-tdep.c > @@ -8403,7 +8403,8 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep, > const struct tdesc_feature *feature_core; > > const struct tdesc_feature *feature_sse, *feature_avx, *feature_avx512= , > - *feature_pkeys, *feature_segments; > + *feature_pkeys, *feature_segments, > + *feature_pl3_ssp; > int i, num_regs, valid_p; > > if (! tdesc_has_registers (tdesc)) > @@ -8429,6 +8430,9 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep, > /* Try PKEYS */ > feature_pkeys =3D tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys")= ; > > + /* Try Shadow Stack. */ > + feature_pl3_ssp =3D tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pl3_s= sp"); > + > valid_p =3D 1; > > /* The XCR0 bits. */ > @@ -8544,6 +8548,15 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep, > tdep->pkeys_register_names[i]= ); > } > > + if (feature_pl3_ssp !=3D nullptr) > + { > + if (tdep->ssp_regnum < 0) > + tdep->ssp_regnum =3D I386_PL3_SSP_REGNUM; > + > + valid_p &=3D tdesc_numbered_register (feature_pl3_ssp, tdesc_data, > + tdep->ssp_regnum, "pl3_ssp"); > + } > + > return valid_p; > } > > @@ -8835,6 +8848,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct= gdbarch_list *arches) > /* No segment base registers. */ > tdep->fsbase_regnum =3D -1; > > + /* No shadow stack pointer register. */ > + tdep->ssp_regnum =3D -1; > + > tdesc_arch_data_up tdesc_data =3D tdesc_data_alloc (); > > set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction); > @@ -8955,13 +8971,15 @@ const struct target_desc * > 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*/] =3D {}; > + [2/*SSE*/][2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*CET_U*/] \ > + [2/*segments*/] =3D {}; > target_desc **tdesc; > > tdesc =3D &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] > + [(xstate_bv_mask & X86_XSTATE_CET_U) ? 1 : 0] > [segments ? 1 : 0]; > > if (*tdesc =3D=3D NULL) > diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h > index 239bc8674e8..60d6f3eb732 100644 > --- a/gdb/i386-tdep.h > +++ b/gdb/i386-tdep.h > @@ -191,6 +191,9 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base > /* PKEYS register names. */ > const char * const *pkeys_register_names =3D nullptr; > > + /* Shadow stack pointer register. */ > + int ssp_regnum =3D 0; > + > /* Register number for %fsbase. Set this to -1 to indicate the > absence of segment base registers. */ > int fsbase_regnum =3D 0; > @@ -293,6 +296,7 @@ enum i386_regnum > I386_ZMM0H_REGNUM, /* %zmm0h */ > I386_ZMM7H_REGNUM =3D I386_ZMM0H_REGNUM + 7, > I386_PKRU_REGNUM, > + I386_PL3_SSP_REGNUM, > I386_FSBASE_REGNUM, > I386_GSBASE_REGNUM > }; > diff --git a/gdb/nat/x86-linux-tdesc.c b/gdb/nat/x86-linux-tdesc.c > index e9cf2527c5f..5bc36b6bef2 100644 > --- a/gdb/nat/x86-linux-tdesc.c > +++ b/gdb/nat/x86-linux-tdesc.c > @@ -110,6 +110,8 @@ x86_linux_tdesc_for_tid (int tid, uint64_t *xstate_bv= _storage, > =3D x86_fetch_xsave_layout (xcr0, x86_xsave_length ()); > > *xstate_bv_storage =3D xcr0; > + if (x86_check_ssp_support (tid)) > + *xstate_bv_storage |=3D X86_XSTATE_CET_U; > } > } > > diff --git a/gdb/nat/x86-linux.c b/gdb/nat/x86-linux.c > index 0bdff736f8a..1756d5441fc 100644 > --- a/gdb/nat/x86-linux.c > +++ b/gdb/nat/x86-linux.c > @@ -17,6 +17,12 @@ > You should have received a copy of the GNU General Public License > along with this program. If not, see .= */ > > +#include "elf/common.h" > +#include "gdbsupport/common-defs.h" > +#include "nat/gdb_ptrace.h" > +#include "nat/linux-ptrace.h" > +#include "nat/x86-cpuid.h" > +#include > #include "x86-linux.h" > #include "x86-linux-dregs.h" > #include "nat/gdb_ptrace.h" > @@ -126,3 +132,54 @@ x86_linux_ptrace_get_arch_size (int tid) > return x86_linux_arch_size (false, false); > #endif > } > + > +/* See nat/x86-linux.h. */ > + > +bool > +x86_check_ssp_support (const int tid) > +{ > + /* It's not enough to check shadow stack support with the ptrace call > + below only, as we cannot distinguish between shadow stack not enabl= ed > + for the current thread and shadow stack is not supported by HW. In > + both scenarios the ptrace call fails with ENODEV. In case shadow > + stack is not enabled for the current thread, we still want to retur= n > + true. */ > + unsigned int eax, ebx, ecx, edx; > + > + __get_cpuid_count (7, 0, &eax, &ebx, &ecx, &edx); It should be if (! __get_cpuid_count (7, 0, &eax, &ebx, &ecx, &edx)) return false; > + > + if ((ecx & bit_SHSTK) =3D=3D 0) > + return false; > + H.J.