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.
next prev 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