* [RFC][PATCH v2] Rebase executable to match relocated base address [not found] <20191223140825.5378-1-ssbssa.ref@yahoo.de> @ 2019-12-23 14:08 ` Hannes Domani via gdb-patches 2020-01-16 20:37 ` Hannes Domani via gdb-patches 0 siblings, 1 reply; 3+ messages in thread From: Hannes Domani via gdb-patches @ 2019-12-23 14:08 UTC (permalink / raw) To: gdb-patches 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). The first version of this patch didn't apply on master, this one does. --- 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 449ed5f462..d453b89cdd 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -74,6 +74,7 @@ static int attaching = 0; static HANDLE current_process_handle = NULL; static DWORD current_process_id = 0; static DWORD main_thread_id = 0; +static CORE_ADDR current_exec_base; /* Executable base address */ static enum gdb_signal last_sig = GDB_SIGNAL_0; /* The current debug event from WaitForDebugEvent. */ @@ -1485,6 +1486,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, @@ -1695,6 +1698,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) @@ -1796,7 +1826,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 10d5c95d09..4a5d9230cc 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -235,6 +235,7 @@ static DEBUG_EVENT current_event; /* The current debug event from WaitForDebugEvent */ static HANDLE current_process_handle; /* Currently executing process */ static windows_thread_info *current_thread; /* Info on currently selected thread */ +static CORE_ADDR current_exec_base; /* Executable base address */ /* Counts of things. */ static int exception_count = 0; @@ -1593,6 +1594,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, @@ -2969,6 +2972,35 @@ windows_xfer_shared_libraries (struct target_ops *ops, return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; } +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, @@ -2984,6 +3016,9 @@ windows_nat_target::xfer_partial (enum target_object object, return windows_xfer_shared_libraries (this, object, annex, readbuf, writebuf, 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 bb69a79996..03b69464db 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; @@ -461,6 +465,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); + } +} + /* To be called from the various GDB_OSABI_CYGWIN handlers for the various Windows architectures and machine types. */ @@ -477,6 +495,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); } -- 2.24.1 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC][PATCH v2] Rebase executable to match relocated base address 2019-12-23 14:08 ` [RFC][PATCH v2] Rebase executable to match relocated base address Hannes Domani via gdb-patches @ 2020-01-16 20:37 ` Hannes Domani via gdb-patches 2020-01-21 23:27 ` Tom Tromey 0 siblings, 1 reply; 3+ messages in thread From: Hannes Domani via gdb-patches @ 2020-01-16 20:37 UTC (permalink / raw) To: Gdb-patches Ping. Am Montag, 23. Dezember 2019, 15:08:56 MEZ hat Hannes Domani via gdb-patches <gdb-patches@sourceware.org> Folgendes geschrieben: > 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). > > The first version of this patch didn't apply on master, this one does. > --- > 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 449ed5f462..d453b89cdd 100644 > --- a/gdb/gdbserver/win32-low.c > +++ b/gdb/gdbserver/win32-low.c > @@ -74,6 +74,7 @@ static int attaching = 0; > static HANDLE current_process_handle = NULL; > static DWORD current_process_id = 0; > static DWORD main_thread_id = 0; > +static CORE_ADDR current_exec_base; /* Executable base address */ > static enum gdb_signal last_sig = GDB_SIGNAL_0; > > /* The current debug event from WaitForDebugEvent. */ > @@ -1485,6 +1486,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, > @@ -1695,6 +1698,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) > @@ -1796,7 +1826,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 10d5c95d09..4a5d9230cc 100644 > --- a/gdb/windows-nat.c > +++ b/gdb/windows-nat.c > @@ -235,6 +235,7 @@ static DEBUG_EVENT current_event; /* The current debug event from > WaitForDebugEvent */ > static HANDLE current_process_handle; /* Currently executing process */ > static windows_thread_info *current_thread; /* Info on currently selected thread */ > +static CORE_ADDR current_exec_base; /* Executable base address */ > > /* Counts of things. */ > static int exception_count = 0; > @@ -1593,6 +1594,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, > @@ -2969,6 +2972,35 @@ windows_xfer_shared_libraries (struct target_ops *ops, > return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; > } > > +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, > @@ -2984,6 +3016,9 @@ windows_nat_target::xfer_partial (enum target_object object, > return windows_xfer_shared_libraries (this, object, annex, readbuf, > writebuf, 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 bb69a79996..03b69464db 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; > > @@ -461,6 +465,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); > + } > +} > + > /* To be called from the various GDB_OSABI_CYGWIN handlers for the > various Windows architectures and machine types. */ > > @@ -477,6 +495,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); > } > > -- > 2.24.1 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC][PATCH v2] Rebase executable to match relocated base address 2020-01-16 20:37 ` Hannes Domani via gdb-patches @ 2020-01-21 23:27 ` Tom Tromey 0 siblings, 0 replies; 3+ messages in thread From: Tom Tromey @ 2020-01-21 23:27 UTC (permalink / raw) To: Hannes Domani via gdb-patches; +Cc: Hannes Domani >>>>> "Hannes" == Hannes Domani via gdb-patches <gdb-patches@sourceware.org> writes: >> 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. I don't know about this either :(. Should it use the "library list format" stuff instead? Or, how does it work on Linux? >> >> +static int >> +win32_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len) New functions need an introductory comment. >> >> +static enum target_xfer_status >> +windows_xfer_auxv (gdb_byte *readbuf, ULONGEST offset, ULONGEST len, >> + ULONGEST *xfered_len) Here too. >> + solib_target_so_ops.solib_create_inferior_hook = >> + windows_solib_create_inferior_hook; "=" should be after the line break. Tom ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-01-21 22:38 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <20191223140825.5378-1-ssbssa.ref@yahoo.de> 2019-12-23 14:08 ` [RFC][PATCH v2] Rebase executable to match relocated base address Hannes Domani via gdb-patches 2020-01-16 20:37 ` Hannes Domani via gdb-patches 2020-01-21 23:27 ` Tom Tromey
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).