Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCHv2 2/3] gdb: introduce program_space::get_entry_point_info function
Date: Fri, 12 Jun 2026 16:41:39 +0100	[thread overview]
Message-ID: <ebddd7fb-f07a-4c30-8fa1-ccf36d5e5b17@palves.net> (raw)
In-Reply-To: <864cefb52d208dd8aac6b1b5f452cadad7546af8.1781214731.git.aburgess@redhat.com>

On 2026-06-11 22:59, Andrew Burgess wrote:

>  
> +/* See solib.h.  */
> +
> +std::optional<CORE_ADDR>
> +svr4_solib_ops::inferior_entry_point_address () const
> +{
> +  std::optional<gdb::byte_vector> interp_name_holder
> +    = svr4_find_program_interpreter ();
> +
> +  /* No interpreter means this is a static executable.  Ask the
> +     program_space for the entry address within the main executable.  */
> +  if (!interp_name_holder.has_value ())
> +    return m_pspace->exec_entry_point_address_if_available ();
> +
> +  /* If we can find a solib that matches the interpreter name then we can
> +     use that to find the actual entry address of the inferior.  */
> +  const solib *interp_solib = nullptr;
> +  const char *interp_name = (const char *) interp_name_holder->data ();
> +  for (const solib &so : m_pspace->solibs ())
> +    {
> +      if (svr4_same_name (interp_name, so.original_name.c_str ()))
> +	{
> +	  interp_solib = &so;
> +
> +	  const objfile *objfile = so.objfile;
> +	  if (objfile != nullptr && objfile->per_bfd->ei.entry_point_p)
> +	    {
> +	      const entry_info &ei = objfile->per_bfd->ei;
> +	      return (ei.entry_point
> +		      + objfile->section_offsets[ei.the_bfd_section_index]);
> +	    }
> +	}
> +    }
> +
> +  gdb_bfd_ref_ptr tmp_bfd;
> +  target_ops_up tmp_bfd_target;
> +  try
> +    {
> +      tmp_bfd = solib_bfd_open (interp_name);
> +
> +      /* Failed to open the interpreter BFD.  */
> +      if (tmp_bfd == nullptr)
> +	return {};
> +
> +      tmp_bfd_target = target_bfd_reopen (tmp_bfd);
> +    }
> +  catch (const gdb_exception &ex)
> +    {

Swallows Ctrl-C.  (I see you're just copying this from elsewhere.)

> +      return {};
> +    }
> +
> +  CORE_ADDR entry_addr
> +    = exec_entry_point (tmp_bfd.get (), tmp_bfd_target.get ());
> +
> +  /* We found the solib for the interpreter, but we don't have a
> +     corresponding objfile, or the objfile doesn't have entry point
> +     information.  Maybe symbols haven't been loaded yet?  */
> +  if (interp_solib != nullptr)
> +    {
> +      gdb_assert (interp_solib->objfile == nullptr
> +		  || !interp_solib->objfile->per_bfd->ei.entry_point_p);
> +
> +      CORE_ADDR load_addr
> +	= this->lm_addr_check (*interp_solib, tmp_bfd.get ());
> +
> +      return load_addr + entry_addr;
> +    }
> +
> +  /* We could not find a solib corresponding to the interpreter, this might
> +     mean that the name didn't match for some reason, or maybe GDB has
> +     failed to create a solib due to some other issue reading the solib
> +     list from the inferior.
> +
> +     If we got here we have managed to open the expected interpreter on
> +     disk though, so we can try using the AT_BASE value.  */
> +  CORE_ADDR load_addr;
> +  if (target_auxv_search (AT_BASE, &load_addr) > 0)
> +    {
> +      int addr_bit = gdbarch_addr_bit (current_inferior ()->arch ());
> +
> +      /* Ensure LOAD_ADDR has proper sign in its possible upper bits so
> +	 that `+ load_addr' will overflow CORE_ADDR width not creating
> +	 invalid addresses like 0x101234567 for 32bit inferiors on 64bit
> +	 GDB.  */
> +      if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
> +	{
> +	  CORE_ADDR space_size = (CORE_ADDR) 1 << addr_bit;
> +
> +	  gdb_assert (load_addr < space_size);
> +
> +	  /* ENTRY_ADDR exceeding SPACE_SIZE would be for prelinked
> +	     64bit ld.so with 32bit executable, it should not happen.  */
> +	  if (entry_addr < space_size
> +	      && entry_addr + load_addr >= space_size)
> +	    load_addr -= space_size;
> +	}
> +
> +      return load_addr + entry_addr;
> +    }

I wonder whether just looking at AT_BASE, which points at an ELF, and then
adding elf_header->e_entr, wouldn't be simpler than all of this.
We already use Elf32_External/Elf64_External structs in the file, so maybe
the manual ELF peeking is OK.

Alternatively, of lot of that code looks similar to enable_break.  Maybe
it could be refactored to be shared.  Or enable_break could cache the 
entry address.


> +# Use 'readelf' to extract the entry point address from TESTFILE.
> +proc get_exec_entry_address { testfile } {
> +    set readelf_program [gdb_find_readelf]
> +    set command "exec $readelf_program -Wh [standard_output_file $testfile]"

If you use "objdump -f" instead, this has a better chance of working on Windows PE/COFF too (eventually):

 $ objdump.exe -f ./foo.exe

 ./foo.exe:     file format pei-x86-64
 architecture: i386:x86-64, flags 0x0000013b:
 HAS_RELOC, EXEC_P, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, D_PAGED
 start address 0x00000001400013f0
> +# Start TESTFILE using 'starti'.  Check if the 'backtrace' command
> +# prints any additional frames; we don't expect any.
> +#
> +# When IS_DYNAMIC is true then TESTFILE is a dynamically linked
> +# executable, otherwise TESTFILE is statically linked.
> +proc run_test { testfile is_dynamic } {
> +    clean_restart $testfile
> +
> +    set exe_entry_addr [get_exec_entry_address $testfile]
> +
> +    # The inferior entry address is always unknown before starting the
> +    # inferior as at the point GDB has no solib_ops, and it is only
> +    # through that that we figure out the inferior entry address.
> +    check_maint_info_entry_addr "<unknown>" $exe_entry_addr \
> +	"check 'maint info entry-address' before inferior starts"
> +
> +    # Start inferior with 'starti' and then wait for a prompt.
> +    gdb_starti_cmd
> +    gdb_test "" ".*" "prompt after starti"
> +
> +    # Only svr4 targets currently support querying the inferior entry
> +    # address.
> +    if {[istarget *-linux*]} {

There are more svr4 targets than linux.  I think this style of allow-list has
a good chance of never getting updated.  Deny-lists are better, IMHO.  If the
test fails on some port, that might trigger someone to add the feature there.

> +	set pc [get_hexadecimal_valueof "\$pc" "UNKNOWN" \
> +		    "get current program counter"]
> +
> +	if { !$is_dynamic } {
> +	    # In static binaries, the first address should be the first
> +	    # address in the executable.
> +	    gdb_assert { $pc == $exe_entry_addr } \
> +		"stopped at executable entry address"
> +	}
> +
> +	set inf_entry_addr $pc
> +    } else {
> +	set inf_entry_addr "<unknown>"
> +    }
> +
> +    check_maint_info_entry_addr $inf_entry_addr $exe_entry_addr \
> +	"check 'maint info entry-address' after starti"
> +
> +    # Allow backtrace past the entry frame, count how many frames GDB
> +    # finds.  If on this target there are no additional frames then
> +    # the following test isn't going to tell us much, so skip it.
> +    gdb_test_no_output "set backtrace past-entry on"
> +    set frame_count 0
> +    gdb_test_multiple "bt" "count possible frames" {
> +	-re "^#($::decimal)\\s+\[^\r\n\]+\r\n" {
> +	    incr frame_count
> +	    exp_continue
> +	}
> +	-re "^$::gdb_prompt $" {
> +	    if { $frame_count > 1 } {
> +		pass $gdb_test_name
> +	    } else {
> +		unsupported "$gdb_test_name (insufficient frames)"
> +		return
> +	    }
> +	}
> +	-re "^\[^\r\n\]*\r\n" {
> +	    exp_continue
> +	}

This looks like could use -lbl.



  parent reply	other threads:[~2026-06-12 15:42 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-08 18:14 [PATCH] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-11 19:24 ` Guinevere Larsen
2026-06-11 20:40   ` Andrew Burgess
2026-06-12 12:49     ` Guinevere Larsen
2026-06-11 21:59 ` [PATCHv2 0/3] " Andrew Burgess
2026-06-11 21:59   ` [PATCHv2 1/3] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-12 15:41     ` Pedro Alves
2026-06-11 21:59   ` [PATCHv2 2/3] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-12  6:07     ` Eli Zaretskii
2026-06-15 10:14       ` Andrew Burgess
2026-06-15 12:01         ` Eli Zaretskii
2026-06-12 15:41     ` Pedro Alves [this message]
2026-06-15 10:29       ` Andrew Burgess
2026-06-16 18:36         ` Pedro Alves
2026-06-23  9:46           ` Andrew Burgess
2026-06-23 10:20             ` Pedro Alves
2026-06-11 21:59   ` [PATCHv2 3/3] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-12 15:57     ` Pedro Alves
2026-06-16 19:47   ` [PATCHv3 0/4] " Andrew Burgess
2026-06-16 19:47     ` [PATCHv3 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-16 19:47     ` [PATCHv3 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-17 11:52       ` Eli Zaretskii
2026-06-16 19:47     ` [PATCHv3 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-16 19:47     ` [PATCHv3 4/4] gdb: cache program space entry point information Andrew Burgess
2026-06-23 10:47     ` [PATCHv4 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-23 10:47       ` [PATCHv4 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-23 10:47       ` [PATCHv4 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-23 10:47       ` [PATCHv4 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-23 10:47       ` [PATCHv4 4/4] gdb: cache program space entry point information Andrew Burgess
2026-06-25 15:26       ` [PATCHv5 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-25 15:26         ` [PATCHv5 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-25 15:26         ` [PATCHv5 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-25 15:26         ` [PATCHv5 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-25 15:26         ` [PATCHv5 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-10 14:24         ` [PATCHv6 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-10 14:24           ` [PATCHv6 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-10 14:24           ` [PATCHv6 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-10 15:39             ` Simon Marchi
2026-07-10 14:24           ` [PATCHv6 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-10 17:00             ` Simon Marchi
2026-07-10 17:01               ` Simon Marchi
2026-07-16 15:06               ` Andrew Burgess
2026-07-10 14:24           ` [PATCHv6 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-10 17:07             ` Simon Marchi
2026-07-18 13:11           ` [PATCHv7 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-18 13:11             ` [PATCHv7 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-18 13:11             ` [PATCHv7 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-18 13:11             ` [PATCHv7 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-18 13:11             ` [PATCHv7 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-20  9:52             ` [PATCHv8 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-20  9:52               ` [PATCHv8 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-20  9:52               ` [PATCHv8 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-20  9:52               ` [PATCHv8 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-20  9:52               ` [PATCHv8 4/4] gdb: cache program space entry point information Andrew Burgess

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=ebddd7fb-f07a-4c30-8fa1-ccf36d5e5b17@palves.net \
    --to=pedro@palves.net \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.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