From patchwork Sun Dec 22 17:00:00 2019 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: 37068 Received: (qmail 103457 invoked by alias); 22 Dec 2019 17:00:46 -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 103311 invoked by uid 89); 22 Dec 2019 17:00:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.8 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=4896, rebasing, HContent-Transfer-Encoding:8bit X-HELO: sonic314-19.consmr.mail.ir2.yahoo.com Received: from sonic314-19.consmr.mail.ir2.yahoo.com (HELO sonic314-19.consmr.mail.ir2.yahoo.com) (77.238.177.145) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 22 Dec 2019 17:00:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1577034020; bh=PBefVEK7J5K6aAI2NIavnUNaHjATLD/lb5yhQTQHvDM=; h=From:To:Subject:Date:References:From:Subject; b=VrYebIV6mRmuXB0hAlGXmLfOvI+J400eX8WFvwb2CQk43NJyn5RVrIKkxuBlZ+k691LnsW0eGlX9rRZ2Vg4RD7CiLp10BOCMwzRn4XBIgUInBapEJfvxrdBUihACy6t9vxGM6V6nQR2MOTkjqSkdoIJijG20qVWN8J70amuxbzdkmjdkewv5uyCJ3DBOFmupFC45zFI4YHHopgkZ//Y7w2evpwPXKUKuyvrrTBdnDOJ0T2EwElwTx+XPEjZ2BewpE1q4LA/MYqMVpYqGojRFL113sjhdzItdG8nn9EFaOX3e9+SzhmNI7F2YyHh1PlMAKIn7Q1s2SvkglaTCrczZkw== Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ir2.yahoo.com with HTTP; Sun, 22 Dec 2019 17:00:20 +0000 Received: by smtp409.mail.ir2.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d3a7ea716eeaa207e8938120e4d50a67; Sun, 22 Dec 2019 17:00:14 +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: [RFC][PATCH] Rebase executable to match relocated base address Date: Sun, 22 Dec 2019 18:00:00 +0100 Message-Id: <20191222170000.7548-1-ssbssa@yahoo.de> MIME-Version: 1.0 References: <20191222170000.7548-1-ssbssa.ref@yahoo.de> Content-Length: 6308 X-IsSubscribed: yes 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);