Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Abdul Basit Ijaz <abdul.b.ijaz@intel.com>
To: gdb-patches@sourceware.org
Cc: abdul.b.ijaz@intel.com, JiniSusan.George@amd.com, tom@tromey.com,
	eliz@gnu.org,
	Nils-Christian Kempke <nils-christian.kempke@intel.com>
Subject: [PATCH v11 02/10] gdb/symtab: add lookup for trampoline functions
Date: Mon,  3 Aug 2026 21:34:41 +0200	[thread overview]
Message-ID: <20260803193449.33375-3-abdul.b.ijaz@intel.com> (raw)
In-Reply-To: <20260803193449.33375-1-abdul.b.ijaz@intel.com>

From: Nils-Christian Kempke <nils-christian.kempke@intel.com>

In order to query information about the DW_AT_trampoline tag for
subroutines and inlined subroutines, three functions were added to symtab.

First, in_trampoline_code() a routine for querying whether the given
pc belongs to a block that is associated with a function (maybe inlined)
marked DW_AT_trampoline.  Used inside trampoline code (inline or concrete)
that was stepped into and continues stepping through it.  This function
uses find_symbol_for_pc_sect_maybe_inline() which calls containing_function
to detect inline trampolines as well as concrete ones.

Second, in_trampoline_function() a routine to check concrete trampoline
(non-inline) functions and attempt target resolution upfront.  Used in
forward stepping and for frame navigation commands.  This function uses
find_symbol_for_pc_sect() which calls block->linkage_function to skip
inlined blocks and return only the concrete function at the PC.

Third, find_function_trampoline_target() a routine for querying a trampoline
function's target.  Subroutines and inlined subroutines marked with
DW_AT_trampoline usually contain information about the target subroutine
they are 'wrapping'/ passing control to.

These lookup functions will be used in the follow up commits for the
trampoline handling in different GDB commands.

Co-Authored-By: Abdul Basit Ijaz <abdul.b.ijaz@intel.com>
---
 gdb/symtab.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/symtab.h |  24 ++++++++++++
 2 files changed, 132 insertions(+)

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 5d5076f2e77..e5464551807 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -74,6 +74,7 @@
 #include "gdbsupport/common-utils.h"
 #include <optional>
 #include "gdbsupport/unordered_set.h"
+#include "gdbsupport/symbol.h"
 
 /* Forward declarations for local functions.  */
 
@@ -4103,6 +4104,113 @@ find_function_alias_target (bound_minimal_symbol msymbol)
   return NULL;
 }
 
