[PING] [PATCH] Rebase executable to match relocated base address

Hannes Domani via gdb-patches gdb-patches@sourceware.org
Wed Feb 12 18:05:00 GMT 2020


 Am Mittwoch, 12. Februar 2020, 05:49:45 MEZ hat Simon Marchi <simark@simark.ca> Folgendes geschrieben:

> On 2020-02-11 6:34 a.m., Hannes Domani via gdb-patches wrote:
> >> This function is needed, but the question is how it should get the base
> >> address from the target.
> >>
> >> The auxv trickery works, but that may have other implications. I'm not
> >> sure if GDB won't try to fetch more stuff given we now have an "auxv".
> >> And it is also a bit misleading.
> >
> > I've used this approach for a while now, and never had any problem with it.
> > Also, gnu-nat.c creates a fake auxv entry as well.
> >
> >
> >> Is there some other way one can fetch this data? Registers? Memory?
> >
> > I'm not sure how that would work.
>
> If that value was stored in some data structure in the process' memory or
> register, we could get it from there.  But that doesn't seem to be the case,
> it's only given at the create process debug event.

Actually, this value is available in the process memory in the Process
Environment Block (PEB), and can be accessed via:
$_tlb->process_environment_block->image_base_address

Based on this, I wrote this alternative:

static void
windows_solib_create_inferior_hook (int from_tty)
{
  CORE_ADDR tlb;
  if (symfile_objfile && target_get_tib_address (inferior_ptid, &tlb))
    {
      gdb_byte addr_buf[8];
      struct gdbarch *gdbarch = target_gdbarch ();
      int ptr_bytes, peb_offset, base_offset;
      if (gdbarch_ptr_bit (gdbarch) == 32)
    {
      ptr_bytes = 4;
      peb_offset = 48;
      base_offset = 8;
    }
      else
    {
      ptr_bytes = 8;
      peb_offset = 96;
      base_offset = 16;
    }
      if (!target_read_memory (tlb + peb_offset, addr_buf, ptr_bytes))
    {
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
      CORE_ADDR peb
        = extract_unsigned_integer (addr_buf, ptr_bytes, byte_order);
      if (!target_read_memory (peb + base_offset, addr_buf, ptr_bytes))
        {
          CORE_ADDR exec_base
        = extract_unsigned_integer (addr_buf, ptr_bytes, byte_order);
          CORE_ADDR vmaddr = pe_data (exec_bfd)->pe_opthdr.ImageBase;
          if (vmaddr != exec_base)
        objfile_rebase (symfile_objfile, exec_base - vmaddr);
        }
    }
    }
}


I've tested this on 32bit & 64bit, both with and without gdbserver,
and it seems to work fine as well.

I only have one problem with this approach, it doesn't work with my
corefile support for Windows minidumps if TIB or PEB were not included in
the minidump file.

Before, I created a fake .auxv section, just like I did in gdb.



More information about the Gdb-patches mailing list