aboutsummaryrefslogtreecommitdiff
path: root/gdb/windows-nat.c
diff options
context:
space:
mode:
authorHannes Domani <ssbssa@yahoo.de>2024-12-06 14:04:00 +0100
committerHannes Domani <ssbssa@yahoo.de>2024-12-06 14:04:04 +0100
commitb2682eade4db993bc8231007ba94aec4e4728c61 (patch)
treefab3f6098344cbdea331fabf92734d1ed66e9445 /gdb/windows-nat.c
parenta3011beced048e66d200921b2a11c836fae31abf (diff)
downloadgdb-b2682eade4db993bc8231007ba94aec4e4728c61.zip
gdb-b2682eade4db993bc8231007ba94aec4e4728c61.tar.gz
gdb-b2682eade4db993bc8231007ba94aec4e4728c61.tar.bz2
Reduce WOW64 code duplication
Currently we have duplicate code for each place where windows_thread_info::context is touched, since for WOW64 processes it has to do the equivalent with wow64_context instead. For example this code...: #ifdef __x86_64__ if (windows_process.wow64_process) { th->wow64_context.ContextFlags = WOW64_CONTEXT_ALL; CHECK (Wow64GetThreadContext (th->h, &th->wow64_context)); ... } else #endif { th->context.ContextFlags = CONTEXT_DEBUGGER_DR; CHECK (GetThreadContext (th->h, &th->context)); ... } ...changes to look like this instead: windows_process.with_context (th, [&] (auto *context) { context->ContextFlags = WindowsContext<decltype(context)>::all; CHECK (get_thread_context (th->h, context)); ... } The actual choice if context or wow64_context are used, is handled by this new function in windows_process_info: template<typename Function> auto with_context (windows_thread_info *th, Function function) { #ifdef __x86_64__ if (wow64_process) return function (th != nullptr ? th->wow64_context : nullptr); else #endif return function (th != nullptr ? th->context : nullptr); } The other parts to make this work are the templated WindowsContext class which give the appropriate ContextFlags for both types. And there are also overloaded helper functions, like in the case of get_thread_context here, call either GetThreadContext or Wow64GetThreadContext. According git log --stat, this results in 120 lines less code. Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/windows-nat.c')
-rw-r--r--gdb/windows-nat.c232
1 files changed, 56 insertions, 176 deletions
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index abacafe..f2d0633 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -166,16 +166,6 @@ enum
};
#endif
-#ifndef CONTEXT_EXTENDED_REGISTERS
-/* This macro is only defined on ia32. It only makes sense on this target,
- so define it as zero if not already defined. */
-#define CONTEXT_EXTENDED_REGISTERS 0
-#endif
-
-#define CONTEXT_DEBUGGER_DR CONTEXT_FULL | CONTEXT_FLOATING_POINT \
- | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \
- | CONTEXT_EXTENDED_REGISTERS
-
#define DR6_CLEAR_VALUE 0xffff0ff0
/* The string sent by cygwin when it processes a signal.
@@ -657,11 +647,10 @@ windows_fetch_one_register (struct regcache *regcache,
gdb_assert (r >= 0);
gdb_assert (!th->reload_context);
- char *context_ptr = (char *) &th->context;
-#ifdef __x86_64__
- if (windows_process.wow64_process)
- context_ptr = (char *) &th->wow64_context;
-#endif
+ char *context_ptr = windows_process.with_context (th, [] (auto *context)
+ {
+ return (char *) context;
+ });
char *context_offset = context_ptr + windows_process.mappings[r];
struct gdbarch *gdbarch = regcache->arch ();
@@ -727,42 +716,24 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
if (th->reload_context)
{
-#ifdef __x86_64__
- if (windows_process.wow64_process)
+ windows_process.with_context (th, [&] (auto *context)
{
- th->wow64_context.ContextFlags = WOW64_CONTEXT_ALL;
- CHECK (Wow64GetThreadContext (th->h, &th->wow64_context));
+ context->ContextFlags = WindowsContext<decltype(context)>::all;
+ CHECK (get_thread_context (th->h, 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;
+ windows_process.dr[0] = context->Dr0;
+ windows_process.dr[1] = context->Dr1;
+ windows_process.dr[2] = context->Dr2;
+ windows_process.dr[3] = context->Dr3;
+ windows_process.dr[6] = context->Dr6;
+ windows_process.dr[7] = 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;
}
@@ -785,11 +756,10 @@ windows_store_one_register (const struct regcache *regcache,
{
gdb_assert (r >= 0);
- char *context_ptr = (char *) &th->context;
-#ifdef __x86_64__
- if (windows_process.wow64_process)
- context_ptr = (char *) &th->wow64_context;
-#endif
+ char *context_ptr = windows_process.with_context (th, [] (auto *context)
+ {
+ return (char *) context;
+ });
struct gdbarch *gdbarch = regcache->arch ();
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
@@ -1086,13 +1056,10 @@ static int
display_selector (HANDLE thread, DWORD sel)
{
LDT_ENTRY info;
- BOOL ret;
-#ifdef __x86_64__
- if (windows_process.wow64_process)
- ret = Wow64GetThreadSelectorEntry (thread, sel, &info);
- else
-#endif
- ret = GetThreadSelectorEntry (thread, sel, &info);
+ BOOL ret = windows_process.with_context (nullptr, [&] (auto *context)
+ {
+ return get_thread_selector_entry (context, thread, sel, &info);
+ });
if (ret)
{
int base, limit;
@@ -1181,50 +1148,21 @@ display_selectors (const char * args, int from_tty)
if (!args)
{
-#ifdef __x86_64__
- if (windows_process.wow64_process)
- {
- gdb_puts ("Selector $cs\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->wow64_context.SegCs);
- gdb_puts ("Selector $ds\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->wow64_context.SegDs);
- gdb_puts ("Selector $es\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->wow64_context.SegEs);
- gdb_puts ("Selector $ss\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->wow64_context.SegSs);
- gdb_puts ("Selector $fs\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->wow64_context.SegFs);
- gdb_puts ("Selector $gs\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->wow64_context.SegGs);
- }
- else
-#endif
+ windows_process.with_context (current_windows_thread, [&] (auto *context)
{
gdb_puts ("Selector $cs\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->context.SegCs);
+ display_selector (current_windows_thread->h, context->SegCs);
gdb_puts ("Selector $ds\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->context.SegDs);
+ display_selector (current_windows_thread->h, context->SegDs);
gdb_puts ("Selector $es\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->context.SegEs);
+ display_selector (current_windows_thread->h, context->SegEs);
gdb_puts ("Selector $ss\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->context.SegSs);
+ display_selector (current_windows_thread->h, context->SegSs);
gdb_puts ("Selector $fs\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->context.SegFs);
+ display_selector (current_windows_thread->h, context->SegFs);
gdb_puts ("Selector $gs\n");
- display_selector (current_windows_thread->h,
- current_windows_thread->context.SegGs);
- }
+ display_selector (current_windows_thread->h, context->SegGs);
+ });
}
else
{
@@ -1285,65 +1223,36 @@ windows_nat_target::windows_continue (DWORD continue_status, int id,
for (auto &th : windows_process.thread_list)
if (id == -1 || id == (int) th->tid)
{
-#ifdef __x86_64__
- if (windows_process.wow64_process)
+ windows_process.with_context (th.get (), [&] (auto *context)
{
if (th->debug_registers_changed)
{
- th->wow64_context.ContextFlags |= WOW64_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.Dr6 = DR6_CLEAR_VALUE;
- th->wow64_context.Dr7 = windows_process.dr[7];
+ context->ContextFlags
+ |= WindowsContext<decltype(context)>::debug;
+ context->Dr0 = windows_process.dr[0];
+ context->Dr1 = windows_process.dr[1];
+ context->Dr2 = windows_process.dr[2];
+ context->Dr3 = windows_process.dr[3];
+ context->Dr6 = DR6_CLEAR_VALUE;
+ context->Dr7 = windows_process.dr[7];
th->debug_registers_changed = false;
}
- if (th->wow64_context.ContextFlags)
+ if (context->ContextFlags)
{
DWORD ec = 0;
if (GetExitCodeThread (th->h, &ec)
&& ec == STILL_ACTIVE)
{
- BOOL status = Wow64SetThreadContext (th->h,
- &th->wow64_context);
+ BOOL status = set_thread_context (th->h, context);
if (!killed)
CHECK (status);
}
- th->wow64_context.ContextFlags = 0;
- }
- }
- else
-#endif
- {
- 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.Dr6 = DR6_CLEAR_VALUE;
- th->context.Dr7 = windows_process.dr[7];
- th->debug_registers_changed = false;
+ context->ContextFlags = 0;
}
- if (th->context.ContextFlags)
- {
- DWORD ec = 0;
-
- if (GetExitCodeThread (th->h, &ec)
- && ec == STILL_ACTIVE)
- {
- BOOL status = SetThreadContext (th->h, &th->context);
+ });
- if (!killed)
- CHECK (status);
- }
- th->context.ContextFlags = 0;
- }
- }
th->resume ();
}
else
@@ -1454,8 +1363,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
th = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
if (th)
{
-#ifdef __x86_64__
- if (windows_process.wow64_process)
+ windows_process.with_context (th, [&] (auto *context)
{
if (step)
{
@@ -1463,53 +1371,25 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
regcache *regcache = get_thread_regcache (inferior_thread ());
struct gdbarch *gdbarch = regcache->arch ();
fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
- th->wow64_context.EFlags |= FLAG_TRACE_BIT;
+ context->EFlags |= FLAG_TRACE_BIT;
}
- if (th->wow64_context.ContextFlags)
+ if (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];
+ context->Dr0 = windows_process.dr[0];
+ context->Dr1 = windows_process.dr[1];
+ context->Dr2 = windows_process.dr[2];
+ context->Dr3 = windows_process.dr[3];
+ context->Dr6 = DR6_CLEAR_VALUE;
+ context->Dr7 = windows_process.dr[7];
th->debug_registers_changed = false;
}
- CHECK (Wow64SetThreadContext (th->h, &th->wow64_context));
- th->wow64_context.ContextFlags = 0;
+ CHECK (set_thread_context (th->h, context));
+ context->ContextFlags = 0;
}
- }
- else
-#endif
- {
- if (step)
- {
- /* Single step by setting t bit. */
- regcache *regcache = get_thread_regcache (inferior_thread ());
- struct gdbarch *gdbarch = regcache->arch ();
- 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;
- }
- }
+ });
}
/* Allow continuing with the same signal that interrupted us.