[RFC][PATCH] Rebase executable to match relocated base address
Hannes Domani via gdb-patches
gdb-patches@sourceware.org
Sun Dec 22 17:00:00 GMT 2019
Windows executables linked with -dynamicbase get a new base address
when loaded, which makes debugging impossible if the executable isn't
also rebased in gdb.
solib_create_inferior_hook looked like the right place for rebasing,
since there is similar code in solib_aix_solib_create_inferior_hook
and darwin_solib_create_inferior_hook.
But I'm not at all sure about my approach to forward the image base
via auxv data, but I needed a solution that worked for gdbserver as well.
Also I just reused AT_ENTRY, which is not nice at all.
I guess a new define should be created (where?), and a new auxv print function
registered with set_gdbarch_print_auxv_entry, but since I'm not sure
if the auxv approach is even correct, I didn't bother with this (for now).
---
gdb/gdbserver/win32-low.c | 32 +++++++++++++++++++++++++++++++-
gdb/windows-nat.c | 35 +++++++++++++++++++++++++++++++++++
gdb/windows-tdep.c | 20 ++++++++++++++++++++
3 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 33171ba7d2..33dd771998 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -75,6 +75,7 @@ static HANDLE current_process_handle = NULL;
static DWORD current_process_id = 0;
static DWORD main_thread_id = 0;
static EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
+static CORE_ADDR current_exec_base; /* Executable base address */
static enum gdb_signal last_sig = GDB_SIGNAL_0;
/* The current debug event from WaitForDebugEvent. */
@@ -1490,6 +1491,8 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
current_process_handle = current_event.u.CreateProcessInfo.hProcess;
main_thread_id = current_event.dwThreadId;
+ current_exec_base =
+ (CORE_ADDR) current_event.u.CreateProcessInfo.lpBaseOfImage;
/* Add the main thread. */
child_add_thread (current_event.dwProcessId,
@@ -1700,6 +1703,33 @@ win32_request_interrupt (void)
soft_interrupt_requested = 1;
}
+static int
+win32_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
+{
+ size_t buf[4];
+
+ if (!myaddr)
+ return -1;
+
+ if (offset > sizeof (buf))
+ return -1;
+
+ if (offset == sizeof (buf))
+ return 0;
+
+ if (offset + len > sizeof (buf))
+ len = sizeof (buf) - offset;
+
+ buf[0] = 9; /* AT_ENTRY */
+ buf[1] = current_exec_base;
+ buf[2] = 0; /* AT_NULL */
+ buf[3] = 0;
+
+ memcpy (myaddr, (char *) buf + offset, len);
+
+ return len;
+}
+
#ifdef _WIN32_WCE
int
win32_error_to_fileio_error (DWORD err)
@@ -1822,7 +1852,7 @@ static struct target_ops win32_target_ops = {
win32_write_inferior_memory,
NULL, /* lookup_symbols */
win32_request_interrupt,
- NULL, /* read_auxv */
+ win32_read_auxv,
win32_supports_z_point_type,
win32_insert_point,
win32_remove_point,
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index bb7d02b770..7e0dedee68 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -236,6 +236,7 @@ static DEBUG_EVENT current_event; /* The current debug event from
static HANDLE current_process_handle; /* Currently executing process */
static windows_thread_info *current_thread; /* Info on currently selected thread */
static EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
+static CORE_ADDR current_exec_base; /* Executable base address */
/* Counts of things. */
static int exception_count = 0;
@@ -1597,6 +1598,8 @@ get_windows_debug_event (struct target_ops *ops,
break;
current_process_handle = current_event.u.CreateProcessInfo.hProcess;
+ current_exec_base =
+ (CORE_ADDR) current_event.u.CreateProcessInfo.lpBaseOfImage;
/* Add the main thread. */
th = windows_add_thread
(ptid_t (current_event.dwProcessId, 0,
@@ -2997,6 +3000,35 @@ windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len,
return TARGET_XFER_OK;
}
+static enum target_xfer_status
+windows_xfer_auxv (gdb_byte *readbuf, ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
+{
+ CORE_ADDR buf[4];
+
+ if (!readbuf)
+ return TARGET_XFER_E_IO;
+
+ if (offset > sizeof (buf))
+ return TARGET_XFER_E_IO;
+
+ if (offset == sizeof (buf))
+ return TARGET_XFER_EOF;
+
+ if (offset + len > sizeof (buf))
+ len = sizeof (buf) - offset;
+
+ buf[0] = 9; /* AT_ENTRY */
+ buf[1] = current_exec_base;
+ buf[2] = 0; /* AT_NULL */
+ buf[3] = 0;
+
+ memcpy (readbuf, (char *) buf + offset, len);
+ *xfered_len = len;
+
+ return TARGET_XFER_OK;
+}
+
enum target_xfer_status
windows_nat_target::xfer_partial (enum target_object object,
const char *annex, gdb_byte *readbuf,
@@ -3015,6 +3047,9 @@ windows_nat_target::xfer_partial (enum target_object object,
case TARGET_OBJECT_SIGNAL_INFO:
return windows_xfer_siginfo (readbuf, offset, len, xfered_len);
+ case TARGET_OBJECT_AUXV:
+ return windows_xfer_auxv (readbuf, offset, len, xfered_len);
+
default:
if (beneath () == NULL)
{
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 9353f191d9..e3bd34f8ac 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -34,6 +34,10 @@
#include "solib.h"
#include "solib-target.h"
#include "gdbcore.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+#include "solist.h"
+#include "auxv.h"
struct cmd_list_element *info_w32_cmdlist;
@@ -489,6 +493,20 @@ init_w32_command_list (void)
}
}
+static void
+windows_solib_create_inferior_hook (int from_tty)
+{
+ CORE_ADDR exec_base;
+ /* 9 -> AT_ENTRY */
+ if (target_auxv_search (current_top_target (), 9, &exec_base) == 1
+ && exec_base && symfile_objfile)
+ {
+ CORE_ADDR vmaddr = pe_data (exec_bfd)->pe_opthdr.ImageBase;
+ if (vmaddr != exec_base)
+ objfile_rebase (symfile_objfile, exec_base - vmaddr);
+ }
+}
+
struct enum_value_name
{
uint32_t value;
@@ -622,6 +640,8 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_iterate_over_objfiles_in_search_order
(gdbarch, windows_iterate_over_objfiles_in_search_order);
+ solib_target_so_ops.solib_create_inferior_hook =
+ windows_solib_create_inferior_hook;
set_solib_ops (gdbarch, &solib_target_so_ops);
set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
--
2.24.1
More information about the Gdb-patches
mailing list