This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PING] [PATCH] Rebase executable to match relocated base address
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.