Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Christina Schimpe <christina.schimpe@intel.com>
To: gdb-patches@sourceware.org
Cc: thiago.bauermann@linaro.org, luis.machado@arm.com
Subject: [PATCH v5 09/12] gdb, gdbarch: Enable inferior calls for shadow stack support.
Date: Sat, 28 Jun 2025 01:28:07 -0700	[thread overview]
Message-ID: <20250628082810.332526-10-christina.schimpe@intel.com> (raw)
In-Reply-To: <20250628082810.332526-1-christina.schimpe@intel.com>

Inferior calls in GDB reset the current PC to the beginning of the function
that is called.  As no call instruction is executed the new return address
needs to be pushed to the shadow stack and the shadow stack pointer needs
to be updated.

This commit adds a new gdbarch method to push an address on the shadow
stack.  The method is used to adapt the function 'call_function_by_hand_dummy'
for inferior call shadow stack support.

Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Reviewed-By: Luis Machado <luis.machado@arm.com>
---
 gdb/gdbarch-gen.c         | 32 ++++++++++++++++++++++++++++++++
 gdb/gdbarch-gen.h         | 14 ++++++++++++++
 gdb/gdbarch_components.py | 16 ++++++++++++++++
 gdb/infcall.c             | 14 ++++++++++----
 4 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c
index fc570d37a8d..a4b72793fd8 100644
--- a/gdb/gdbarch-gen.c
+++ b/gdb/gdbarch-gen.c
@@ -262,6 +262,7 @@ struct gdbarch
   gdbarch_read_core_file_mappings_ftype *read_core_file_mappings = default_read_core_file_mappings;
   gdbarch_use_target_description_from_corefile_notes_ftype *use_target_description_from_corefile_notes = default_use_target_description_from_corefile_notes;
   gdbarch_core_parse_exec_context_ftype *core_parse_exec_context = default_core_parse_exec_context;
+  gdbarch_shadow_stack_push_ftype *shadow_stack_push = nullptr;
 };
 
 /* Create a new ``struct gdbarch'' based on information provided by
@@ -535,6 +536,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of read_core_file_mappings, invalid_p == 0.  */
   /* Skip verify of use_target_description_from_corefile_notes, invalid_p == 0.  */
   /* Skip verify of core_parse_exec_context, invalid_p == 0.  */
+  /* Skip verify of shadow_stack_push, has predicate.  */
   if (!log.empty ())
     internal_error (_("verify_gdbarch: the following are invalid ...%s"),
 		    log.c_str ());
@@ -1406,6 +1408,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   gdb_printf (file,
 	      "gdbarch_dump: core_parse_exec_context = <%s>\n",
 	      host_address_to_string (gdbarch->core_parse_exec_context));
+  gdb_printf (file,
+	      "gdbarch_dump: gdbarch_shadow_stack_push_p() = %d\n",
+	      gdbarch_shadow_stack_push_p (gdbarch));
+  gdb_printf (file,
+	      "gdbarch_dump: shadow_stack_push = <%s>\n",
+	      host_address_to_string (gdbarch->shadow_stack_push));
   if (gdbarch->dump_tdep != NULL)
     gdbarch->dump_tdep (gdbarch, file);
 }
