diff options
author | Hannes Domani <ssbssa@yahoo.de> | 2020-04-24 17:23:59 +0200 |
---|---|---|
committer | Hannes Domani <ssbssa@yahoo.de> | 2020-04-30 18:30:20 +0200 |
commit | 7d186bc04245c5757f396c2d4f8f89f24818628e (patch) | |
tree | cd43bdbf890d076a6a2a8889c0be130e30e8d3e9 /gdbserver/win32-i386-low.cc | |
parent | ee9d1e5f76033cd8432713a76381ade76697df04 (diff) | |
download | gdb-7d186bc04245c5757f396c2d4f8f89f24818628e.zip gdb-7d186bc04245c5757f396c2d4f8f89f24818628e.tar.gz gdb-7d186bc04245c5757f396c2d4f8f89f24818628e.tar.bz2 |
Implement debugging of WOW64 processes in gdbserver
gdbserver/ChangeLog:
2020-04-30 Hannes Domani <ssbssa@yahoo.de>
* configure.srv <x86_64-*-mingw*, x86_64-*-cygwin*> (srv_tgtobj):
Add arch/i386.o.
* win32-arm-low.cc (arm_num_regs): New function.
(struct win32_target_ops): Use arm_num_regs.
* win32-i386-low.cc (win32_get_current_dr): Adapt for WOW64
processes.
(i386_get_thread_context): Likewise.
(i386_prepare_to_resume): Likewise.
(i386_thread_added): Likewise.
(i386_single_step): Likewise.
(i386_fetch_inferior_register): Likewise.
(i386_store_inferior_register): Likewise.
(i386_arch_setup): Likewise.
(i386_win32_num_regs): New function.
(struct win32_target_ops): Use i386_win32_num_regs.
* win32-low.cc (win32_get_thread_context): Adapt for WOW64
processes.
(win32_require_context): Likewise.
(child_add_thread): Likewise.
(do_initial_child_stuff): Likewise.
(continue_one_thread): Likewise.
(win32_process_target::resume): Likewise.
(load_psapi): Likewise.
(win32_add_all_dlls): Likewise.
(maybe_adjust_pc): Likewise.
(win32_process_target::qxfer_siginfo): Likewise.
(initialize_low): Likewise.
* win32-low.h (struct win32_target_ops): Change num_regs to
callback function.
Diffstat (limited to 'gdbserver/win32-i386-low.cc')
-rw-r--r-- | gdbserver/win32-i386-low.cc | 171 |
1 files changed, 138 insertions, 33 deletions
diff --git a/gdbserver/win32-i386-low.cc b/gdbserver/win32-i386-low.cc index 48893af..389ec49 100644 --- a/gdbserver/win32-i386-low.cc +++ b/gdbserver/win32-i386-low.cc @@ -80,18 +80,40 @@ win32_get_current_dr (int dr) win32_require_context (th); +#ifdef __x86_64__ +#define RET_DR(DR) \ + case DR: \ + return th->wow64_context.Dr ## DR + + if (wow64_process) + { + switch (dr) + { + RET_DR (0); + RET_DR (1); + RET_DR (2); + RET_DR (3); + RET_DR (6); + RET_DR (7); + } + } + else +#undef RET_DR +#endif #define RET_DR(DR) \ case DR: \ return th->context.Dr ## DR - switch (dr) { - RET_DR (0); - RET_DR (1); - RET_DR (2); - RET_DR (3); - RET_DR (6); - RET_DR (7); + switch (dr) + { + RET_DR (0); + RET_DR (1); + RET_DR (2); + RET_DR (3); + RET_DR (6); + RET_DR (7); + } } #undef RET_DR @@ -219,12 +241,27 @@ i386_get_thread_context (windows_thread_info *th) static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS; again: - th->context.ContextFlags = (CONTEXT_FULL - | CONTEXT_FLOATING_POINT - | CONTEXT_DEBUG_REGISTERS - | extended_registers); +#ifdef __x86_64__ + if (wow64_process) + th->wow64_context.ContextFlags = (CONTEXT_FULL + | CONTEXT_FLOATING_POINT + | CONTEXT_DEBUG_REGISTERS + | extended_registers); + else +#endif + th->context.ContextFlags = (CONTEXT_FULL + | CONTEXT_FLOATING_POINT + | CONTEXT_DEBUG_REGISTERS + | extended_registers); - if (!GetThreadContext (th->h, &th->context)) + BOOL ret; +#ifdef __x86_64__ + if (wow64_process) + ret = win32_Wow64GetThreadContext (th->h, &th->wow64_context); + else +#endif + ret = GetThreadContext (th->h, &th->context); + if (!ret) { DWORD e = GetLastError (); @@ -247,13 +284,28 @@ i386_prepare_to_resume (windows_thread_info *th) win32_require_context (th); - th->context.Dr0 = dr->dr_mirror[0]; - th->context.Dr1 = dr->dr_mirror[1]; - th->context.Dr2 = dr->dr_mirror[2]; - th->context.Dr3 = dr->dr_mirror[3]; - /* th->context.Dr6 = dr->dr_status_mirror; - FIXME: should we set dr6 also ?? */ - th->context.Dr7 = dr->dr_control_mirror; +#ifdef __x86_64__ + if (wow64_process) + { + th->wow64_context.Dr0 = dr->dr_mirror[0]; + th->wow64_context.Dr1 = dr->dr_mirror[1]; + th->wow64_context.Dr2 = dr->dr_mirror[2]; + th->wow64_context.Dr3 = dr->dr_mirror[3]; + /* th->wow64_context.Dr6 = dr->dr_status_mirror; + FIXME: should we set dr6 also ?? */ + th->wow64_context.Dr7 = dr->dr_control_mirror; + } + else +#endif + { + th->context.Dr0 = dr->dr_mirror[0]; + th->context.Dr1 = dr->dr_mirror[1]; + th->context.Dr2 = dr->dr_mirror[2]; + th->context.Dr3 = dr->dr_mirror[3]; + /* th->context.Dr6 = dr->dr_status_mirror; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr->dr_control_mirror; + } th->debug_registers_changed = false; } @@ -268,11 +320,14 @@ i386_thread_added (windows_thread_info *th) static void i386_single_step (windows_thread_info *th) { - th->context.EFlags |= FLAG_TRACE_BIT; +#ifdef __x86_64__ + if (wow64_process) + th->wow64_context.EFlags |= FLAG_TRACE_BIT; + else +#endif + th->context.EFlags |= FLAG_TRACE_BIT; } -#ifndef __x86_64__ - /* An array of offset mappings into a Win32 Context structure. This is a one-to-one mapping which is indexed by gdb's register numbers. It retrieves an offset into the context structure where @@ -280,8 +335,12 @@ i386_single_step (windows_thread_info *th) An offset value of -1 indicates that Win32 does not provide this register in it's CONTEXT structure. In this case regptr will return a pointer into a dummy register. */ +#ifdef __x86_64__ +#define context_offset(x) (offsetof (WOW64_CONTEXT, x)) +#else #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) -static const int mappings[] = { +#endif +static const int i386_mappings[] = { context_offset (Eax), context_offset (Ecx), context_offset (Edx), @@ -328,10 +387,10 @@ static const int mappings[] = { }; #undef context_offset -#else /* __x86_64__ */ +#ifdef __x86_64__ #define context_offset(x) (offsetof (CONTEXT, x)) -static const int mappings[] = +static const int amd64_mappings[] = { context_offset (Rax), context_offset (Rbx), @@ -402,7 +461,21 @@ static void i386_fetch_inferior_register (struct regcache *regcache, windows_thread_info *th, int r) { - char *context_offset = (char *) &th->context + mappings[r]; + const int *mappings; +#ifdef __x86_64__ + if (!wow64_process) + mappings = amd64_mappings; + else +#endif + mappings = i386_mappings; + + char *context_offset; +#ifdef __x86_64__ + if (wow64_process) + context_offset = (char *) &th->wow64_context + mappings[r]; + else +#endif + context_offset = (char *) &th->context + mappings[r]; long l; if (r == FCS_REGNUM) @@ -424,7 +497,22 @@ static void i386_store_inferior_register (struct regcache *regcache, windows_thread_info *th, int r) { - char *context_offset = (char *) &th->context + mappings[r]; + const int *mappings; +#ifdef __x86_64__ + if (!wow64_process) + mappings = amd64_mappings; + else +#endif + mappings = i386_mappings; + + char *context_offset; +#ifdef __x86_64__ + if (wow64_process) + context_offset = (char *) &th->wow64_context + mappings[r]; + else +#endif + context_offset = (char *) &th->context + mappings[r]; + collect_register (regcache, r, context_offset); } @@ -439,15 +527,32 @@ i386_arch_setup (void) #ifdef __x86_64__ tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false, false, false); - const char **expedite_regs = amd64_expedite_regs; -#else + init_target_desc (tdesc, amd64_expedite_regs); + win32_tdesc = tdesc; +#endif + tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); - const char **expedite_regs = i386_expedite_regs; + init_target_desc (tdesc, i386_expedite_regs); +#ifdef __x86_64__ + wow64_win32_tdesc = tdesc; +#else + win32_tdesc = tdesc; #endif +} - init_target_desc (tdesc, expedite_regs); +/* Implement win32_target_ops "num_regs" method. */ - win32_tdesc = tdesc; +static int +i386_win32_num_regs (void) +{ + int num_regs; +#ifdef __x86_64__ + if (!wow64_process) + num_regs = sizeof (amd64_mappings) / sizeof (amd64_mappings[0]); + else +#endif + num_regs = sizeof (i386_mappings) / sizeof (i386_mappings[0]); + return num_regs; } /* Implement win32_target_ops "get_pc" method. */ @@ -496,7 +601,7 @@ i386_win32_set_pc (struct regcache *regcache, CORE_ADDR pc) struct win32_target_ops the_low_target = { i386_arch_setup, - sizeof (mappings) / sizeof (mappings[0]), + i386_win32_num_regs, i386_initial_stuff, i386_get_thread_context, i386_prepare_to_resume, |