From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id bN3BL1yfAmpaHDIAWB0awg (envelope-from ) for ; Mon, 11 May 2026 23:32:44 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=w0fLnlHR; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id A803C1E093; Mon, 11 May 2026 23:32:44 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (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 737531E093 for ; Mon, 11 May 2026 23:32:43 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8768F4BB58BD for ; Tue, 12 May 2026 03:32:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8768F4BB58BD Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=w0fLnlHR Received: from mail-dy1-x1329.google.com (mail-dy1-x1329.google.com [IPv6:2607:f8b0:4864:20::1329]) by sourceware.org (Postfix) with ESMTPS id 7FBE24BB3BC4 for ; Tue, 12 May 2026 03:32:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7FBE24BB3BC4 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7FBE24BB3BC4 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1329 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778556725; cv=none; b=F5tvLlGlc5bkGPN1f87Nu1ddVLiasmNPYShZX3Er5nfgzNnnhkxCuJ3/dvz38s2uNmJfuEQoLq0PF3+Ic1/j51CWE/2miiQMrkrFeYNYf2NPXqCQvehsZGi8AB9ZAT0eJNNguMb2n3KFIEQnIc49VPN33LMtVz86QphPO7IHDWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778556725; c=relaxed/simple; bh=T/uEVcmaBWO9YuzV/CM2HCmJXX0KOXAOGVqzUYmyy0o=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ajsfn2/KTp37OjzPmDFrJ7FyOZH86LfUhpZ0KXcMO1EmX+Z5vIBBydBXnqe/cPDlEsQq+TNpOGPaB0mnf7xlJo6FLFOyjVPHlnhJajV4+3no32ZzpbmyUetMHbG3c43eRPRRpBgNAO+3ql+Z9KXOxA8ScuU2EK0sSBan6Jv/33s= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=w0fLnlHR DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7FBE24BB3BC4 Received: by mail-dy1-x1329.google.com with SMTP id 5a478bee46e88-2ef2a1cc06dso8822311eec.0 for ; Mon, 11 May 2026 20:32:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1778556724; x=1779161524; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:user-agent :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jcxxtcprrhctmOr1oXJyo+msZRxkTFGbPKVdnY1FKs4=; b=w0fLnlHR/JgIAUHhDheN0aeTXkKi9UJnToXGu1ZkBnDNvS2vu/fZLOt6JSbn3HNKig LwktIx47HuuU4TuUT0zuYwsZFAzSmnw6Wy+1EFoBVRxQ+2+Bq7Vdke1/BIJJE7kc3e59 jrA+iz/10+sPQItp3sqKXqRpE49eJwzuQ7vW5bhT3sdKDa3McdelIC12ecMT83doLaIZ uIU/+cGiSgqdLGHZ8LOYcjiGeJYQCB7N6Moj3QvhQExUKk1yRUpUWSCmujGzSzfR2elL EwLwr2XLcrpKWrxogGsH+iFnq3tbCE6iAkNtzhYbQEASALQcaZHOUZYGk9aTzL8IbAmh 4GfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778556724; x=1779161524; h=content-transfer-encoding:mime-version:message-id:date:user-agent :references:in-reply-to:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jcxxtcprrhctmOr1oXJyo+msZRxkTFGbPKVdnY1FKs4=; b=AIF459XABRbuHZrPJ3VGrA4aCLsd5rkqWV5trB5O49tf4amAgGoD3gurCBKUrqKnrG kN+sHJnkdGDCOPmQAv4Lp4N0w74uRytQREZ4isVBUCLZZo4QMjOoTErAIS/1ef/50V7H e+FZwIbsytLKos17/iOgRDcvYEgChTlapASUNbZghSj0G139sQpiRyxHlRs8cawaSmrY Tww2wcwnX6k8CGFxHqBepx6xJ2rtuJhBUiMDiBfkqN6ZFiN5uHnHfhyPn3xszxKv+UQj oU8YLkTg/BAbf+BXnCltQw4MuEdaIZ7zlATSFwY681vPU30gf3jUyLnyBLGxjhNX1Yov yNLA== X-Gm-Message-State: AOJu0YyesP76nndv7batE2oWPpFX0O6si+bE7LmwkjehMavwqSBxKfOn ssgzbxdvolcAjy0HiewtsGd8t/rNGIb/t56Vo/m9GN7yY9d3D0HGaYd9pyKZgG6wSAOD3nX7P9d vO4RT X-Gm-Gg: Acq92OGHh5aNIpIZ1VazVGziLoJ5cx2PhLFm8KSS3MX8042Ej8p9VdEgqmSAtSOu/pX ZQdiTvt4fG09WWIlZMBceNXuOGKftQO6IAMXBR6ipAT2gA++5BJfsEs7wMO7TVtFscinlGece3O rmsAOKSpKvGzxuR9qEl24Z5647oegKr8mL9SOjYWxBPDJJtSyEPiPifbWk0YJU1XkSQl0KuZJCz LfIdY8RbLneJV2z+oxNU2GNKDyW+54nV8DcSD26FnNHOhDls9gj+orBDVWBW7qDdLcJrT9CAIX2 oNJv29Di18BPJixBDS7/95G+kaA+Z3kCwMXhU243QeihZkhuihpl8qWb5lai3s6XUiR0EtyDs7p Ma0v9ItznOWsa2r96HTZXnGRzQ3vd/PaiEgDNaKLy9fkYkvv8FCtjTVY0qxalwsG/9TgK1bs2xX Jepu2scS7nAOOKRb7EEmjUltZoT1mDdg== X-Received: by 2002:a05:7300:df4b:b0:2ed:e17:d510 with SMTP id 5a478bee46e88-2fb4c3e427bmr6661223eec.35.1778556723988; Mon, 11 May 2026 20:32:03 -0700 (PDT) Received: from localhost ([177.25.198.13]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f8884752ccsm15739927eec.17.2026.05.11.20.32.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 May 2026 20:32:03 -0700 (PDT) From: Thiago Jung Bauermann To: Christina Schimpe Cc: gdb-patches@sourceware.org Subject: Re: [PATCH v2 6/9] gdb: Add command option 'bt -shadow' to print the shadow stack backtrace. In-Reply-To: <20260123080532.878738-7-christina.schimpe@intel.com> (Christina Schimpe's message of "Fri, 23 Jan 2026 08:05:28 +0000") References: <20260123080532.878738-1-christina.schimpe@intel.com> <20260123080532.878738-7-christina.schimpe@intel.com> User-Agent: mu4e 1.14.1; emacs 30.2 Date: Tue, 12 May 2026 00:32:00 -0300 Message-ID: <874ikd1exb.fsf@linaro.org> MIME-Version: 1.0 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 Hello Christina, I was having one more look at this patch today. I just have a few nits: Christina Schimpe writes: > diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py > index d44e59a523d..1f24a3a6d72 100644 > --- a/gdb/gdbarch_components.py > +++ b/gdb/gdbarch_components.py > @@ -2830,9 +2830,11 @@ provided: > unwinding and inferior function calls > - top_addr_empty_shadow_stack: required for shadow stack pointer unwindi= ng > - ssp_regnum: required for inferior function calls. > - > If the shadow stack alignment is not the predefault of 8 bytes, configure > the gdbarch value shadow_stack_element_size_aligned. > +To support the command line option 'backtrace -shadow' in addition to all > +values and methods listed above also the gdbarch hook get_shadow_stack_s= ize, > +has to be provided. >=20=20 > If possible, return the shadow stack pointer. If the shadow stack > feature is enabled then set SHADOW_STACK_ENABLED to true, otherwise > @@ -2893,3 +2895,19 @@ this value. > predefault=3D"8", > invalid=3DFalse, > ) > + > +Method( > + comment=3D""" > +Return the number of elements which are currently on the shadow stack > +based on the shadow stack pointer SSP and the shadow stack memory > +RANGE [start_address, end_address) of the current thread. > +In case shadow stack is not enabled for the current thread, return -1. > +""", > + type=3D"long", > + name=3D"get_shadow_stack_size", > + params=3D[ > + ("const std::optional", "ssp"), > + ("const std::pair", "range") > + ], > + predicate=3DTrue, > +) Small nit: we aim to keep the Python files in the style used by the Black Python code formatter. If you run it on this file: $ black gdb/gdbarch_components.py It changes the above to: name=3D"get_shadow_stack_size", params=3D[ ("const std::optional", "ssp"), - ("const std::pair", "range") + ("const std::pair", "range"), ], predicate=3DTrue, ) > +/* Read the memory at shadow stack pointer SSP and assign it to > + RETURN_VALUE. In case we cannot read the memory, set REASON to > + ssp_unwind_stop_reason::memory_read_error and return false. */ > + > +static bool > +read_shadow_stack_memory (gdbarch *gdbarch, CORE_ADDR ssp, > + CORE_ADDR &return_value, > + ssp_unwind_stop_reason *reason) "reason" can also be a reference, since it's assumed to be non-null. > +{ > + /* On x86 there can be a shadow stack token at bit 63. For x32, the > + address size is only 32 bit. Thus, we still must use > + gdbarch_shadow_stack_element_size_aligned (and not gdbarch_addr_bit) > + to read the full element for x32 as well. */ > + const int element_size > + =3D gdbarch_shadow_stack_element_size_aligned (gdbarch); > + > + const bfd_endian byte_order =3D gdbarch_byte_order (gdbarch); > + if (!safe_read_memory_unsigned_integer (ssp, element_size, byte_order, > + &return_value)) > + { > + *reason =3D ssp_unwind_stop_reason::memory_read_error; > + return false; > + } > + > + return true; > +} > + > +/* If possible, return the starting shadow stack frame info needed to h= andle > + COUNT outermost frames. FRAME should point to the innermost (newest) > + element of the shadow stack. RANGE is the shadow stack memory range > + [start_address, end_address) corresponding to FRAME's shadow stack p= ointer. > + If COUNT is bigger than the number of elements on the shadow stack, = return > + FRAME. In case of failure, assign an appropriate ssp_unwind_stop_re= ason in > + FRAME->UNWIND_stop_REASON. */ I like this new wording of the doc comment. Thanks! Just one nit: UNWIND_stop_REASON should be all upper-case. :) > + > +static std::optional > +get_trailing_outermost_shadow_stack_frame_info > + (gdbarch *gdbarch, const std::pair range, > + const ULONGEST count, shadow_stack_frame_info &frame) > +{ > + gdb_assert (gdbarch_get_shadow_stack_size_p (gdbarch)); > + > + const long shadow_stack_size > + =3D gdbarch_get_shadow_stack_size (gdbarch, > + std::optional (frame.ssp), > + range); > + > + /* We should only get here in case shadow stack is enabled for the > + current thread. */ > + gdb_assert (shadow_stack_size >=3D 0); > + > + const long level =3D shadow_stack_size - count; Just for the record: as I'm sure you realized, I was wrong in my comment in v1's review where I said this expression to calculate level was missing a "- 1" term. This looks good. Sorry about that. I think this function and the loop that calls it in backtrace_shadow_command are all good now. > + /* COUNT exceeds the number of elements on the shadow stack. Return t= he > + starting shadow stack frame info FRAME. */ > + if (level <=3D 0) > + return std::optional (frame); > + > + CORE_ADDR new_ssp =3D update_shadow_stack_pointer > + (gdbarch, frame.ssp, level, ssp_update_direction::outer); > + > + if (gdbarch_stack_grows_down (gdbarch)) > + gdb_assert (new_ssp < range.second); > + else > + gdb_assert (new_ssp >=3D range.first); > + > + CORE_ADDR new_value; > + if (!read_shadow_stack_memory (gdbarch, new_ssp, new_value, > + &frame.unwind_stop_reason)) > + return {}; > + > + return std::optional > + ({new_ssp, new_value, (unsigned long) level, > + ssp_unwind_stop_reason::no_error}); > +} > + > +std::optional > +shadow_stack_frame_info::unwind_prev_shadow_stack_frame_info > + (gdbarch *gdbarch, std::pair range) > +{ > + /* If the user's backtrace limit has been exceeded, stop. We must > + add two to the current level; one of those accounts for > + backtrace_limit being 1-based and the level being 0-based, and the > + other accounts for the level of the new frame instead of the level > + of the current frame. */ > + if (this->level + 2 > user_set_backtrace_options.backtrace_limit) > + return {}; > + > + CORE_ADDR new_ssp > + =3D update_shadow_stack_pointer (gdbarch, this->ssp, 1, > + ssp_update_direction::outer); > + > + if (gdbarch_top_addr_empty_shadow_stack_p (gdbarch) > + && gdbarch_top_addr_empty_shadow_stack (gdbarch, new_ssp, range)) > + return {}; > + else if (gdbarch_stack_grows_down (gdbarch)) The four lines above are indented with one extra space. =E2=8B=AE > + if (read_shadow_stack_memory (gdbarch, *start_ssp, new_value, &reason)) > + current =3D {*start_ssp, new_value, 0, ssp_unwind_stop_reason::no_er= ror}; > + > + std::optional trailing =3D current; > + > + LONGEST count =3D -1; > + if (current.has_value () && count_exp !=3D nullptr) > + { > + count =3D parse_and_eval_long (count_exp); > + /* If count is negative, update trailing with the shadow stack fra= me > + info from which we should start printing. */ > + if (count < 0) > + { > + trailing =3D get_trailing_outermost_shadow_stack_frame_info > + (gdbarch, range, std::abs (count), *current); > + > + if (!trailing.has_value ()) > + reason =3D current->unwind_stop_reason; > + } > + } > + > + if (!trailing.has_value ()) > + { > + gdb_assert (reason !=3D ssp_unwind_stop_reason::no_error); > + > + error (_("Cannot print shadow stack backtrace: %s.\n"), > + ssp_unwind_stop_reason_to_err_string (reason)); > + } > + > + current =3D trailing; The assignment above is now redundant, since it's also in the for loop initial condition. > + for (current =3D trailing; current.has_value () && count !=3D 0; count= --) > + { > + QUIT; > + > + print_shadow_stack_frame_info (gdbarch, fp_opts, *current, LOCATIO= N); > + > + trailing =3D current; > + current =3D current->unwind_prev_shadow_stack_frame_info (gdbarch,= range); > + } > + > + /* If we've stopped before the end, mention that. */ > + if (current.has_value () && from_tty) > + gdb_printf (_("(More shadow stack frames follow...)\n")); > + > + /* Due to the loop above, trailing always has a value at this point. = */ > + gdb_assert (trailing.has_value ()); > + > + /* If we've run out of shadow stack frames, and the reason appears to > + be an error condition, print it. */ > + if (!current.has_value () > + && trailing->unwind_stop_reason > ssp_unwind_stop_reason::no_error) > + gdb_printf (_("Shadow stack backtrace stopped at shadow stack " \ > + "pointer %s due to: %s.\n"), > + paddress (gdbarch, trailing->ssp), > + ssp_unwind_stop_reason_to_err_string > + (trailing->unwind_stop_reason)); > +} --=20 Thiago