@@ -5551,3 +5559,27 @@ set_gdbarch_core_parse_exec_context (struct gdbarch *gdbarch,
 {
   gdbarch->core_parse_exec_context = core_parse_exec_context;
 }
+
+bool
+gdbarch_shadow_stack_push_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->shadow_stack_push != NULL;
+}
+
+void
+gdbarch_shadow_stack_push (struct gdbarch *gdbarch, CORE_ADDR new_addr, regcache *regcache)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->shadow_stack_push != NULL);
+  if (gdbarch_debug >= 2)
+    gdb_printf (gdb_stdlog, "gdbarch_shadow_stack_push called\n");
+  gdbarch->shadow_stack_push (gdbarch, new_addr, regcache);
+}
+
+void
+set_gdbarch_shadow_stack_push (struct gdbarch *gdbarch,
+			       gdbarch_shadow_stack_push_ftype shadow_stack_push)
+{
+  gdbarch->shadow_stack_push = shadow_stack_push;
+}
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 281b97b7aa8..71142332540 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -1802,3 +1802,17 @@ extern void set_gdbarch_use_target_description_from_corefile_notes (struct gdbar
 typedef core_file_exec_context (gdbarch_core_parse_exec_context_ftype) (struct gdbarch *gdbarch, bfd *cbfd);
 extern core_file_exec_context gdbarch_core_parse_exec_context (struct gdbarch *gdbarch, bfd *cbfd);
 extern void set_gdbarch_core_parse_exec_context (struct gdbarch *gdbarch, gdbarch_core_parse_exec_context_ftype *core_parse_exec_context);
+
+/* Some targets support special hardware-assisted control-flow protection
+   technologies.  For example, the Intel Control-Flow Enforcement Technology
+   (Intel CET) on x86 provides a shadow stack and indirect branch tracking.
+   To enable shadow stack support for inferior calls the shadow_stack_push
+   gdbarch hook has to be provided.
+
+   Push NEW_ADDR to the shadow stack and update the shadow stack pointer. */
+
+extern bool gdbarch_shadow_stack_push_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_shadow_stack_push_ftype) (struct gdbarch *gdbarch, CORE_ADDR new_addr, regcache *regcache);
+extern void gdbarch_shadow_stack_push (struct gdbarch *gdbarch, CORE_ADDR new_addr, regcache *regcache);
+extern void set_gdbarch_shadow_stack_push (struct gdbarch *gdbarch, gdbarch_shadow_stack_push_ftype *shadow_stack_push);
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index 91c867e69bf..abc79588473 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -2848,3 +2848,19 @@ which all assume current_inferior() is the one to read from.
     predefault="default_core_parse_exec_context",
     invalid=False,
 )
