aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/windows-nat.c31
-rw-r--r--gdb/windows-tdep.c72
-rw-r--r--gdbserver/ChangeLog6
-rw-r--r--gdbserver/win32-low.c30
6 files changed, 155 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3aecd12..6de07a9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2020-02-09 Hannes Domani <ssbssa@yahoo.de>
+
+ * NEWS: Mention $_siginfo support for Windows.
+ * windows-nat.c (handle_exception): Set siginfo_er.
+ (windows_nat_target::mourn_inferior): Reset siginfo_er.
+ (windows_xfer_siginfo): New function.
+ (windows_nat_target::xfer_partial): Call windows_xfer_siginfo.
+ * windows-tdep.c (struct windows_gdbarch_data): New struct.
+ (init_windows_gdbarch_data): New function.
+ (get_windows_gdbarch_data): New function.
+ (windows_get_siginfo_type): New function.
+ (windows_init_abi): Register windows_get_siginfo_type.
+ (_initialize_windows_tdep): Register init_windows_gdbarch_data.
+
2020-02-08 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (class cutu_reader) <cutu_reader,
diff --git a/gdb/NEWS b/gdb/NEWS
index d4e2e70..c202fe0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -10,6 +10,9 @@
that support it (see entry for GDB 9, below), providing faster
performance for programs with many symbols.
+* The $_siginfo convenience variable now also works on Windows targets,
+ and will display the EXCEPTION_RECORD of the last handled exception.
+
* New commands
set exec-file-mismatch -- Set exec-file-mismatch handling (ask|warn|off).
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 366c98f..76fcdd6 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 EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
/* Counts of things. */
static int exception_count = 0;
@@ -1167,6 +1168,8 @@ handle_exception (struct target_waitstatus *ourstatus)
DWORD code = rec->ExceptionCode;
handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
+ memcpy (&siginfo_er, rec, sizeof siginfo_er);
+
ourstatus->kind = TARGET_WAITKIND_STOPPED;
/* Record the context of the current thread. */
@@ -2863,6 +2866,7 @@ windows_nat_target::mourn_inferior ()
CHECK (CloseHandle (current_process_handle));
open_process_used = 0;
}
+ siginfo_er.ExceptionCode = 0;
inf_child_target::mourn_inferior ();
}
@@ -2996,6 +3000,30 @@ windows_xfer_shared_libraries (struct target_ops *ops,
return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
}
+/* Helper for windows_nat_target::xfer_partial that handles signal info. */
+
+static enum target_xfer_status
+windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
+{
+ if (siginfo_er.ExceptionCode == 0)
+ return TARGET_XFER_E_IO;
+
+ if (readbuf == nullptr)
+ return TARGET_XFER_E_IO;
+
+ if (offset > sizeof (siginfo_er))
+ return TARGET_XFER_E_IO;
+
+ if (offset + len > sizeof (siginfo_er))
+ len = sizeof (siginfo_er) - offset;
+
+ memcpy (readbuf, (char *) &siginfo_er + 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 +3039,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_SIGNAL_INFO:
+ return windows_xfer_siginfo (readbuf, offset, len, xfered_len);
+
default:
if (beneath () == NULL)
{
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 6c9632d..ad65b1b 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -153,6 +153,30 @@ static const int FULL_TIB_SIZE = 0x1000;
static bool maint_display_all_tib = false;
+static struct gdbarch_data *windows_gdbarch_data_handle;
+
+struct windows_gdbarch_data
+{
+ struct type *siginfo_type;
+};
+
+/* Allocate windows_gdbarch_data for an arch. */
+
+static void *
+init_windows_gdbarch_data (struct gdbarch *gdbarch)
+{
+ return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct windows_gdbarch_data);
+}
+
+/* Get windows_gdbarch_data of an arch. */
+
+static struct windows_gdbarch_data *
+get_windows_gdbarch_data (struct gdbarch *gdbarch)
+{
+ return ((struct windows_gdbarch_data *)
+ gdbarch_data (gdbarch, windows_gdbarch_data_handle));
+}
+
/* Define Thread Local Base pointer type. */
static struct type *
@@ -656,6 +680,49 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal)
return -1;
}
+/* Implement the "get_siginfo_type" gdbarch method. */
+
+static struct type *
+windows_get_siginfo_type (struct gdbarch *gdbarch)
+{
+ struct windows_gdbarch_data *windows_gdbarch_data;
+ struct type *dword_type, *pvoid_type, *ulongptr_type;
+ struct type *siginfo_ptr_type, *siginfo_type;
+
+ windows_gdbarch_data = get_windows_gdbarch_data (gdbarch);
+ if (windows_gdbarch_data->siginfo_type != NULL)
+ return windows_gdbarch_data->siginfo_type;
+
+ dword_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
+ 1, "DWORD");
+ pvoid_type = arch_pointer_type (gdbarch, gdbarch_ptr_bit (gdbarch), "PVOID",
+ builtin_type (gdbarch)->builtin_void);
+ ulongptr_type = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch),
+ 1, "ULONG_PTR");
+
+ siginfo_type = arch_composite_type (gdbarch, "EXCEPTION_RECORD",
+ TYPE_CODE_STRUCT);
+ siginfo_ptr_type = arch_pointer_type (gdbarch, gdbarch_ptr_bit (gdbarch),
+ NULL, siginfo_type);
+
+ append_composite_type_field (siginfo_type, "ExceptionCode", dword_type);
+ append_composite_type_field (siginfo_type, "ExceptionFlags", dword_type);
+ append_composite_type_field (siginfo_type, "ExceptionRecord",
+ siginfo_ptr_type);
+ append_composite_type_field (siginfo_type, "ExceptionAddress",
+ pvoid_type);
+ append_composite_type_field (siginfo_type, "NumberParameters", dword_type);
+ /* The 64-bit variant needs some padding. */
+ append_composite_type_field_aligned (siginfo_type, "ExceptionInformation",
+ lookup_array_range_type (ulongptr_type,
+ 0, 14),
+ TYPE_LENGTH (ulongptr_type));
+
+ windows_gdbarch_data->siginfo_type = siginfo_type;
+
+ return siginfo_type;
+}
+
/* To be called from the various GDB_OSABI_CYGWIN handlers for the
various Windows architectures and machine types. */
@@ -675,6 +742,8 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_gdb_signal_to_target (gdbarch, windows_gdb_signal_to_target);
set_solib_ops (gdbarch, &solib_target_so_ops);
+
+ set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
}
/* Implementation of `tlb' variable. */
@@ -690,6 +759,9 @@ void _initialize_windows_tdep ();
void
_initialize_windows_tdep ()
{
+ windows_gdbarch_data_handle
+ = gdbarch_data_register_post_init (init_windows_gdbarch_data);
+
init_w32_command_list ();
add_cmd ("thread-information-block", class_info, display_tib,
_("Display thread information block."),
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
index a1d6e2a..4f3e8cb 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-09 Hannes Domani <ssbssa@yahoo.de>
+
+ * win32-low.c (win32_clear_inferiors): Reset siginfo_er.
+ (handle_exception): Set siginfo_er.
+ (win32_xfer_siginfo): New function.
+
2020-02-07 Tom Tromey <tom@tromey.com>
Pedro Alves <palves@redhat.com>
diff --git a/gdbserver/win32-low.c b/gdbserver/win32-low.c
index 2c4a9b1..9d03437 100644
--- a/gdbserver/win32-low.c
+++ b/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 EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
static enum gdb_signal last_sig = GDB_SIGNAL_0;
/* The current debug event from WaitForDebugEvent. */
@@ -801,6 +802,7 @@ win32_clear_inferiors (void)
CloseHandle (current_process_handle);
for_each_thread (delete_thread_info);
+ siginfo_er.ExceptionCode = 0;
clear_inferiors ();
}
@@ -1230,6 +1232,9 @@ handle_exception (struct target_waitstatus *ourstatus)
{
DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
+ memcpy (&siginfo_er, &current_event.u.Exception.ExceptionRecord,
+ sizeof siginfo_er);
+
ourstatus->kind = TARGET_WAITKIND_STOPPED;
switch (code)
@@ -1772,6 +1777,29 @@ wince_hostio_last_error (char *buf)
}
#endif
+/* Write Windows signal info. */
+
+static int
+win32_xfer_siginfo (const char *annex, unsigned char *readbuf,
+ unsigned const char *writebuf, CORE_ADDR offset, int len)
+{
+ if (siginfo_er.ExceptionCode == 0)
+ return -1;
+
+ if (readbuf == nullptr)
+ return -1;
+
+ if (offset > sizeof (siginfo_er))
+ return -1;
+
+ if (offset + len > sizeof (siginfo_er))
+ len = sizeof (siginfo_er) - offset;
+
+ memcpy (readbuf, (char *) &siginfo_er + offset, len);
+
+ return len;
+}
+
/* Write Windows OS Thread Information Block address. */
static int
@@ -1833,7 +1861,7 @@ static process_stratum_target win32_target_ops = {
hostio_last_error_from_errno,
#endif
NULL, /* qxfer_osdata */
- NULL, /* qxfer_siginfo */
+ win32_xfer_siginfo,
NULL, /* supports_non_stop */
NULL, /* async */
NULL, /* start_non_stop */