+/* See symtab.h.  */
+
+bool
+in_trampoline_code (CORE_ADDR pc)
+{
+  /* Find the innermost function containing pc, which might be an inlined
+     function.  This is used by stepping logic to detect when execution is
+     within ANY trampoline code (inline or concrete) and continue stepping
+     through it.
+
+     Unlike in_trampoline_function(), this uses containing_function() by
+     calling find_symbol_for_pc_sect_maybe_inline to detect inline trampolines as
+     well as concrete ones.  */
+  symbol *sym = find_symbol_for_pc_sect_maybe_inline (pc,
+						  find_pc_mapped_section (pc));
+  return sym != nullptr && TYPE_IS_TRAMPOLINE (sym->type ());
+}
+
+/* See symtab.h.  */
+
+bool
+in_trampoline_function (CORE_ADDR pc)
+{
+  /* Find the concrete non-inlined function at pc, skipping inlined blocks.
+     The find_symbol_for_pc_sect calls block->linkage_function which skips
+     inlined blocks to return the concrete function at the PC.  This ensures
+     we check the concrete function's trampoline flag, not the flag from an
+     abstract inline origin that might be marked as a trampoline.
+
+     This is used by forward stepping to determine if about to step into a
+     concrete trampoline function and by frame navigation commands to skip
+     trampoline frames.
+
+     For O2 optimization, the compiler may create trampoline wrappers with
+     both DW_AT_trampoline + DW_AT_inline.  At a given PC, inlined code from
+     such abstract trampolines may exist, but the concrete function at that
+     PC is the user's real function (not a trampoline).  Using linkage_function
+     by calling find_symbol_for_pc_sect avoids incorrectly checking the inline
+     trampoline's abstract origin.  */
+  symbol *sym = find_symbol_for_pc_sect (pc, find_pc_mapped_section (pc));
+  return sym != nullptr && TYPE_IS_TRAMPOLINE (sym->type ());
+}
+
+/* See symtab.h.  */
+
+CORE_ADDR
+find_function_trampoline_target (CORE_ADDR pc)
+{
+  /* Find the innermost function containing pc.  This might be an inlined
+     function.  */
+  symbol *sym
+    = find_symbol_for_pc_sect_maybe_inline (pc, find_pc_mapped_section (pc));
+  CORE_ADDR target_address = 0;
+
+  if (sym != nullptr && TYPE_IS_TRAMPOLINE (sym->type ()))
+    {
+      trampoline_target *trampoline = TYPE_TRAMPOLINE_TARGET (sym->type ());
+
+      /* DW_AT_trampoline can be given as an address, name, or flag here (die
+	 references have been resolved as names at this point.  In the case
+	 where DW_AT_trampoline contains a flag we do not know the target
+	 address and return 0.  */
+      if (trampoline->target_kind () == TRAMPOLINE_TARGET_NAME)
+	{
+	  /* Handle both the mangled and demangled PHYSNAME.  */
+	  const char *physname = trampoline->target_name ();
+
+	  /* First, check whether there exists a symbol matching the
+	     physname.  If we cannot find one also check for minimal
+	     symbols.  */
+	  const block *blk = block_for_pc (pc);
+	  block_symbol bs
+	    = lookup_symbol (physname, blk, SEARCH_VAR_DOMAIN, 0);
+	  if (bs.symbol != nullptr)
+	    {
+	      const block *block = bs.symbol->value_block ();
+	      gdb_assert (block != nullptr);
+	      target_address = block->start ();
+	    }
+	  else
+	    {
+	      /* We normally expect the target symbol to be located in one
+		 objfile only.  However, a JIT compiler may have generated
+		 a duplicated symbol that most likely resides in the same
+		 objfile with the trampoline symbol.  Give priority to that
+		 objfile in the search.  If not found, try all objfiles.
+		 This is a heuristic.  */
+	      if ((find_minimal_symbol_address (physname, &target_address,
+						sym->objfile ()) != 0)
+		  && (find_minimal_symbol_address (physname, &target_address,
+						   nullptr) != 0))
+		target_address = 0;
+	    }
+	}
+      else if (trampoline->target_kind () == TRAMPOLINE_TARGET_ADDR)
+	{
+	  /* If the function symbol containing this trampoline target has
+	     been relocated we assume the target_address also needs relocation.
+	     If it has not been relocated the offset should be zero.  */
+	  target_address = \
+	    ( (CORE_ADDR) trampoline->target_addr ()
+	       + sym->objfile ()->section_offsets[sym->section_index ()]);
+	}
+    }
+
+  return target_address;
+}
 \f
 /* If P is of the form "operator[ \t]+..." where `...' is
    some legitimate operator text, return a pointer to the
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 6443216fd7f..10f64548f58 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2362,6 +2362,30 @@ extern const struct gnu_ifunc_fns *gnu_ifunc_fns_p;
 
 extern CORE_ADDR find_solib_trampoline_target (const frame_info_ptr &, CORE_ADDR);
 
+/* Return whether the current pc is within a block that belongs to a
+   function that is marked as a trampoline by the compiler.  This checks
+   only the concrete (non-inline) function at the PC.  Used by forward stepping
+   to check if about to step into a concrete trampoline function and attempt
+   to resolve its target.  Also used for frame navigation commands.  */
+
+extern bool in_trampoline_function (CORE_ADDR pc);
+
+/* Return whether the current pc is within any trampoline code
+   (inline or concrete).  Used to detect when execution stepped into ANY
+   trampoline code (inline or concrete) and continue stepping through it.
+   Also used for reverse stepping logic.  */
+
+extern bool in_trampoline_code (CORE_ADDR pc);
+
+/* Find the target of a trampoline function marked via the DW_AT_trampoline
+   attribute and return its address.  Returns 0 if the pc is not contained
+   in a trampoline function (inlined or not).  If DW_AT_trampoline
+   is given as a flag, the target is unknown and the function will still return
+   0.  One has to additionally query in_trampoline_function to cover this
+   case.  */
+
+extern CORE_ADDR find_function_trampoline_target (CORE_ADDR pc);
+
 struct symtab_and_line
 {
   /* The program space of this sal.  */
-- 
2.34.1

________________________________________
Intel Deutschland GmbH 

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany 

Tel: +49 (89) 99143-0 

www.intel.de 

Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman

Chairperson of the Supervisory Board: Sonja Pierer

Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


  parent reply	other threads:[~2026-08-03 19:35 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-03 19:34 [PATCH v11 00/10] GDB support for DW_AT_trampoline Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 01/10] gdb, dwarf: add support for DW_AT_trampoline in DWARF reader Abdul Basit Ijaz
2026-08-03 19:34 ` Abdul Basit Ijaz [this message]
2026-08-03 19:34 ` [PATCH v11 03/10] gdb: handle stepping through functions with DW_AT_trampoline Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 04/10] gdb: Skip trampoline frames for the backtrace command Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 05/10] gdb: Skip trampoline functions for the finish and reverse-finish commands Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 06/10] gdb: Skip trampoline functions for the up command Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 07/10] gdb: Skip trampoline functions for the return command Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 08/10] gdb, mi: Skip trampoline functions for the -stack-list-frames command Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 09/10] gdb, mi: Skip trampoline functions for the -stack-list-arguments command Abdul Basit Ijaz
2026-08-03 19:34 ` [PATCH v11 10/10] gdb: Filter trampoline frames in backtrace when using Python frame-filters Abdul Basit Ijaz

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=20260803193449.33375-3-abdul.b.ijaz@intel.com \
    --to=abdul.b.ijaz@intel.com \
    --cc=JiniSusan.George@amd.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=nils-christian.kempke@intel.com \
    --cc=tom@tromey.com \
    /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