From patchwork Sat Jan 25 16:42:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Terekhov, Mikhail via Gdb-patches" X-Patchwork-Id: 37540 Received: (qmail 47267 invoked by alias); 25 Jan 2020 16:47:12 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 47253 invoked by uid 89); 25 Jan 2020 16:47:11 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=flavors, toms, differ, 16058 X-HELO: sonic308-18.consmr.mail.ir2.yahoo.com Received: from sonic308-18.consmr.mail.ir2.yahoo.com (HELO sonic308-18.consmr.mail.ir2.yahoo.com) (77.238.178.146) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 25 Jan 2020 16:47:09 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1579970827; bh=pn27I+Q4IwoRR7ruf6AW1QHNxO1biBW3BrCTlyA1Wxo=; h=From:To:Subject:Date:References:From:Subject; b=cvWpbj0xmoqeEictCA3ml6weLanZidsMv3aFCQmEogpQL21/K6p5PTciM2w5S3zTRb1QeEsFJ16eQgp9aEK0gkGoYLjdptKFMjE5O2BG8dA73h9FN6TIUDTKxBXrBsWIXzgznYF/xQhOPzpGFDHhmIm/tXi/WpJTv5+SRTahhLP+hIpeXTP15+GsdGwEUldRfKPQHCdvECRvfIj01qRXuacZ45xgshWUV6fwvAkU/6P6mjJX6SOup4FbJs1g/bugboTQRggEtVIlig7ZTeDW09IlGkFQ9Ws5mIqlrTkWIXpa5z3cD1KDUVvHch6PwN6tz3TxWJALHiurDrLT5ZYRNQ== Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ir2.yahoo.com with HTTP; Sat, 25 Jan 2020 16:47:07 +0000 Received: by smtp417.mail.ir2.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 5feaee1c599520574f786ec3d9512ce5; Sat, 25 Jan 2020 16:47:06 +0000 (UTC) X-Patchwork-Original-From: "Hannes Domani via gdb-patches" From: "Terekhov, Mikhail via Gdb-patches" Reply-To: Hannes Domani To: gdb-patches@sourceware.org Subject: [PATCH] Rebase executable to match relocated base address Date: Sat, 25 Jan 2020 17:42:32 +0100 Message-Id: <20200125164231.50741-1-ssbssa@yahoo.de> MIME-Version: 1.0 References: <20200125164231.50741-1-ssbssa.ref@yahoo.de> Content-Length: 6966 X-IsSubscribed: yes Compared to the [RFC], only Tom's noticed coding style problems were fixed. binutils 2.34 will have an improved -dynamicbase (so far this only worked with some workarounds for executables), so the rebasing problem might get more relevant in the future. 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. The transfer of the new base address is done via a fake auxv entry, so it's working with gdbserver as well. gdb/ChangeLog: 2020-01-25 Hannes Domani * windows-nat.c (windows_nat_target::get_windows_debug_event): Set current_exec_base. (windows_xfer_auxv): New function. (windows_nat_target::xfer_partial): Call windows_xfer_auxv. * windows-tdep.c (windows_solib_create_inferior_hook): New function. (windows_init_abi): Use windows_solib_create_inferior_hook. gdb/gdbserver/ChangeLog: 2020-01-25 Hannes Domani * win32-low.c (get_child_debug_event): Set current_exec_base. (win32_read_auxv): New function. --- gdb/gdbserver/win32-low.c | 35 ++++++++++++++++++++++++++++++++++- gdb/windows-nat.c | 38 ++++++++++++++++++++++++++++++++++++++ gdb/windows-tdep.c | 20 ++++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index 2c4a9b1074..2f6fe5785e 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -75,6 +75,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. */ @@ -1486,6 +1487,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, @@ -1713,6 +1716,36 @@ win32_request_interrupt (void) soft_interrupt_requested = 1; } +/* Windows does not have auxv, but this creates a fake AT_ENTRY entry + which is the base address of the executable. */ + +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) @@ -1814,7 +1847,7 @@ static process_stratum_target 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 366c98fbf3..459bb10fe9 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 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; @@ -1604,6 +1605,8 @@ windows_nat_target::get_windows_debug_event (int pid, 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, @@ -2996,6 +2999,38 @@ windows_xfer_shared_libraries (struct target_ops *ops, return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; } +/* Windows does not have auxv, but this creates a fake AT_ENTRY entry + which is the base address of the executable. */ + +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, @@ -3011,6 +3046,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 6c9632d035..fd491e8e67 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" /* Windows signal numbers differ between MinGW flavors and between those and Cygwin. The below enumeration was gleaned from the @@ -656,6 +660,20 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) return -1; } +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. */ @@ -674,6 +692,8 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_gdb_signal_to_target (gdbarch, windows_gdb_signal_to_target); + solib_target_so_ops.solib_create_inferior_hook + = windows_solib_create_inferior_hook; set_solib_ops (gdbarch, &solib_target_so_ops); }