diff options
Diffstat (limited to 'gdb/windows-nat.c')
-rw-r--r-- | gdb/windows-nat.c | 151 |
1 files changed, 66 insertions, 85 deletions
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 5578ae2..0102511 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -97,8 +97,6 @@ struct windows_per_inferior : public windows_process_info void handle_unload_dll () override; bool handle_access_violation (const EXCEPTION_RECORD *rec) override; - uintptr_t dr[8] {}; - int windows_initialization_done = 0; std::vector<std::unique_ptr<windows_thread_info>> thread_list; @@ -730,36 +728,12 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r) { th->wow64_context.ContextFlags = CONTEXT_DEBUGGER_DR; CHECK (Wow64GetThreadContext (th->h, &th->wow64_context)); - /* Copy dr values from that thread. - But only if there were not modified since last stop. - PR gdb/2388 */ - if (!th->debug_registers_changed) - { - windows_process.dr[0] = th->wow64_context.Dr0; - windows_process.dr[1] = th->wow64_context.Dr1; - windows_process.dr[2] = th->wow64_context.Dr2; - windows_process.dr[3] = th->wow64_context.Dr3; - windows_process.dr[6] = th->wow64_context.Dr6; - windows_process.dr[7] = th->wow64_context.Dr7; - } } else #endif { th->context.ContextFlags = CONTEXT_DEBUGGER_DR; CHECK (GetThreadContext (th->h, &th->context)); - /* Copy dr values from that thread. - But only if there were not modified since last stop. - PR gdb/2388 */ - if (!th->debug_registers_changed) - { - windows_process.dr[0] = th->context.Dr0; - windows_process.dr[1] = th->context.Dr1; - windows_process.dr[2] = th->context.Dr2; - windows_process.dr[3] = th->context.Dr3; - windows_process.dr[6] = th->context.Dr6; - windows_process.dr[7] = th->context.Dr7; - } } th->reload_context = false; } @@ -1283,18 +1257,21 @@ windows_nat_target::windows_continue (DWORD continue_status, int id, for (auto &th : windows_process.thread_list) if (id == -1 || id == (int) th->tid) { + struct x86_debug_reg_state *state + = x86_debug_reg_state (windows_process.process_id); + #ifdef __x86_64__ if (windows_process.wow64_process) { if (th->debug_registers_changed) { th->wow64_context.ContextFlags |= CONTEXT_DEBUG_REGISTERS; - th->wow64_context.Dr0 = windows_process.dr[0]; - th->wow64_context.Dr1 = windows_process.dr[1]; - th->wow64_context.Dr2 = windows_process.dr[2]; - th->wow64_context.Dr3 = windows_process.dr[3]; + th->wow64_context.Dr0 = state->dr_mirror[0]; + th->wow64_context.Dr1 = state->dr_mirror[1]; + th->wow64_context.Dr2 = state->dr_mirror[2]; + th->wow64_context.Dr3 = state->dr_mirror[3]; th->wow64_context.Dr6 = DR6_CLEAR_VALUE; - th->wow64_context.Dr7 = windows_process.dr[7]; + th->wow64_context.Dr7 = state->dr_control_mirror; th->debug_registers_changed = false; } if (th->wow64_context.ContextFlags) @@ -1319,12 +1296,12 @@ windows_nat_target::windows_continue (DWORD continue_status, int id, if (th->debug_registers_changed) { th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS; - th->context.Dr0 = windows_process.dr[0]; - th->context.Dr1 = windows_process.dr[1]; - th->context.Dr2 = windows_process.dr[2]; - th->context.Dr3 = windows_process.dr[3]; + th->context.Dr0 = state->dr_mirror[0]; + th->context.Dr1 = state->dr_mirror[1]; + th->context.Dr2 = state->dr_mirror[2]; + th->context.Dr3 = state->dr_mirror[3]; th->context.Dr6 = DR6_CLEAR_VALUE; - th->context.Dr7 = windows_process.dr[7]; + th->context.Dr7 = state->dr_control_mirror; th->debug_registers_changed = false; } if (th->context.ContextFlags) @@ -1463,22 +1440,6 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) fetch_registers (regcache, gdbarch_ps_regnum (gdbarch)); th->wow64_context.EFlags |= FLAG_TRACE_BIT; } - - if (th->wow64_context.ContextFlags) - { - if (th->debug_registers_changed) - { - th->wow64_context.Dr0 = windows_process.dr[0]; - th->wow64_context.Dr1 = windows_process.dr[1]; - th->wow64_context.Dr2 = windows_process.dr[2]; - th->wow64_context.Dr3 = windows_process.dr[3]; - th->wow64_context.Dr6 = DR6_CLEAR_VALUE; - th->wow64_context.Dr7 = windows_process.dr[7]; - th->debug_registers_changed = false; - } - CHECK (Wow64SetThreadContext (th->h, &th->wow64_context)); - th->wow64_context.ContextFlags = 0; - } } else #endif @@ -1491,22 +1452,6 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) fetch_registers (regcache, gdbarch_ps_regnum (gdbarch)); th->context.EFlags |= FLAG_TRACE_BIT; } - - if (th->context.ContextFlags) - { - if (th->debug_registers_changed) - { - th->context.Dr0 = windows_process.dr[0]; - th->context.Dr1 = windows_process.dr[1]; - th->context.Dr2 = windows_process.dr[2]; - th->context.Dr3 = windows_process.dr[3]; - th->context.Dr6 = DR6_CLEAR_VALUE; - th->context.Dr7 = windows_process.dr[7]; - th->debug_registers_changed = false; - } - CHECK (SetThreadContext (th->h, &th->context)); - th->context.ContextFlags = 0; - } } } @@ -1887,19 +1832,15 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, void windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching) { - int i; struct inferior *inf; windows_process.last_sig = GDB_SIGNAL_0; windows_process.open_process_used = 0; - for (i = 0; - i < sizeof (windows_process.dr) / sizeof (windows_process.dr[0]); - i++) - windows_process.dr[i] = 0; #ifdef __CYGWIN__ windows_process.cygwin_load_start = 0; windows_process.cygwin_load_end = 0; #endif + windows_process.process_id = pid; memset (&windows_process.current_event, 0, sizeof (windows_process.current_event)); inf = current_inferior (); @@ -3321,7 +3262,6 @@ cygwin_set_dr (int i, CORE_ADDR addr) { if (i < 0 || i > 3) internal_error (_("Invalid register %d in cygwin_set_dr.\n"), i); - windows_process.dr[i] = addr; for (auto &th : windows_process.thread_list) th->debug_registers_changed = true; @@ -3333,8 +3273,6 @@ cygwin_set_dr (int i, CORE_ADDR addr) static void cygwin_set_dr7 (unsigned long val) { - windows_process.dr[7] = (CORE_ADDR) val; - for (auto &th : windows_process.thread_list) th->debug_registers_changed = true; } @@ -3344,26 +3282,69 @@ cygwin_set_dr7 (unsigned long val) static CORE_ADDR cygwin_get_dr (int i) { - return windows_process.dr[i]; + windows_thread_info *th + = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT); + +#ifdef __x86_64__ + if (windows_process.wow64_process) + { + gdb_assert (th->wow64_context.ContextFlags != 0); + switch (i) + { + case 0: + return th->wow64_context.Dr0; + case 1: + return th->wow64_context.Dr1; + case 2: + return th->wow64_context.Dr2; + case 3: + return th->wow64_context.Dr3; + case 6: + return th->wow64_context.Dr6; + case 7: + return th->wow64_context.Dr7; + }; + } + else +#endif + { + gdb_assert (th->context.ContextFlags != 0); + switch (i) + { + case 0: + return th->context.Dr0; + case 1: + return th->context.Dr1; + case 2: + return th->context.Dr2; + case 3: + return th->context.Dr3; + case 6: + return th->context.Dr6; + case 7: + return th->context.Dr7; + }; + } + + gdb_assert_not_reached ("invalid x86 dr register number: %d", i); } -/* Get the value of the DR6 debug status register from the inferior. - Here we just return the value stored in dr[6] - by the last call to thread_rec for current_event.dwThreadId id. */ +/* Get the value of the DR6 debug status register from the + inferior. */ + static unsigned long cygwin_get_dr6 (void) { - return (unsigned long) windows_process.dr[6]; + return cygwin_get_dr (6); } -/* Get the value of the DR7 debug status register from the inferior. - Here we just return the value stored in dr[7] by the last call to - thread_rec for current_event.dwThreadId id. */ +/* Get the value of the DR7 debug status register from the + inferior. */ static unsigned long cygwin_get_dr7 (void) { - return (unsigned long) windows_process.dr[7]; + return cygwin_get_dr (7); } /* Determine if the thread referenced by "ptid" is alive |