+
+Method(
+    comment="""
+Some targets support special hardware-assisted control-flow protection
+technologies.  For example, the Intel Control-Flow Enforcement Technology
+(Intel CET) on x86 provides a shadow stack and indirect branch tracking.
+To enable shadow stack support for inferior calls the shadow_stack_push
+gdbarch hook has to be provided.
+
+Push NEW_ADDR to the shadow stack and update the shadow stack pointer.
+""",
+    type="void",
+    name="shadow_stack_push",
+    params=[("CORE_ADDR", "new_addr"), ("regcache *", "regcache")],
+    predicate=True,
+)
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 2b5936d1621..db6d6774367 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -1448,10 +1448,16 @@ call_function_by_hand_dummy (struct value *function,
   /* Create the dummy stack frame.  Pass in the call dummy address as,
      presumably, the ABI code knows where, in the call dummy, the
      return address should be pointed.  */
-  sp = gdbarch_push_dummy_call (gdbarch, function,
-				get_thread_regcache (inferior_thread ()),
-				bp_addr, args.size (), args.data (),
-				sp, return_method, struct_addr);
+  regcache *regcache = get_thread_regcache (inferior_thread ());
+  sp = gdbarch_push_dummy_call (gdbarch, function, regcache, bp_addr,
+				args.size (), args.data (), sp,
+				return_method, struct_addr);
+
+  /* Push the return address of the inferior (bp_addr) to the shadow stack
+     and update the shadow stack pointer.  As we don't execute a call
+     instruction to call the function we need to handle this manually.  */
+  if (gdbarch_shadow_stack_push_p (gdbarch))
+    gdbarch_shadow_stack_push (gdbarch, bp_addr, regcache);
 
   /* Set up a frame ID for the dummy frame so we can pass it to
      set_momentary_breakpoint.  We need to give the breakpoint a frame
-- 
2.43.0


  parent reply	other threads:[~2025-06-28  8:35 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-28  8:27 [PATCH v5 00/12] Add CET " Christina Schimpe
2025-06-28  8:27 ` [PATCH v5 01/12] gdb, testsuite: Extend core_find procedure to save program output Christina Schimpe
2025-07-14 12:21   ` Andrew Burgess
2025-07-17 13:37     ` Schimpe, Christina
2025-06-28  8:28 ` [PATCH v5 02/12] gdbserver: Add optional runtime register set type Christina Schimpe
2025-06-28  8:28 ` [PATCH v5 03/12] gdbserver: Add assert in x86_linux_read_description Christina Schimpe
2025-06-28  8:28 ` [PATCH v5 04/12] gdb: Sync up x86-gcc-cpuid.h with cpuid.h from gcc 14 branch Christina Schimpe
2025-06-28  8:28 ` [PATCH v5 05/12] gdb, gdbserver: Use xstate_bv for target description creation on x86 Christina Schimpe
2025-07-14 13:52   ` Andrew Burgess
2025-07-15 10:28     ` Schimpe, Christina
2025-07-23 12:47       ` Schimpe, Christina
2025-08-05 13:47         ` Andrew Burgess
2025-06-28  8:28 ` [PATCH v5 06/12] gdb, gdbserver: Add support of Intel shadow stack pointer register Christina Schimpe
2025-07-25 12:49   ` Andrew Burgess
2025-07-25 15:03     ` Schimpe, Christina
2025-08-01 12:54       ` Schimpe, Christina
2025-08-05 13:57       ` Andrew Burgess
2025-08-06 19:53         ` Schimpe, Christina
2025-08-06 19:54           ` Schimpe, Christina
2025-08-07  3:17             ` Thiago Jung Bauermann
2025-08-14 11:39           ` Andrew Burgess
2025-07-29 13:51   ` Andrew Burgess
2025-08-01 12:40     ` Schimpe, Christina
2025-08-10 19:01   ` H.J. Lu
2025-08-10 20:07     ` Schimpe, Christina
2025-06-28  8:28 ` [PATCH v5 07/12] gdb: amd64 linux coredump support with shadow stack Christina Schimpe
2025-07-29 14:46   ` Andrew Burgess
2025-07-30  1:55     ` Thiago Jung Bauermann
2025-07-30 11:42       ` Schimpe, Christina
2025-08-04 15:28         ` Schimpe, Christina
2025-08-05  4:29           ` Thiago Jung Bauermann
2025-08-05 15:29             ` Schimpe, Christina
2025-08-06 20:52             ` Luis
2025-08-11 11:52               ` Schimpe, Christina
2025-08-04 12:45     ` Schimpe, Christina
2025-06-28  8:28 ` [PATCH v5 08/12] gdb: Handle shadow stack pointer register unwinding for amd64 linux Christina Schimpe
2025-07-30  9:58   ` Andrew Burgess
2025-07-30 12:06     ` Schimpe, Christina
2025-06-28  8:28 ` Christina Schimpe [this message]
2025-07-30 10:42   ` [PATCH v5 09/12] gdb, gdbarch: Enable inferior calls for shadow stack support Andrew Burgess
2025-06-28  8:28 ` [PATCH v5 10/12] gdb: Implement amd64 linux shadow stack support for inferior calls Christina Schimpe
2025-07-30 11:58   ` Andrew Burgess
2025-07-31 12:32     ` Schimpe, Christina
2025-06-28  8:28 ` [PATCH v5 11/12] gdb, gdbarch: Introduce gdbarch method to get the shadow stack pointer Christina Schimpe
2025-07-30 12:22   ` Andrew Burgess
2025-08-04 13:01     ` Schimpe, Christina
2025-08-14 15:50       ` Andrew Burgess
2025-08-19 15:37         ` Schimpe, Christina
2025-06-28  8:28 ` [PATCH v5 12/12] gdb: Enable displaced stepping with shadow stack on amd64 linux Christina Schimpe
2025-07-30 13:59   ` Andrew Burgess
2025-07-31 17:29     ` Schimpe, Christina
2025-07-08 15:18 ` [PATCH v5 00/12] Add CET shadow stack support Schimpe, Christina
2025-08-14  7:52   ` Schimpe, Christina
2025-07-11 10:36 ` Luis Machado
2025-07-11 13:54   ` Schimpe, Christina
2025-07-11 15:54     ` Luis Machado
2025-07-13 14:01       ` Schimpe, Christina
2025-07-13 19:05         ` Luis Machado
2025-07-13 19:57           ` Schimpe, Christina
2025-07-14  7:13           ` Luis Machado
2025-07-17 12:01             ` Schimpe, Christina
2025-07-17 14:59               ` Luis Machado
2025-07-23 12:45                 ` Schimpe, Christina
2025-07-28 17:05                   ` Luis Machado
2025-07-28 17:20                     ` Schimpe, Christina
2025-08-20  9:16 ` Schimpe, Christina
2025-08-20 15:21   ` Schimpe, Christina

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250628082810.332526-10-christina.schimpe@intel.com \
    --to=christina.schimpe@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado@arm.com \
    --cc=thiago.bauermann@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox