From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id CcMdOnRhTmqwcCwAWB0awg (envelope-from ) for ; Wed, 08 Jul 2026 10:40:52 -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=dq49TkIw; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id EA55F1E024; Wed, 08 Jul 2026 10:40:52 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 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 autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::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 47AAF1E024 for ; Wed, 08 Jul 2026 10:40:52 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1BCEF4BA2E19 for ; Wed, 8 Jul 2026 14:40:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1BCEF4BA2E19 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=dq49TkIw Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.16]) by sourceware.org (Postfix) with ESMTPS id BD26E4BA23D3 for ; Wed, 8 Jul 2026 14:38:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BD26E4BA23D3 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 BD26E4BA23D3 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=198.175.65.16 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783521493; cv=none; b=rnK3euWvSCZCzxWyx2m2DLbNs4++KL5Jn0qJHF9CCgqBXIX6tWT4w/gY6We4Yg4/SaYbxpaxlXi2RiRnRL0SQbJ8zLhnjufn3m9Y/HM/kvndmVQ/OTw1SakSuZxZ58vN7ctO+6JKLVtSgzbP7kEt2iwpGtNK0Sbr7lVYaO01xAM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783521493; c=relaxed/simple; bh=RWwjWOiTK0sNrmROPF3Nf8KaHXqVo21vRaYowYKnl48=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=mIzS86mGYoE/R4FIU7t8DsJxz1eRrxMQv2yAOcrv1ZfEcT2t7Z3nSQ3q1wbLX6CVNXt4i57iv45M7yOoVnATjYZgeJys4A5wdcuxFN9+FGFRdt2yjb1zXNGKD+LRadzKzWVkrJg7JubbMTtAvn3Wz2AOyjUZ8iUhzyW09RB6Fyc= ARC-Authentication-Results: i=1; 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=dq49TkIw DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BD26E4BA23D3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1783521493; x=1815057493; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RWwjWOiTK0sNrmROPF3Nf8KaHXqVo21vRaYowYKnl48=; b=dq49TkIwL+Tv2M+nDQxBDA9VdxUCuAwedCSmrwOhvQYQdlz81EF5QnvL pDFklPpYd01/o2+U1qdUqFcZ1Qjt9zCGGxFEOLw9T1Ee2uULdZyGdz064 pVpM+ZKz2+03wq76pj02hJInty1kVOYBliRfDAqkGysdc2VFMwkeUgmNv Zs3B04yHOiosn0RPwiU5MLqXn6UWDKWGnDQSUOnUIqYST2giaFLb3J99X DMqMmfEA0Fqaynmx9fkQ5wAeXURZzHu7GwjNuW6WYNdJoTp1sbLeezGQC xQenJpV32AjtFMmWL2n2FX9Wjyevj7LnhoRCAfAlIVFIwvae0eoH4ZKMK w==; X-CSE-ConnectionGUID: 5mDh/Z+PSU+ppb2LcakPFw== X-CSE-MsgGUID: WcLzKa/hRGGR2vwVbdonwQ== X-IronPort-AV: E=McAfee;i="6800,10657,11841"; a="84375547" X-IronPort-AV: E=Sophos;i="6.25,153,1779174000"; d="scan'208";a="84375547" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa108.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jul 2026 07:38:12 -0700 X-CSE-ConnectionGUID: OBUctuQfTxCiwNFdRRkZoA== X-CSE-MsgGUID: K2vWCgQxTdu0ql7rFilWxg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,153,1779174000"; d="scan'208";a="249864418" Received: from gkldtt-dev-004.igk.intel.com (HELO localhost) ([10.123.221.202]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jul 2026 07:38:11 -0700 From: Christina Schimpe To: gdb-patches@sourceware.org Cc: tom@tromey.com, thiago.bauermann@linaro.org Subject: [PATCH v4 11/13] gdb: Enable inferior calls in the shadow stack backtrace. Date: Wed, 8 Jul 2026 14:36:37 +0000 Message-Id: <20260708143639.2214689-12-christina.schimpe@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260708143639.2214689-1-christina.schimpe@intel.com> References: <20260708143639.2214689-1-christina.schimpe@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 Similar to the normal backtrace display in the shadow stack backtrace for inferior function calls. Example for a nested inferior call: ~~~ (gdb) bt -shadow \#0 \#1 \#2 0x000000000040045a in call1 at /tmp/amd64-shadow-stack.c:27 \#3 0x0000000000400466 in main at /tmp/amd64-shadow-stack.c:38 (gdb) bt \#0 call2 () at /tmp/amd64-shadow-stack.c:21 \#1 \#2 call2 () at /tmp/amd64-shadow-stack.c:21 \#3 \#4 call2 () at /tmp/amd64-shadow-stack.c:21 \#5 0x000000000040045a in call1 () at /tmp/amd64-shadow-stack.c:27 \#6 0x0000000000400466 in main () at /tmp/amd64-shadow-stack.c:38 ~~~ --- gdb/shadow-stack.c | 36 +++++++++++++++++++ gdb/shadow-stack.h | 4 +++ .../gdb.arch/amd64-shadow-stack-cmds.exp | 24 +++++++++++++ 3 files changed, 64 insertions(+) diff --git a/gdb/shadow-stack.c b/gdb/shadow-stack.c index dbd8959753d..94062034bd3 100644 --- a/gdb/shadow-stack.c +++ b/gdb/shadow-stack.c @@ -215,6 +215,29 @@ find_pc_funname (CORE_ADDR pc) return funname; } +/* Check if the shadow stack frame's value VAL is an inferior call + return address. */ + +static bool +is_infcall_return_address (const CORE_ADDR val) +{ + const int inf_thread_num = inferior_thread ()->global_num; + + for (breakpoint &b : all_breakpoints ()) + { + if (b.type != bp_call_dummy + || b.thread != inf_thread_num + || b.frame_id.code_addr != val) + continue; + + for (bp_location &bl : b.locations ()) + if (bl.pspace == current_program_space) + return true; + } + + return false; +} + /* Print information of shadow stack frame info FRAME. The output is formatted according to PRINT_WHAT. For the meaning of PRINT_WHAT, see enum print_what comments in frame.h. Note that PRINT_WHAT is overridden, @@ -242,6 +265,8 @@ do_print_shadow_stack_frame_info gdb_assert (frame.non_return_description.has_value ()); str = frame.non_return_description.value (); } + else if (frame.type == ssp_frame_type::dummy_frame) + str = ""; else gdb_assert_not_reached ("Invalid shadow stack frame type."); @@ -430,6 +455,17 @@ get_shadow_stack_frame_info return *no_return_frame; } + if (is_infcall_return_address (value)) + { + /* If VALUE belongs to a dummy call breakpoint get_sal_arch won't + return a valid gdbarch and we can assign the current gdbarch + here. We also don't show any SAL information, so we can set it + to an empty optional. */ + return std::optional + ({ssp, value, level, fallback_arch, {}, ssp_frame_type::dummy_frame, + {}, ssp_unwind_stop_reason::no_error}); + } + /* At this point, we know that SSP points to VALUE which is a return address. In contrast to find_frame_sal which is used for the normal backtrace command, VALUE always points at the return instruction diff --git a/gdb/shadow-stack.h b/gdb/shadow-stack.h index 4278620c70c..225fd3996cd 100644 --- a/gdb/shadow-stack.h +++ b/gdb/shadow-stack.h @@ -76,6 +76,10 @@ enum class ssp_frame_type This frame type is configured in the target specific implementation of is_no_return_shadow_stack_address. */ non_return_frame, + + /* A fake frame, created by GDB when performing an inferior function + call. */ + dummy_frame, }; /* Information of a shadow stack frame belonging to a shadow stack element diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp index 0347313b647..3259fd2f918 100644 --- a/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp @@ -167,6 +167,30 @@ save_vars { ::env(GLIBC_TUNABLES) } { gdb_continue_to_end } + with_test_prefix "test inferior call shadow stack backtrace" { + restart_and_run_infcall_call2 + gdb_test "bt -shadow" \ + [multi_line \ + "#0\[ \t\]*" \ + "#1\[ \t\]*$hex in \[^\r\n\]+" \ + "#2\[ \t\]*$hex in \[^\r\n\]+" ] \ + "Test shadow stack backtrace for inferior calls." + + set inside_infcall_str \ + "The program being debugged stopped while in a function called from GDB" + gdb_test "call (int) call2()" \ + "Breakpoint \[0-9\]*, call2.*$inside_infcall_str.*" \ + "Execute an inferior call inside an inferior call." + + gdb_test "bt -shadow" \ + [multi_line \ + "#0\[ \t\]*" \ + "#1\[ \t\]*" \ + "#2\[ \t\]*$hex in \[^\r\n\]+" \ + "#3\[ \t\]*$hex in \[^\r\n\]+" ] \ + "Test shadow stack backtrace for nested inferior calls." + } + clean_restart ${::testfile} if { ![runto_main] } { return -- 2.34.1 Intel Deutschland GmbH Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany Tel: +49 89 991 430, www.intel.de Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell Chairperson of the Supervisory Board: Nicole Lau Registered Seat: Munich Commercial Register: Amtsgericht Muenchen HRB 186928