* [PING] [PATCH] Rebase executable to match relocated base address
[not found] <691075103.286431.1581179823782.ref@mail.yahoo.com>
@ 2020-02-08 16:37 ` Hannes Domani via gdb-patches
2020-02-11 0:29 ` Luis Machado
0 siblings, 1 reply; 7+ messages in thread
From: Hannes Domani via gdb-patches @ 2020-02-08 16:37 UTC (permalink / raw)
To: Gdb-patches
Ping.
Am Samstag, 25. Januar 2020, 17:47:19 MEZ hat Hannes Domani via gdb-patches <gdb-patches@sourceware.org> Folgendes geschrieben:
> 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 <ssbssa@yahoo.de>
>
> * 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 <ssbssa@yahoo.de>
>
> * 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);
> }
>
> --
> 2.25.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PING] [PATCH] Rebase executable to match relocated base address
2020-02-08 16:37 ` [PING] [PATCH] Rebase executable to match relocated base address Hannes Domani via gdb-patches
@ 2020-02-11 0:29 ` Luis Machado
2020-02-11 11:34 ` Hannes Domani via gdb-patches
0 siblings, 1 reply; 7+ messages in thread
From: Luis Machado @ 2020-02-11 0:29 UTC (permalink / raw)
To: Hannes Domani, Gdb-patches
On 2/8/20 1:37 PM, Hannes Domani via gdb-patches wrote:
> Ping.
>
> Am Samstag, 25. Januar 2020, 17:47:19 MEZ hat Hannes Domani via gdb-patches <gdb-patches@sourceware.org> Folgendes geschrieben:
>
>> 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 <ssbssa@yahoo.de>
>>
>> Â Â Â Â * 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 <ssbssa@yahoo.de>
>>
>> Â Â Â Â * 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 */
Set current_exec_base to 0 so it gets explicitly initialized?
>> 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;
Formatting of the second line looks funny. Should be moved forward.
Has the lpBaseOfImage member variable always been there and was never
used? From what i looked at MSDN, it looks like it.
>>
>>       /* 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)
Missing documentation for this function.
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.
Is there some other way one can fetch this data? Registers? Memory?
If not, then maybe we could create a new qxfer request to fetch this
data for Windows, say, TARGET_OBJECT_WINDOWS_LOADBASE. It would be
cleaner and would handle both gdbserver and gdb.
In case we want to make the request more generic, maybe call it
TARGET_OBJECT_EXEC_LOADBASE or somesuch.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PING] [PATCH] Rebase executable to match relocated base address
2020-02-11 0:29 ` Luis Machado
@ 2020-02-11 11:34 ` Hannes Domani via gdb-patches
2020-02-12 4:49 ` Simon Marchi
0 siblings, 1 reply; 7+ messages in thread
From: Hannes Domani via gdb-patches @ 2020-02-11 11:34 UTC (permalink / raw)
To: Gdb-patches
Am Dienstag, 11. Februar 2020, 01:29:44 MEZ hat Luis Machado <luis.machado@linaro.org> Folgendes geschrieben:
> On 2/8/20 1:37 PM, Hannes Domani via gdb-patches wrote:
> > Ping.
> >
> > Am Samstag, 25. Januar 2020, 17:47:19 MEZ hat Hannes Domani via gdb-patches <gdb-patches@sourceware.org> Folgendes geschrieben:
> >
> >> 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 <ssbssa@yahoo.de>
> >>
> >> * 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 <ssbssa@yahoo.de>
> >>
> >> * 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 */
>
> Set current_exec_base to 0 so it gets explicitly initialized?
OK.
> >> 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;
>
> Formatting of the second line looks funny. Should be moved forward.
OK.
> Has the lpBaseOfImage member variable always been there and was never
> used? From what i looked at MSDN, it looks like it.
Yes.
> >>
> >> /* 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)
>
>
> Missing documentation for this function.
Right.
> 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 not, then maybe we could create a new qxfer request to fetch this
> data for Windows, say, TARGET_OBJECT_WINDOWS_LOADBASE. It would be
> cleaner and would handle both gdbserver and gdb.
>
> In case we want to make the request more generic, maybe call it
> TARGET_OBJECT_EXEC_LOADBASE or somesuch.
I agree that this would be the cleanest solution, but I thought touching
the gdbserver interface isn't the best idea when it can be avoided.
Regards
Hannes Domani
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PING] [PATCH] Rebase executable to match relocated base address
2020-02-11 11:34 ` Hannes Domani via gdb-patches
@ 2020-02-12 4:49 ` Simon Marchi
2020-02-12 18:05 ` Hannes Domani via gdb-patches
0 siblings, 1 reply; 7+ messages in thread
From: Simon Marchi @ 2020-02-12 4:49 UTC (permalink / raw)
To: Hannes Domani, Gdb-patches; +Cc: Luis Machado
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.
>> If not, then maybe we could create a new qxfer request to fetch this
>> data for Windows, say, TARGET_OBJECT_WINDOWS_LOADBASE. It would be
>> cleaner and would handle both gdbserver and gdb.
>>
>> In case we want to make the request more generic, maybe call it
>> TARGET_OBJECT_EXEC_LOADBASE or somesuch.
>
> I agree that this would be the cleanest solution, but I thought touching
> the gdbserver interface isn't the best idea when it can be avoided.
I lean towards Luis' side, I think it's worth taking the time to do things right,
since once it's published it's hard to change. auxv is not really meant to be an
abstraction to be used on all platforms.
So there's Luis' suggestion of a new target object. I also noticed there's a
qGetTIBAddr packet that does a similar job. Should we introduce a new dedicated
packet just like this one, or is that an old/obsolete way of doing things?
Simon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PING] [PATCH] Rebase executable to match relocated base address
2020-02-12 4:49 ` Simon Marchi
@ 2020-02-12 18:05 ` Hannes Domani via gdb-patches
2020-02-12 18:19 ` Christian Biesinger via gdb-patches
0 siblings, 1 reply; 7+ messages in thread
From: Hannes Domani via gdb-patches @ 2020-02-12 18:05 UTC (permalink / raw)
To: Gdb-patches
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.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PING] [PATCH] Rebase executable to match relocated base address
2020-02-12 18:05 ` Hannes Domani via gdb-patches
@ 2020-02-12 18:19 ` Christian Biesinger via gdb-patches
2020-02-12 18:38 ` Hannes Domani via gdb-patches
0 siblings, 1 reply; 7+ messages in thread
From: Christian Biesinger via gdb-patches @ 2020-02-12 18:19 UTC (permalink / raw)
To: Hannes Domani; +Cc: Gdb-patches
On Wed, Feb 12, 2020 at 12:05 PM Hannes Domani via gdb-patches
<gdb-patches@sourceware.org> wrote:
> 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.
Sorry for the tangent, but I was also working on supporting minidumps
in GDB -- could you share your code?
Thanks!
Christian
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PING] [PATCH] Rebase executable to match relocated base address
2020-02-12 18:19 ` Christian Biesinger via gdb-patches
@ 2020-02-12 18:38 ` Hannes Domani via gdb-patches
0 siblings, 0 replies; 7+ messages in thread
From: Hannes Domani via gdb-patches @ 2020-02-12 18:38 UTC (permalink / raw)
To: Gdb-patches
[-- Attachment #1: Type: text/plain, Size: 734 bytes --]
Am Mittwoch, 12. Februar 2020, 19:19:17 MEZ hat Christian Biesinger via gdb-patches <gdb-patches@sourceware.org> Folgendes geschrieben:
> On Wed, Feb 12, 2020 at 12:05 PM Hannes Domani via gdb-patches
>
> <gdb-patches@sourceware.org> wrote:
> > 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.
>
>
> Sorry for the tangent, but I was also working on supporting minidumps
> in GDB -- could you share your code?
Sure, I planned to submit the code soon anyways.
It should be working completely, but the code is not ready for integration yet.
[-- Attachment #2: 0001-Move-core-file-functions-from-i386-cygwin-tdep.c-to-.patch --]
[-- Type: application/octet-stream, Size: 6908 bytes --]
From 6529902c3eadf608b0a70680888e0f7d00ea3026 Mon Sep 17 00:00:00 2001
From: Hannes Domani <ssbssa@yahoo.de>
Date: Wed, 30 Jan 2019 23:31:12 +0100
Subject: [PATCH 1/6] Move core file functions from i386-cygwin-tdep.c to
windows-tdep.c.
---
gdb/i386-cygwin-tdep.c | 104 -------------------------------------------------
gdb/windows-tdep.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 104 deletions(-)
diff --git a/gdb/i386-cygwin-tdep.c b/gdb/i386-cygwin-tdep.c
index cb66632648..346e95d12a 100644
--- a/gdb/i386-cygwin-tdep.c
+++ b/gdb/i386-cygwin-tdep.c
@@ -88,105 +88,6 @@ static int i386_windows_gregset_reg_offset[] =
#define I386_WINDOWS_SIZEOF_GREGSET 716
-struct cpms_data
-{
- struct gdbarch *gdbarch;
- struct obstack *obstack;
- int module_count;
-};
-
-static void
-core_process_module_section (bfd *abfd, asection *sect, void *obj)
-{
- struct cpms_data *data = (struct cpms_data *) obj;
- enum bfd_endian byte_order = gdbarch_byte_order (data->gdbarch);
-
- char *module_name;
- size_t module_name_size;
- CORE_ADDR base_addr;
-
- gdb_byte *buf = NULL;
-
- if (!startswith (sect->name, ".module"))
- return;
-
- buf = (gdb_byte *) xmalloc (bfd_section_size (sect) + 1);
- if (!buf)
- {
- printf_unfiltered ("memory allocation failed for %s\n", sect->name);
- goto out;
- }
- if (!bfd_get_section_contents (abfd, sect,
- buf, 0, bfd_section_size (sect)))
- goto out;
-
-
-
- /* A DWORD (data_type) followed by struct windows_core_module_info. */
-
- base_addr =
- extract_unsigned_integer (buf + 4, 4, byte_order);
-
- module_name_size =
- extract_unsigned_integer (buf + 8, 4, byte_order);
-
- if (12 + module_name_size > bfd_section_size (sect))
- goto out;
- module_name = (char *) buf + 12;
-
- /* The first module is the .exe itself. */
- if (data->module_count != 0)
- windows_xfer_shared_library (module_name, base_addr,
- NULL, data->gdbarch, data->obstack);
- data->module_count++;
-
-out:
- if (buf)
- xfree (buf);
- return;
-}
-
-static ULONGEST
-windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
- gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
-{
- struct obstack obstack;
- const char *buf;
- ULONGEST len_avail;
- struct cpms_data data = { gdbarch, &obstack, 0 };
-
- obstack_init (&obstack);
- obstack_grow_str (&obstack, "<library-list>\n");
- bfd_map_over_sections (core_bfd,
- core_process_module_section,
- &data);
- obstack_grow_str0 (&obstack, "</library-list>\n");
-
- buf = (const char *) obstack_finish (&obstack);
- len_avail = strlen (buf);
- if (offset >= len_avail)
- return 0;
-
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
-
- obstack_free (&obstack, NULL);
- return len;
-}
-
-/* This is how we want PTIDs from core files to be printed. */
-
-static std::string
-i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
-{
- if (ptid.lwp () != 0)
- return string_printf ("Thread 0x%lx", ptid.lwp ());
-
- return normal_pid_to_str (ptid);
-}
-
static CORE_ADDR
i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
@@ -218,11 +119,6 @@ i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sizeof_fpregset = 0;
- /* Core file support. */
- set_gdbarch_core_xfer_shared_libraries
- (gdbarch, windows_core_xfer_shared_libraries);
- set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
-
set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset);
}
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 6eef3fbd96..91a778cd81 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -812,6 +812,105 @@ windows_get_siginfo_type (struct gdbarch *gdbarch)
return siginfo_type;
}
+struct cpms_data
+{
+ struct gdbarch *gdbarch;
+ struct obstack *obstack;
+ int module_count;
+};
+
+static void
+core_process_module_section (bfd *abfd, asection *sect, void *obj)
+{
+ struct cpms_data *data = (struct cpms_data *) obj;
+ enum bfd_endian byte_order = gdbarch_byte_order (data->gdbarch);
+
+ char *module_name;
+ size_t module_name_size;
+ CORE_ADDR base_addr;
+
+ gdb_byte *buf = NULL;
+
+ if (!startswith (sect->name, ".module"))
+ return;
+
+ buf = (gdb_byte *) xmalloc (bfd_section_size (sect) + 1);
+ if (!buf)
+ {
+ printf_unfiltered ("memory allocation failed for %s\n", sect->name);
+ goto out;
+ }
+ if (!bfd_get_section_contents (abfd, sect,
+ buf, 0, bfd_section_size (sect)))
+ goto out;
+
+
+
+ /* A DWORD (data_type) followed by struct windows_core_module_info. */
+
+ base_addr =
+ extract_unsigned_integer (buf + 4, 4, byte_order);
+
+ module_name_size =
+ extract_unsigned_integer (buf + 8, 4, byte_order);
+
+ if (12 + module_name_size > bfd_section_size (sect))
+ goto out;
+ module_name = (char *) buf + 12;
+
+ /* The first module is the .exe itself. */
+ if (data->module_count != 0)
+ windows_xfer_shared_library (module_name, base_addr,
+ NULL, data->gdbarch, data->obstack);
+ data->module_count++;
+
+out:
+ if (buf)
+ xfree (buf);
+ return;
+}
+
+static ULONGEST
+windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
+ gdb_byte *readbuf,
+ ULONGEST offset, ULONGEST len)
+{
+ struct obstack obstack;
+ const char *buf;
+ ULONGEST len_avail;
+ struct cpms_data data = { gdbarch, &obstack, 0 };
+
+ obstack_init (&obstack);
+ obstack_grow_str (&obstack, "<library-list>\n");
+ bfd_map_over_sections (core_bfd,
+ core_process_module_section,
+ &data);
+ obstack_grow_str0 (&obstack, "</library-list>\n");
+
+ buf = (const char *) obstack_finish (&obstack);
+ len_avail = strlen (buf);
+ if (offset >= len_avail)
+ return 0;
+
+ if (len > len_avail - offset)
+ len = len_avail - offset;
+ memcpy (readbuf, buf + offset, len);
+
+ obstack_free (&obstack, NULL);
+ return len;
+}
+
+/* This is how we want PTIDs from core files to be printed. */
+
+static std::string
+i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
+{
+ if (ptid.lwp () != 0)
+ return string_printf ("Thread 0x%lx", ptid.lwp ());
+
+ return normal_pid_to_str (ptid);
+}
+
/* To be called from the various GDB_OSABI_CYGWIN handlers for the
various Windows architectures and machine types. */
@@ -833,6 +932,11 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_solib_ops (gdbarch, &solib_target_so_ops);
set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
+
+ /* Core file support. */
+ set_gdbarch_core_xfer_shared_libraries
+ (gdbarch, windows_core_xfer_shared_libraries);
+ set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
}
/* Implementation of `tlb' variable. */
--
2.15.1.windows.2
[-- Attachment #3: 0002-Read-minidump-file.patch --]
[-- Type: application/octet-stream, Size: 15168 bytes --]
From 1f1ebe21723580a1bd53e97779912114ab2fa532 Mon Sep 17 00:00:00 2001
From: Hannes Domani <ssbssa@yahoo.de>
Date: Thu, 31 Jan 2019 00:48:50 +0100
Subject: [PATCH 2/6] Read minidump file.
---
bfd/coff-i386.c | 2 +-
bfd/coff-x86_64.c | 2 +-
bfd/coffgen.c | 415 +++++++++++++++++++++++++++++++++++++++++++++++
bfd/libcoff-in.h | 3 +
bfd/libcoff.h | 3 +
gdb/amd64-windows-tdep.c | 76 +++++++++
gdb/windows-tdep.c | 29 +++-
7 files changed, 527 insertions(+), 3 deletions(-)
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index 7fb59dd31c..705df2eb75 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -677,7 +677,7 @@ const bfd_target
_bfd_dummy_target,
coff_object_p,
bfd_generic_archive_p,
- coff_object_p
+ coff_core_file_p
},
#endif
{ /* bfd_set_format */
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index e0b32fddb8..0dc0136cd5 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -795,7 +795,7 @@ const bfd_target
_bfd_dummy_target,
amd64coff_object_p,
bfd_generic_archive_p,
- amd64coff_object_p
+ coff_core_file_p
},
{ /* bfd_set_format. */
_bfd_bool_bfd_false_error,
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 31e6fa7a08..f9f2530952 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -3183,3 +3183,418 @@ _bfd_coff_close_and_cleanup (bfd *abfd)
}
return _bfd_generic_close_and_cleanup (abfd);
}
+
+/* Read minidump file. */
+
+#pragma pack(push,4)
+
+typedef struct
+{
+ uint8_t sig[4];
+ uint32_t ver;
+ uint32_t streamCount;
+ uint32_t streamRva;
+ uint32_t checksum;
+ uint32_t timestamp;
+ uint64_t flags;
+}
+dump_header;
+
+typedef struct
+{
+ uint32_t size;
+ uint32_t rva;
+}
+dump_loc_desc;
+
+typedef struct
+{
+ uint32_t type;
+ dump_loc_desc loc;
+}
+dump_directory;
+
+typedef enum
+{
+ UnusedStream,
+ ReservedStream0,
+ ReservedStream1,
+ ThreadListStream,
+ ModuleListStream,
+ MemoryListStream,
+ ExceptionStream,
+ SystemInfoStream,
+ ThreadExListStream,
+ Memory64ListStream,
+ CommentStreamA,
+ CommentStreamW,
+ HandleDataStream,
+ FunctionTableStream,
+ UnloadedModuleListStream,
+ MiscInfoStream,
+ MemoryInfoListStream,
+ ThreadInfoListStream,
+ HandleOperationListStream,
+ TokenStream,
+ JavaScriptDataStream,
+ SystemMemoryInfoStream,
+ ProcessVmCountersStream,
+ IptTraceStream,
+ ThreadNamesStream,
+ ceStreamNull,
+ ceStreamSystemInfo,
+ ceStreamException,
+ ceStreamModuleList,
+ ceStreamProcessList,
+ ceStreamThreadList,
+ ceStreamThreadContextList,
+ ceStreamThreadCallStackList,
+ ceStreamMemoryVirtualList,
+ ceStreamMemoryPhysicalList,
+ ceStreamBucketParameters,
+ ceStreamProcessModuleMap,
+ ceStreamDiagnosisList,
+ LastReservedStream
+}
+dump_stream_type;
+
+typedef struct
+{
+ uint64_t startAddress;
+ dump_loc_desc memory;
+}
+dump_memory_desc;
+
+typedef struct
+{
+ uint32_t threadId;
+ uint32_t suspendCount;
+ uint32_t priorityClass;
+ uint32_t priority;
+ uint64_t teb;
+ dump_memory_desc stack;
+ dump_loc_desc context;
+}
+dump_thread;
+
+typedef struct
+{
+ uint64_t startAddress;
+ uint64_t size;
+}
+dump_memory_desc64;
+
+typedef struct
+{
+ uint64_t rangeCount;
+ uint64_t baseRva;
+}
+dump_memory64_list;
+
+typedef struct
+{
+ uint32_t code;
+ uint32_t flags;
+ uint64_t record;
+ uint64_t address;
+ uint32_t parameterCount;
+ uint32_t unusedAlign;
+ uint64_t information[15];
+}
+dump_exception;
+
+typedef struct
+{
+ uint32_t threadId;
+ uint32_t unusedAlign;
+ dump_exception record;
+ dump_loc_desc context;
+}
+dump_exception_stream;
+
+typedef struct
+{
+ uint32_t signature;
+ uint32_t structVersion;
+ uint32_t fileVersionMS;
+ uint32_t fileVersionLS;
+ uint32_t productVersionMS;
+ uint32_t productVersionLS;
+ uint32_t fileFlagsMask;
+ uint32_t fileFlags;
+ uint32_t fileOS;
+ uint32_t fileType;
+ uint32_t fileSubtype;
+ uint32_t fileDateMS;
+ uint32_t fileDateLS;
+}
+dump_file_info;
+
+typedef struct
+{
+ uint64_t base;
+ uint32_t size;
+ uint32_t checksum;
+ uint32_t timestamp;
+ uint32_t nameRva;
+ dump_file_info versionInfo;
+ dump_loc_desc cvRecord;
+ dump_loc_desc miscRecord;
+ uint64_t reserved0;
+ uint64_t reserved1;
+}
+dump_module;
+
+#pragma pack(pop)
+
+
+static asection *
+make_bfd_asection (bfd *abfd, const char *name, flagword flags,
+ file_ptr filepos, bfd_size_type size, bfd_vma vma)
+{
+ asection *asect;
+ char *newname;
+
+ newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
+ if (!newname)
+ return NULL;
+
+ strcpy (newname, name);
+
+ asect = bfd_make_section_anyway_with_flags (abfd, newname, flags);
+ if (!asect)
+ return NULL;
+
+ asect->filepos = filepos;
+ asect->size = size;
+ asect->vma = vma;
+
+ return asect;
+}
+
+const bfd_target *
+coff_core_file_p (bfd *abfd)
+{
+ dump_header header;
+ asection *sec;
+ uint32_t s;
+ uint32_t moduleListRva = 0;
+ uint32_t memoryListRva = 0;
+ uint32_t memory64ListRva = 0;
+ uint32_t exceptionRva = 0;
+ uint32_t threadListRva = 0;
+ uint32_t systemInfoRva = 0;
+
+ if (bfd_bread (&header, sizeof header, abfd) != sizeof header)
+ goto fail;
+
+ if (header.sig[0] != 'M' || header.sig[1] != 'D' ||
+ header.sig[2] != 'M' || header.sig[3] != 'P')
+ goto fail;
+
+ for (s = 0; s < header.streamCount; s++)
+ {
+ dump_directory dir;
+ if (bfd_bread (&dir, sizeof dir, abfd) != sizeof dir)
+ goto fail;
+
+ switch (dir.type)
+ {
+ case ModuleListStream:
+ moduleListRva = dir.loc.rva;
+ break;
+ case MemoryListStream:
+ memoryListRva = dir.loc.rva;
+ break;
+ case Memory64ListStream:
+ memory64ListRva = dir.loc.rva;
+ break;
+ case ExceptionStream:
+ exceptionRva = dir.loc.rva;
+ break;
+ case ThreadListStream:
+ threadListRva = dir.loc.rva;
+ break;
+ case SystemInfoStream:
+ systemInfoRva = dir.loc.rva;
+ break;
+ }
+ }
+
+ if (moduleListRva)
+ {
+ uint32_t moduleCount;
+ dump_module module;
+ char secname[32];
+ uint32_t size;
+ uint32_t m;
+
+ if (bfd_seek (abfd, moduleListRva, SEEK_SET) != 0
+ || bfd_bread (&moduleCount, sizeof moduleCount, abfd)
+ != sizeof moduleCount)
+ goto fail;
+
+ for (m = 0; m < moduleCount; m++)
+ {
+ if (bfd_bread (&module, sizeof module, abfd) != sizeof module)
+ goto fail;
+
+ if (bfd_seek (abfd, module.nameRva, SEEK_SET) != 0
+ || bfd_bread (&size, sizeof size, abfd) != sizeof size)
+ goto fail;
+
+ sprintf (secname, ".coremodule/%llx", module.base);
+
+ sec = make_bfd_asection (abfd, secname,
+ SEC_HAS_CONTENTS,
+ module.nameRva + 4,
+ size,
+ 0);
+ if (!sec)
+ goto fail;
+
+ if (bfd_seek (abfd, moduleListRva + 4 + (m + 1) * sizeof module,
+ SEEK_SET) != 0)
+ goto fail;
+ }
+ }
+
+ if (memoryListRva)
+ {
+ dump_memory_desc desc;
+ uint32_t rangeCount;
+ uint32_t r;
+
+ if (bfd_seek (abfd, memoryListRva, SEEK_SET) != 0
+ || bfd_bread (&rangeCount, sizeof rangeCount, abfd)
+ != sizeof rangeCount)
+ goto fail;
+
+ for (r = 0; r < rangeCount; r++)
+ {
+ if (bfd_bread (&desc, sizeof desc, abfd) != sizeof desc)
+ goto fail;
+
+ sec = make_bfd_asection (abfd, ".data",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ desc.memory.rva,
+ desc.memory.size,
+ desc.startAddress);
+ if (!sec)
+ goto fail;
+ }
+ }
+
+ if (memory64ListRva)
+ {
+ dump_memory64_list list64;
+ dump_memory_desc64 desc64;
+ uint64_t r;
+
+ if (bfd_seek (abfd, memory64ListRva, SEEK_SET) != 0
+ || bfd_bread (&list64, sizeof list64, abfd) != sizeof list64)
+ goto fail;
+
+ for (r = 0; r < list64.rangeCount; r++)
+ {
+ if (bfd_bread (&desc64, sizeof desc64, abfd) != sizeof desc64)
+ goto fail;
+
+ sec = make_bfd_asection (abfd, ".data",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ list64.baseRva,
+ desc64.size,
+ desc64.startAddress);
+ if (!sec)
+ goto fail;
+
+ list64.baseRva += desc64.size;
+ }
+ }
+
+ uint32_t exceptionThreadId = 0;
+ if (exceptionRva)
+ {
+ dump_exception_stream exception;
+ char secname[32];
+
+ if (bfd_seek (abfd, exceptionRva, SEEK_SET) != 0
+ || bfd_bread (&exception, sizeof exception, abfd) != sizeof exception)
+ goto fail;
+
+ sec = make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ exception.context.rva,
+ exception.context.size,
+ 0);
+ if (!sec)
+ goto fail;
+
+ sprintf (secname, ".reg/%u", exception.threadId);
+ sec = make_bfd_asection (abfd, secname,
+ SEC_HAS_CONTENTS,
+ exception.context.rva,
+ exception.context.size,
+ 0);
+ if (!sec)
+ goto fail;
+
+ exceptionThreadId = exception.threadId;
+ }
+
+ if (threadListRva)
+ {
+ uint32_t threadCount;
+ dump_thread thread;
+ char secname[32];
+ uint32_t t;
+
+ if (bfd_seek (abfd, threadListRva, SEEK_SET) != 0
+ || bfd_bread (&threadCount, sizeof threadCount, abfd)
+ != sizeof threadCount)
+ goto fail;
+
+ for (t = 0; t < threadCount; t++)
+ {
+ if (bfd_bread (&thread, sizeof thread, abfd) != sizeof thread)
+ goto fail;
+
+ sec = make_bfd_asection (abfd, ".stack",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ thread.stack.memory.rva,
+ thread.stack.memory.size,
+ thread.stack.startAddress);
+ if (!sec)
+ goto fail;
+
+ if (thread.threadId != exceptionThreadId)
+ {
+ sprintf (secname, ".reg/%u", thread.threadId);
+ sec = make_bfd_asection (abfd, secname,
+ SEC_HAS_CONTENTS,
+ thread.context.rva,
+ thread.context.size,
+ 0);
+ if (!sec)
+ goto fail;
+ }
+ }
+ }
+
+ if (systemInfoRva)
+ {
+ uint16_t arch;
+ if (bfd_seek (abfd, systemInfoRva, SEEK_SET) != 0
+ || bfd_bread (&arch, sizeof arch, abfd) != sizeof arch
+ || (arch != 0 && arch != 9))
+ goto fail;
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386,
+ arch == 9 ? bfd_mach_x86_64 : 0);
+ }
+
+ return abfd->xvec;
+
+fail:
+ return NULL;
+}
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index 807817c94e..7c50313961 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -583,6 +583,9 @@ extern bfd_boolean bfd_coff_gc_sections
extern const char *bfd_coff_group_name
(bfd *, const asection *);
+extern const bfd_target *coff_core_file_p
+ (bfd *);
+
#define coff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index e6af9d6130..ee73e9f982 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -587,6 +587,9 @@ extern bfd_boolean bfd_coff_gc_sections
extern const char *bfd_coff_group_name
(bfd *, const asection *);
+extern const bfd_target *coff_core_file_p
+ (bfd *);
+
#define coff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index d4d79682dd..6e1774a617 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -33,6 +33,76 @@
#include "value.h"
#include <algorithm>
+#define AMD64_WINDOWS_SIZEOF_GREGSET 1232
+
+static int amd64_windows_gregset_reg_offset[] =
+{
+ 120, /* rax */
+ 144, /* rbx */
+ 128, /* rcx */
+ 136, /* rdx */
+
+ 168, /* rsi */
+ 176, /* rdi */
+ 160, /* rbp */
+ 152, /* rsp */
+
+ 184, /* r8 */
+ 192, /* r9 */
+ 200, /* r10 */
+ 208, /* r11 */
+ 216, /* r12 */
+ 224, /* r13 */
+ 232, /* r14 */
+ 240, /* r15 */
+
+ 248, /* rip */
+ 68, /* eflags */
+ 56, /* cs */
+ 66, /* ss */
+
+ 58, /* ds */
+ 60, /* es */
+ 62, /* fs */
+ 64, /* gs */
+
+ 288, /* st0 */
+ 304, /* st1 */
+ 320, /* st2 */
+ 336, /* st3 */
+ 352, /* st4 */
+ 368, /* st5 */
+ 384, /* st6 */
+ 400, /* st7 */
+
+ 256, /* fctrl */
+ 258, /* fstat */
+ 260, /* ftag */
+ 268, /* fiseg */
+ 264, /* fioff */
+ 276, /* foseg */
+ 272, /* fooff */
+ 262, /* fop */
+
+ 416, /* xmm0 */
+ 432, /* xmm1 */
+ 448, /* xmm2 */
+ 464, /* xmm3 */
+ 480, /* xmm4 */
+ 496, /* xmm5 */
+ 512, /* xmm6 */
+ 528, /* xmm7 */
+ 544, /* xmm8 */
+ 560, /* xmm9 */
+ 576, /* xmm10 */
+ 592, /* xmm11 */
+ 608, /* xmm12 */
+ 624, /* xmm13 */
+ 640, /* xmm14 */
+ 656, /* xmm15 */
+ 280, /* mxcsr */
+};
+
/* The registers used to pass integer arguments during a function call. */
static int amd64_windows_dummy_call_integer_regs[] =
{
@@ -1211,6 +1281,8 @@ amd64_windows_auto_wide_charset (void)
static void
amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
/* The dwarf2 unwinder (appended very early by i386_gdbarch_init) is
preferred over the SEH one. The reasons are:
- binaries without SEH but with dwarf2 debug info are correctly handled
@@ -1241,6 +1313,10 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_prologue (gdbarch, amd64_windows_skip_prologue);
+ tdep->gregset_reg_offset = amd64_windows_gregset_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (amd64_windows_gregset_reg_offset);
+ tdep->sizeof_gregset = AMD64_WINDOWS_SIZEOF_GREGSET;
+
set_gdbarch_auto_wide_charset (gdbarch, amd64_windows_auto_wide_charset);
}
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 91a778cd81..6bbee97910 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -34,6 +34,9 @@
#include "solib.h"
#include "solib-target.h"
#include "gdbcore.h"
+#include "charset.h"
+#include "coff/internal.h"
+#include "libcoff.h"
/* Windows signal numbers differ between MinGW flavors and between
those and Cygwin. The below enumeration was gleaned from the
@@ -828,10 +831,13 @@ core_process_module_section (bfd *abfd, asection *sect, void *obj)
char *module_name;
size_t module_name_size;
CORE_ADDR base_addr;
+ int is_module, is_coremodule;
gdb_byte *buf = NULL;
- if (!startswith (sect->name, ".module"))
+ is_module = startswith (sect->name, ".module");
+ is_coremodule = startswith (sect->name, ".coremodule/");
+ if (!is_module && !is_coremodule)
return;
buf = (gdb_byte *) xmalloc (bfd_section_size (sect) + 1);
@@ -845,6 +851,27 @@ core_process_module_section (bfd *abfd, asection *sect, void *obj)
goto out;
+ if (is_coremodule)
+ {
+ auto_obstack host_name;
+ convert_between_encodings (target_wide_charset (data->gdbarch),
+ host_charset (),
+ buf, bfd_section_size (sect), 2,
+ &host_name, translit_char);
+ obstack_grow_str0 (&host_name, "");
+ module_name = (char *) obstack_base (&host_name);
+
+ sscanf (sect->name + 12, "%llx", &base_addr);
+
+ if (data->module_count != 0)
+ windows_xfer_shared_library (module_name, base_addr,
+ NULL, data->gdbarch, data->obstack);
+ data->module_count++;
+
+ xfree (buf);
+ return;
+ }
+
/* A DWORD (data_type) followed by struct windows_core_module_info. */
--
2.15.1.windows.2
[-- Attachment #4: 0003-Additional-core-file-functions-for-minidump.patch --]
[-- Type: application/octet-stream, Size: 8823 bytes --]
From f2b90e9a972c1f997c91d49e0f92b8f654564aef Mon Sep 17 00:00:00 2001
From: Hannes Domani <ssbssa@yahoo.de>
Date: Thu, 31 Jan 2019 01:31:05 +0100
Subject: [PATCH 3/6] Additional core file functions for minidump.
---
bfd/coff-i386.c | 2 +-
bfd/coff-x86_64.c | 2 +-
bfd/coffgen.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++
bfd/libcoff-in.h | 8 ++++
bfd/libcoff.h | 8 ++++
gdb/windows-tdep.c | 47 +++++++++++++++++++++++
6 files changed, 172 insertions(+), 2 deletions(-)
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index 705df2eb75..4bcfcb668c 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -695,7 +695,7 @@ const bfd_target
BFD_JUMP_TABLE_GENERIC (coff),
BFD_JUMP_TABLE_COPY (coff),
- BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_CORE (coff),
BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
BFD_JUMP_TABLE_SYMBOLS (coff),
BFD_JUMP_TABLE_RELOCS (coff),
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 0dc0136cd5..854434886f 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -812,7 +812,7 @@ const bfd_target
BFD_JUMP_TABLE_GENERIC (coff),
BFD_JUMP_TABLE_COPY (coff),
- BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_CORE (coff),
BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
BFD_JUMP_TABLE_SYMBOLS (coff),
BFD_JUMP_TABLE_RELOCS (coff),
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index f9f2530952..2e1e03332a 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -42,6 +42,7 @@
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
+#include "libiberty.h"
/* Take a section header read from a coff file (in HOST byte order),
and make a BFD "section" out of it. This is used by ECOFF. */
@@ -3186,6 +3187,14 @@ _bfd_coff_close_and_cleanup (bfd *abfd)
/* Read minidump file. */
+typedef struct
+{
+ int pid;
+ int signal;
+ char *exe_name;
+}
+pe_core_data;
+
#pragma pack(push,4)
typedef struct
@@ -3345,6 +3354,14 @@ typedef struct
}
dump_module;
+typedef struct
+{
+ uint32_t infoSize;
+ uint32_t flags;
+ uint32_t processId;
+}
+dump_misc;
+
#pragma pack(pop)
@@ -3384,6 +3401,7 @@ coff_core_file_p (bfd *abfd)
uint32_t exceptionRva = 0;
uint32_t threadListRva = 0;
uint32_t systemInfoRva = 0;
+ uint32_t miscInfoRva = 0;
if (bfd_bread (&header, sizeof header, abfd) != sizeof header)
goto fail;
@@ -3392,6 +3410,12 @@ coff_core_file_p (bfd *abfd)
header.sig[2] != 'M' || header.sig[3] != 'P')
goto fail;
+ pe_core_data *pcd = bfd_zalloc (abfd, sizeof (pe_core_data));
+ if (!pcd)
+ goto fail;
+
+ abfd->tdata.any = pcd;
+
for (s = 0; s < header.streamCount; s++)
{
dump_directory dir;
@@ -3418,6 +3442,9 @@ coff_core_file_p (bfd *abfd)
case SystemInfoStream:
systemInfoRva = dir.loc.rva;
break;
+ case MiscInfoStream:
+ miscInfoRva = dir.loc.rva;
+ break;
}
}
@@ -3443,6 +3470,33 @@ coff_core_file_p (bfd *abfd)
|| bfd_bread (&size, sizeof size, abfd) != sizeof size)
goto fail;
+ if (!m && size > 1)
+ {
+ uint16_t *wide_name = bfd_malloc (size + 2);
+ if (wide_name == NULL)
+ goto fail;
+
+ if (bfd_bread (wide_name, size, abfd) == size)
+ {
+ uint32_t len = size / 2;
+ wide_name[len] = 0;
+ pcd->exe_name = bfd_zalloc (abfd, len + 1);
+ if (pcd->exe_name)
+ {
+#ifdef __MINGW32__
+ wcstombs (pcd->exe_name, wide_name, len);
+#else
+ uint32_t n;
+ for (n = 0; n < size; n++)
+ pcd->exe_name[n] =
+ wide_name[n] < 0x80 ? wide_name[n] : '?';
+#endif
+ }
+ }
+
+ free (wide_name);
+ }
+
sprintf (secname, ".coremodule/%llx", module.base);
sec = make_bfd_asection (abfd, secname,
@@ -3540,6 +3594,13 @@ coff_core_file_p (bfd *abfd)
goto fail;
exceptionThreadId = exception.threadId;
+
+ /* some exception codes are bigger than INT_MAX, so this makes sure
+ bits 24 - 27 are 0, and move the highest 4 bits down.
+ windows_gdb_signal_from_target() uses these changed values. */
+ if (!(exception.record.code & 0x0F000000))
+ pcd->signal = ((exception.record.code & 0xF0000000) >> 4)
+ | (exception.record.code & 0x00FFFFFF);
}
if (threadListRva)
@@ -3593,8 +3654,54 @@ coff_core_file_p (bfd *abfd)
arch == 9 ? bfd_mach_x86_64 : 0);
}
+ if (miscInfoRva)
+ {
+ dump_misc misc;
+ if (bfd_seek (abfd, miscInfoRva, SEEK_SET) != 0
+ || bfd_bread (&misc, sizeof misc, abfd) != sizeof misc
+ || misc.infoSize < sizeof misc
+ || !(misc.flags & 1))
+ goto fail;
+
+ pcd->pid = misc.processId;
+ }
+
return abfd->xvec;
fail:
return NULL;
}
+
+
+char *
+coff_core_file_failing_command (bfd *abfd)
+{
+ return ((pe_core_data *) abfd->tdata.any)->exe_name;
+}
+
+int
+coff_core_file_failing_signal (bfd *abfd)
+{
+ return ((pe_core_data *) abfd->tdata.any)->signal;
+}
+
+int
+coff_core_file_pid (bfd *abfd)
+{
+ return ((pe_core_data *) abfd->tdata.any)->pid;
+}
+
+bfd_boolean
+coff_core_file_matches_executable_p (bfd *core_bfd,
+ bfd *exec_bfd)
+{
+ const char *core_exe = ((pe_core_data *) core_bfd->tdata.any)->exe_name;
+ const char *exec_exe = bfd_get_filename (exec_bfd);
+ if (!core_exe)
+ return TRUE;
+
+ core_exe = dos_lbasename (core_exe);
+ exec_exe = lbasename (exec_exe);
+
+ return strcasecmp (core_exe, exec_exe) == 0;
+}
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index 7c50313961..6a86f17f4c 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -585,6 +585,14 @@ extern const char *bfd_coff_group_name
extern const bfd_target *coff_core_file_p
(bfd *);
+extern char *coff_core_file_failing_command
+ (bfd *);
+extern int coff_core_file_failing_signal
+ (bfd *);
+extern int coff_core_file_pid
+ (bfd *);
+extern bfd_boolean coff_core_file_matches_executable_p
+ (bfd *, bfd *);
#define coff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index ee73e9f982..1e8fd29c41 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -589,6 +589,14 @@ extern const char *bfd_coff_group_name
extern const bfd_target *coff_core_file_p
(bfd *);
+extern char *coff_core_file_failing_command
+ (bfd *);
+extern int coff_core_file_failing_signal
+ (bfd *);
+extern int coff_core_file_pid
+ (bfd *);
+extern bfd_boolean coff_core_file_matches_executable_p
+ (bfd *, bfd *);
#define coff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 6bbee97910..03755a1244 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -938,6 +938,51 @@ i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
return normal_pid_to_str (ptid);
}
+static enum gdb_signal
+windows_gdb_signal_from_target (struct gdbarch *gdbarch,
+ int signal)
+{
+ unsigned int usignal = signal;
+ switch (usignal)
+ {
+ case 0:
+ return GDB_SIGNAL_0;
+
+ case 0xC000005: /* EXCEPTION_ACCESS_VIOLATION */
+ case 0xC0000FD: /* STATUS_STACK_OVERFLOW */
+ return GDB_SIGNAL_SEGV;
+
+ case 0xC00008C: /* EXCEPTION_ARRAY_BOUNDS_EXCEEDED */
+ case 0xC00008D: /* STATUS_FLOAT_DENORMAL_OPERAND */
+ case 0xC00008E: /* STATUS_FLOAT_DIVIDE_BY_ZERO */
+ case 0xC00008F: /* STATUS_FLOAT_INEXACT_RESULT */
+ case 0xC000090: /* STATUS_FLOAT_INVALID_OPERATION */
+ case 0xC000091: /* STATUS_FLOAT_OVERFLOW */
+ case 0xC000092: /* STATUS_FLOAT_STACK_CHECK */
+ case 0xC000093: /* STATUS_FLOAT_UNDERFLOW */
+ case 0xC000094: /* STATUS_INTEGER_DIVIDE_BY_ZERO */
+ case 0xC000095: /* STATUS_INTEGER_OVERFLOW */
+ return GDB_SIGNAL_FPE;
+
+ case 0x8000003: /* EXCEPTION_BREAKPOINT */
+ case 0x8000004: /* EXCEPTION_SINGLE_STEP */
+ return GDB_SIGNAL_TRAP;
+
+ case 0x4010005: /* DBG_CONTROL_C */
+ case 0x4010008: /* DBG_CONTROL_BREAK */
+ return GDB_SIGNAL_INT;
+
+ case 0xC00001D: /* EXCEPTION_ILLEGAL_INSTRUCTION */
+ case 0xC000096: /* EXCEPTION_PRIV_INSTRUCTION */
+ case 0xC000025: /* EXCEPTION_NONCONTINUABLE_EXCEPTION */
+ return GDB_SIGNAL_ILL;
+
+ case 0x4000015: /* FATAL_APP_EXIT */
+ return GDB_SIGNAL_ABRT;
+ }
+ return GDB_SIGNAL_UNKNOWN;
+}
+
/* To be called from the various GDB_OSABI_CYGWIN handlers for the
various Windows architectures and machine types. */
@@ -964,6 +1009,8 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_core_xfer_shared_libraries
(gdbarch, windows_core_xfer_shared_libraries);
set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
+ set_gdbarch_gdb_signal_from_target (gdbarch,
+ windows_gdb_signal_from_target);
}
/* Implementation of `tlb' variable. */
--
2.15.1.windows.2
[-- Attachment #5: 0004-Use-TEB-pointer-of-minidump-file-for-_tlb.patch --]
[-- Type: application/octet-stream, Size: 1726 bytes --]
From 0297ac538b96fe164deafe85f889a08e731f2d8b Mon Sep 17 00:00:00 2001
From: Hannes Domani <ssbssa@yahoo.de>
Date: Thu, 31 Jan 2019 17:13:12 +0100
Subject: [PATCH 4/6] Use TEB pointer of minidump file for $_tlb.
---
bfd/coffgen.c | 9 +++++++++
gdb/corelow.c | 20 ++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 2e1e03332a..5b5c53c7ba 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -3639,6 +3639,15 @@ coff_core_file_p (bfd *abfd)
if (!sec)
goto fail;
}
+
+ sprintf (secname, ".coretlb/%u", thread.threadId);
+ sec = make_bfd_asection (abfd, secname,
+ SEC_HAS_CONTENTS,
+ threadListRva + 4 + t * sizeof thread + 16,
+ 8,
+ 0);
+ if (!sec)
+ goto fail;
}
}
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 5cd058d599..3da34abd5e 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -98,6 +98,8 @@ public:
bool info_proc (const char *, enum info_proc_what) override;
+ bool get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
+
/* A few helpers. */
/* Getter, see variable definition. */
@@ -978,6 +980,24 @@ core_target::has_registers ()
return (core_bfd != NULL);
}
+bool
+core_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
+{
+ char secname[32];
+ struct bfd_section *section;
+
+ sprintf (secname, ".coretlb/%ld", ptid.lwp ());
+
+ section = bfd_get_section_by_name (core_bfd, secname);
+ if (section == NULL)
+ return false;
+
+ if (bfd_section_size (section) < sizeof *addr)
+ return false;
+
+ return bfd_get_section_contents (core_bfd, section, addr, 0, sizeof *addr);
+}
+
/* Implement the to_info_proc method. */
bool
--
2.15.1.windows.2
[-- Attachment #6: 0005-Add-_siginfo-for-minidump.patch --]
[-- Type: application/octet-stream, Size: 2645 bytes --]
From 8c7f7542ea10f9d113176b4ea87913795c2433c6 Mon Sep 17 00:00:00 2001
From: Hannes Domani <ssbssa@yahoo.de>
Date: Thu, 31 Jan 2019 01:48:57 +0100
Subject: [PATCH 5/6] Add $_siginfo for minidump.
---
bfd/coffgen.c | 8 ++++++++
gdb/windows-tdep.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 5b5c53c7ba..856bcf5544 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -3593,6 +3593,14 @@ coff_core_file_p (bfd *abfd)
if (!sec)
goto fail;
+ sec = make_bfd_asection (abfd, ".coreexception",
+ SEC_HAS_CONTENTS,
+ exceptionRva + 8,
+ sizeof exception.record,
+ 0);
+ if (!sec)
+ goto fail;
+
exceptionThreadId = exception.threadId;
/* some exception codes are bigger than INT_MAX, so this makes sure
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 03755a1244..dc583cb2c0 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -983,6 +983,49 @@ windows_gdb_signal_from_target (struct gdbarch *gdbarch,
return GDB_SIGNAL_UNKNOWN;
}
+static LONGEST
+windows_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
+ ULONGEST offset, ULONGEST len)
+{
+ asection *section = bfd_get_section_by_name (core_bfd, ".coreexception");
+ if (section == NULL)
+ return -1;
+
+ /* The exception record of the minidump file is always in 64bit format. */
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ {
+ uint32_t rec[38];
+ int r;
+
+#define EXC_SIZE_32 80
+#define EXC_SIZE_64 152
+
+ if (offset > EXC_SIZE_32)
+ return -1;
+
+ if (bfd_section_size (section) != EXC_SIZE_64)
+ return -1;
+
+ if (!bfd_get_section_contents (core_bfd, section, rec, 0, EXC_SIZE_64))
+ return -1;
+
+ for (r = 2; r < 19; r++)
+ rec[r + 1] = rec[r * 2];
+
+ if (len > EXC_SIZE_32 - offset)
+ len = EXC_SIZE_32 - offset;
+
+ memcpy (readbuf, (char *) rec + offset, len);
+
+ return len;
+ }
+
+ if (!bfd_get_section_contents (core_bfd, section, readbuf, offset, len))
+ return -1;
+
+ return len;
+}
+
/* To be called from the various GDB_OSABI_CYGWIN handlers for the
various Windows architectures and machine types. */
@@ -1011,6 +1054,7 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
set_gdbarch_gdb_signal_from_target (gdbarch,
windows_gdb_signal_from_target);
+ set_gdbarch_core_xfer_siginfo (gdbarch, windows_core_xfer_siginfo);
}
/* Implementation of `tlb' variable. */
--
2.15.1.windows.2
[-- Attachment #7: 0006-Add-fake-minidump-.auxv-section-for-base-relocation.patch --]
[-- Type: application/octet-stream, Size: 1989 bytes --]
From d0a0f5a3fddc76321a7d6dfbeb1453c655fdaafa Mon Sep 17 00:00:00 2001
From: Hannes Domani <ssbssa@yahoo.de>
Date: Wed, 6 Feb 2019 19:20:50 +0100
Subject: [PATCH 6/6] Add fake minidump .auxv section for base relocation
---
bfd/coffgen.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 856bcf5544..fcdae78fb4 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -3402,6 +3402,7 @@ coff_core_file_p (bfd *abfd)
uint32_t threadListRva = 0;
uint32_t systemInfoRva = 0;
uint32_t miscInfoRva = 0;
+ uint64_t exec_base = 0;
if (bfd_bread (&header, sizeof header, abfd) != sizeof header)
goto fail;
@@ -3466,6 +3467,9 @@ coff_core_file_p (bfd *abfd)
if (bfd_bread (&module, sizeof module, abfd) != sizeof module)
goto fail;
+ if (!m)
+ exec_base = module.base;
+
if (bfd_seek (abfd, module.nameRva, SEEK_SET) != 0
|| bfd_bread (&size, sizeof size, abfd) != sizeof size)
goto fail;
@@ -3669,6 +3673,42 @@ coff_core_file_p (bfd *abfd)
bfd_default_set_arch_mach (abfd, bfd_arch_i386,
arch == 9 ? bfd_mach_x86_64 : 0);
+
+ if (exec_base)
+ {
+ bfd_size_type auxv_size = 0;
+ void *auxv = NULL;
+ if (arch == 9)
+ {
+ auxv_size = sizeof (uint64_t) * 4;
+ uint64_t *auxv64 = bfd_zalloc (abfd, auxv_size);
+ if (!auxv64)
+ goto fail;
+
+ auxv64[0] = 9; /* AT_ENTRY */
+ auxv64[1] = exec_base;
+ auxv = auxv64;
+ }
+ else
+ {
+ auxv_size = sizeof (uint32_t) * 4;
+ uint32_t *auxv32 = bfd_zalloc (abfd, auxv_size);
+ if (!auxv32)
+ goto fail;
+
+ auxv32[0] = 9; /* AT_ENTRY */
+ auxv32[1] = exec_base;
+ auxv = auxv32;
+ }
+
+ sec = make_bfd_asection (abfd, ".auxv",
+ SEC_HAS_CONTENTS | SEC_IN_MEMORY,
+ 0, auxv_size, 0);
+ if (!sec)
+ goto fail;
+
+ sec->contents = auxv;
+ }
}
if (miscInfoRva)
--
2.15.1.windows.2
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-02-12 18:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <691075103.286431.1581179823782.ref@mail.yahoo.com>
2020-02-08 16:37 ` [PING] [PATCH] Rebase executable to match relocated base address Hannes Domani via gdb-patches
2020-02-11 0:29 ` Luis Machado
2020-02-11 11:34 ` Hannes Domani via gdb-patches
2020-02-12 4:49 ` Simon Marchi
2020-02-12 18:05 ` Hannes Domani via gdb-patches
2020-02-12 18:19 ` Christian Biesinger via gdb-patches
2020-02-12 18:38 ` Hannes Domani via gdb-patches
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox