From 34b34921087ce04e7a45cbb38a3b8af17b0c630a Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 10 May 2007 21:48:56 +0000 Subject: [PATCH] * win32-low.c (debug_registers_changed, debug_registers_used, CONTEXT_EXTENDED_REGISTERS, CONTEXT_FLOATING_POINT, CONTEXT_DEBUG_REGISTERS, CONTEXT_DEBUGGER, CONTEXT_DEBUGGER_DR): Delete. (thread_rec): Get context using the low target. (child_add_thread): Call thread_added on the low target, which does the same thing. (regptr): Delete. (do_initial_child_stuff): Remove debug registers references. Set context using the low target. Resume threads after setting the contexts. (child_continue): Remove dead variable. Remove debug registers references. (child_fetch_inferior_registers): Go through the low target. (do_child_store_inferior_registers): Remove. (child_store_inferior_registers): Go through the low target. (win32_resume): Remove debug registers references. Set context using the low target. (handle_exception): Change return type to void. Don't record context here. Set status to TARGET_WAITKIND_SPURIOUS on a first chance exception. (get_child_debug_event): Change return type to void. Remove goto loop. Always return after waiting for debug event. (win32_wait): Convert to switch statement. Handle spurious events. * win32-i386-low.c (debug_registers_changed, debug_registers_used): New. (initial_stuff): Rename to ... (i386_initial_stuff): ... this. Clear debug registers state variables. (store_debug_registers): Delete. (i386_get_thread_context): New. (load_debug_registers): Delete. (i386_set_thread_context): New. (i386_thread_added): New. (single_step): Rename to ... (i386_single_step): ... this. (do_fetch_inferior_registers): Rename to ... (i386_fetch_inferior_register): ... this. (i386_store_inferior_register): New. (the_low_target): Adapt to new interface. * win32-arm-low.c (CONTEXT_FLOATING_POINT): Define. (arm_get_thread_context): New. (arm_set_thread_context): New. (regptr): New. (do_fetch_inferior_registers): Rename to ... (arm_fetch_inferior_register): ... this. (arm_store_inferior_register): New. (arm_wince_breakpoint): Reimplement as unsigned long. (arm_wince_breakpoint_len): Define. (the_low_target): Adapt to new interface. * win32-low.h (target_ops): Remove regmap, store_debug_registers and load_debug_registers. Add get_thread_context, set_thread_context, thread_added and store_inferior_register. Rename fetch_inferior_registers to fetch_inferior_register. (regptr): Remove declaration. --- gdb/gdbserver/ChangeLog | 62 +++++++++++++ gdb/gdbserver/win32-arm-low.c | 71 ++++++++++++--- gdb/gdbserver/win32-i386-low.c | 133 ++++++++++++++++++++-------- gdb/gdbserver/win32-low.c | 197 +++++++++-------------------------------- gdb/gdbserver/win32-low.h | 36 ++++---- 5 files changed, 272 insertions(+), 227 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 43bf8e9..028da2e 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,67 @@ 2007-05-10 Pedro Alves + * win32-low.c (debug_registers_changed, + debug_registers_used, CONTEXT_EXTENDED_REGISTERS, + CONTEXT_FLOATING_POINT, CONTEXT_DEBUG_REGISTERS, + CONTEXT_DEBUGGER, CONTEXT_DEBUGGER_DR): Delete. + (thread_rec): Get context using the low target. + (child_add_thread): Call thread_added on the low target, + which does the same thing. + (regptr): Delete. + (do_initial_child_stuff): Remove debug registers references. + Set context using the low target. Resume threads after + setting the contexts. + (child_continue): Remove dead variable. Remove debug + registers references. + (child_fetch_inferior_registers): Go through the low target. + (do_child_store_inferior_registers): Remove. + (child_store_inferior_registers): Go through the low target. + (win32_resume): Remove debug registers references. + Set context using the low target. + (handle_exception): Change return type to void. Don't record + context here. Set status to TARGET_WAITKIND_SPURIOUS on a + first chance exception. + (get_child_debug_event): Change return type to void. Remove + goto loop. Always return after waiting for debug event. + (win32_wait): Convert to switch statement. Handle spurious + events. + + * win32-i386-low.c (debug_registers_changed, + debug_registers_used): New. + (initial_stuff): Rename to ... + (i386_initial_stuff): ... this. Clear debug registers + state variables. + (store_debug_registers): Delete. + (i386_get_thread_context): New. + (load_debug_registers): Delete. + (i386_set_thread_context): New. + (i386_thread_added): New. + (single_step): Rename to ... + (i386_single_step): ... this. + (do_fetch_inferior_registers): Rename to ... + (i386_fetch_inferior_register): ... this. + (i386_store_inferior_register): New. + (the_low_target): Adapt to new interface. + + * win32-arm-low.c (CONTEXT_FLOATING_POINT): Define. + (arm_get_thread_context): New. + (arm_set_thread_context): New. + (regptr): New. + (do_fetch_inferior_registers): Rename to ... + (arm_fetch_inferior_register): ... this. + (arm_store_inferior_register): New. + (arm_wince_breakpoint): Reimplement as unsigned long. + (arm_wince_breakpoint_len): Define. + (the_low_target): Adapt to new interface. + + * win32-low.h (target_ops): Remove regmap, store_debug_registers and + load_debug_registers. Add get_thread_context, set_thread_context, + thread_added and store_inferior_register. Rename + fetch_inferior_registers to fetch_inferior_register. + (regptr): Remove declaration. + +2007-05-10 Pedro Alves + * linux-low.c (linux_detach): Change return type to int. Return 0. * spu-low.c (spu_detach): Likewise. diff --git a/gdb/gdbserver/win32-arm-low.c b/gdb/gdbserver/win32-arm-low.c index 08c5a09..6c4b80a 100644 --- a/gdb/gdbserver/win32-arm-low.c +++ b/gdb/gdbserver/win32-arm-low.c @@ -20,12 +20,24 @@ #include "server.h" #include "win32-low.h" -/* Fetch register(s) from gdbserver regcache data. */ +#ifndef CONTEXT_FLOATING_POINT +#define CONTEXT_FLOATING_POINT 0 +#endif + static void -do_fetch_inferior_registers (win32_thread_info *th, int r) +arm_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) { - char *context_offset = regptr (&th->context, r); - supply_register (r, context_offset); + th->context.ContextFlags = \ + CONTEXT_FULL | \ + CONTEXT_FLOATING_POINT; + + GetThreadContext (th->h, &th->context); +} + +static void +arm_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + SetThreadContext (th->h, &th->context); } #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) @@ -59,18 +71,53 @@ static const int mappings[] = { }; #undef context_offset -static const unsigned char arm_wince_le_breakpoint[] = - { 0x10, 0x00, 0x00, 0xe6 }; +/* Return a pointer into a CONTEXT field indexed by gdb register number. + Return a pointer to an dummy register holding zero if there is no + corresponding CONTEXT field for the given register number. */ +static char * +regptr (CONTEXT* c, int r) +{ + if (mappings[r] < 0) + { + static ULONG zero; + /* Always force value to zero, in case the user tried to write + to this register before. */ + zero = 0; + return (char *) &zero; + } + else + return (char *) c + mappings[r]; +} + +/* Fetch register from gdbserver regcache data. */ +static void +arm_fetch_inferior_register (win32_thread_info *th, int r) +{ + char *context_offset = regptr (&th->context, r); + supply_register (r, context_offset); +} + +/* Store a new register value into the thread context of TH. */ +static void +arm_store_inferior_register (win32_thread_info *th, int r) +{ + collect_register (r, regptr (&th->context, r)); +} + +/* Correct in either endianness. We do not support Thumb yet. */ +static const unsigned long arm_wince_breakpoint = 0xe6000001; +#define arm_wince_breakpoint_len 4 struct win32_target_ops the_low_target = { - mappings, sizeof (mappings) / sizeof (mappings[0]), NULL, /* initial_stuff */ - NULL, /* store_debug_registers */ - NULL, /* load_debug_registers */ - do_fetch_inferior_registers, + arm_get_thread_context, + arm_set_thread_context, + NULL, /* thread_added */ + arm_fetch_inferior_register, + arm_store_inferior_register, NULL, /* single_step */ - arm_wince_le_breakpoint, - sizeof (arm_wince_le_breakpoint) / sizeof (arm_wince_le_breakpoint[0]), + (const unsigned char *) &arm_wince_breakpoint, + arm_wince_breakpoint_len, "arm" /* arch_string */ }; diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c index 58ad787..11cab49 100644 --- a/gdb/gdbserver/win32-i386-low.c +++ b/gdb/gdbserver/win32-i386-low.c @@ -27,58 +27,83 @@ static unsigned dr[8]; +static int debug_registers_changed = 0; +static int debug_registers_used = 0; + static void -initial_stuff (void) +i386_initial_stuff (void) { memset (&dr, 0, sizeof (dr)); + debug_registers_changed = 0; + debug_registers_used = 0; } static void -store_debug_registers (win32_thread_info *th) +i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) { - dr[0] = th->context.Dr0; - dr[1] = th->context.Dr1; - dr[2] = th->context.Dr2; - dr[3] = th->context.Dr3; - dr[6] = th->context.Dr6; - dr[7] = th->context.Dr7; + th->context.ContextFlags = \ + CONTEXT_FULL | \ + CONTEXT_FLOATING_POINT | \ + CONTEXT_EXTENDED_REGISTERS | \ + CONTEXT_DEBUG_REGISTERS; + + GetThreadContext (th->h, &th->context); + + debug_registers_changed = 0; + + if (th->tid == current_event->dwThreadId) + { + /* Copy dr values from the current thread. */ + dr[0] = th->context.Dr0; + dr[1] = th->context.Dr1; + dr[2] = th->context.Dr2; + dr[3] = th->context.Dr3; + dr[6] = th->context.Dr6; + dr[7] = th->context.Dr7; + } } static void -load_debug_registers (win32_thread_info *th) +i386_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) { - th->context.Dr0 = dr[0]; - th->context.Dr1 = dr[1]; - th->context.Dr2 = dr[2]; - th->context.Dr3 = dr[3]; - /* th->context.Dr6 = dr[6]; - FIXME: should we set dr6 also ?? */ - th->context.Dr7 = dr[7]; + if (debug_registers_changed) + { + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + } + + SetThreadContext (th->h, &th->context); } -/* Fetch register(s) from gdbserver regcache data. */ static void -do_fetch_inferior_registers (win32_thread_info *th, int r) +i386_thread_added (win32_thread_info *th) { - char *context_offset = regptr (&th->context, r); - - long l; - if (r == FCS_REGNUM) + /* Set the debug registers for the new thread if they are used. */ + if (debug_registers_used) { - l = *((long *) context_offset) & 0xffff; - supply_register (r, (char *) &l); + th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + GetThreadContext (th->h, &th->context); + + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + + SetThreadContext (th->h, &th->context); + th->context.ContextFlags = 0; } - else if (r == FOP_REGNUM) - { - l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); - supply_register (r, (char *) &l); - } - else - supply_register (r, context_offset); } static void -single_step (win32_thread_info *th) +i386_single_step (win32_thread_info *th) { th->context.EFlags |= FLAG_TRACE_BIT; } @@ -138,15 +163,45 @@ static const int mappings[] = { }; #undef context_offset +/* Fetch register from gdbserver regcache data. */ +static void +i386_fetch_inferior_register (win32_thread_info *th, int r) +{ + char *context_offset = (char *) &th->context + mappings[r]; + + long l; + if (r == FCS_REGNUM) + { + l = *((long *) context_offset) & 0xffff; + supply_register (r, (char *) &l); + } + else if (r == FOP_REGNUM) + { + l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); + supply_register (r, (char *) &l); + } + else + supply_register (r, context_offset); +} + +/* Store a new register value into the thread context of TH. */ +static void +i386_store_inferior_register (win32_thread_info *th, int r) +{ + char *context_offset = (char *) &th->context + mappings[r]; + collect_register (r, context_offset); +} + struct win32_target_ops the_low_target = { - mappings, sizeof (mappings) / sizeof (mappings[0]), - initial_stuff, - store_debug_registers, - load_debug_registers, - do_fetch_inferior_registers, - single_step, - (const char*)NULL, /* breakpoint */ + i386_initial_stuff, + i386_get_thread_context, + i386_set_thread_context, + i386_thread_added, + i386_fetch_inferior_register, + i386_store_inferior_register, + i386_single_step, + NULL, /* breakpoint */ 0, /* breakpoint_len */ "i386" /* arch_string */ }; diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index e980db4..51b1915 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -73,32 +73,15 @@ static enum target_signal last_sig = TARGET_SIGNAL_0; /* The current debug event from WaitForDebugEvent. */ static DEBUG_EVENT current_event; -static int debug_registers_changed = 0; -static int debug_registers_used = 0; - #define NUM_REGS (the_low_target.num_regs) typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId); typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit); -#ifndef CONTEXT_EXTENDED_REGISTERS -#define CONTEXT_EXTENDED_REGISTERS 0 -#endif - -#ifndef CONTEXT_FLOATING_POINT -#define CONTEXT_FLOATING_POINT 0 -#endif - -#ifndef CONTEXT_DEBUG_REGISTERS -#define CONTEXT_DEBUG_REGISTERS 0 -#endif - -#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT) -#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \ - | CONTEXT_EXTENDED_REGISTERS - static DWORD main_thread_id = 0; +static void win32_resume (struct thread_resume *resume_info); + /* Get the thread ID from the current selected inferior (the current thread). */ static DWORD @@ -123,21 +106,10 @@ thread_rec (DWORD id, int get_context) th = inferior_target_data (thread); if (!th->suspend_count && get_context) { - if (get_context > 0 && id != current_event.dwThreadId) + if (id != current_event.dwThreadId) th->suspend_count = SuspendThread (th->h) + 1; - else if (get_context < 0) - th->suspend_count = -1; - - th->context.ContextFlags = CONTEXT_DEBUGGER_DR; - GetThreadContext (th->h, &th->context); - - if (id == current_event.dwThreadId) - { - /* Copy dr values from that thread. */ - if (the_low_target.store_debug_registers != NULL) - (*the_low_target.store_debug_registers) (th); - } + (*the_low_target.get_thread_context) (th, ¤t_event); } return th; @@ -162,20 +134,8 @@ child_add_thread (DWORD tid, HANDLE h) find_inferior_id (&all_threads, tid), new_register_cache ()); - /* Set the debug registers for the new thread if they are used. */ - if (debug_registers_used - && the_low_target.load_debug_registers != NULL) - { - /* Only change the value of the debug registers. */ - th->context.ContextFlags = CONTEXT_DEBUGGER_DR; - - GetThreadContext (th->h, &th->context); - - (*the_low_target.load_debug_registers) (th); - - SetThreadContext (th->h, &th->context); - th->context.ContextFlags = 0; - } + if (the_low_target.thread_added != NULL) + (*the_low_target.thread_added) (th); return th; } @@ -246,7 +206,6 @@ enum target_waitkind /* The program has exec'ed a new executable file. The new file's pathname is pointed to by value.execd_pathname. */ - TARGET_WAITKIND_EXECD, /* Nothing happened, but we stopped anyway. This perhaps should be handled @@ -271,25 +230,6 @@ struct target_waitstatus value; }; -/* Return a pointer into a CONTEXT field indexed by gdb register number. - Return a pointer to an dummy register holding zero if there is no - corresponding CONTEXT field for the given register number. */ -char * -regptr (CONTEXT* c, int r) -{ - if (the_low_target.regmap[r] < 0) - { - static ULONG zero; - /* Always force value to zero, in case the user tried to write - to this register before. */ - zero = 0; - return (char *) &zero; - } - else - return (char *) c + the_low_target.regmap[r]; -} - - /* Clear out any old thread list and reinitialize it to a pristine state. */ static void @@ -303,9 +243,6 @@ do_initial_child_stuff (DWORD pid) { last_sig = TARGET_SIGNAL_0; - debug_registers_changed = 0; - debug_registers_used = 0; - memset (¤t_event, 0, sizeof (current_event)); child_init_thread_list (); @@ -327,20 +264,15 @@ continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr) if ((thread_id == -1 || thread_id == th->tid) && th->suspend_count) { - for (i = 0; i < th->suspend_count; i++) - (void) ResumeThread (th->h); - th->suspend_count = 0; - if (debug_registers_changed) + if (th->context.ContextFlags) { - /* Only change the value of the debug registers. */ - th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; - - if (the_low_target.load_debug_registers != NULL) - the_low_target.load_debug_registers (th); - - SetThreadContext (th->h, &th->context); + (*the_low_target.set_thread_context) (th, ¤t_event); th->context.ContextFlags = 0; } + + for (i = 0; i < th->suspend_count; i++) + (void) ResumeThread (th->h); + th->suspend_count = 0; } return 0; @@ -353,11 +285,9 @@ child_continue (DWORD continue_status, int thread_id) res = ContinueDebugEvent (current_event.dwProcessId, current_event.dwThreadId, continue_status); - continue_status = 0; if (res) find_inferior (&all_threads, continue_one_thread, &thread_id); - debug_registers_changed = 0; return res; } @@ -371,14 +301,7 @@ child_fetch_inferior_registers (int r) child_fetch_inferior_registers (NUM_REGS); else for (regno = 0; regno < r; regno++) - (*the_low_target.fetch_inferior_registers) (th, regno); -} - -/* Get register from gdbserver regcache data. */ -static void -do_child_store_inferior_registers (win32_thread_info *th, int r) -{ - collect_register (r, regptr (&th->context, r)); + (*the_low_target.fetch_inferior_register) (th, regno); } /* Store a new register value into the current thread context. We don't @@ -392,7 +315,7 @@ child_store_inferior_registers (int r) child_store_inferior_registers (NUM_REGS); else for (regno = 0; regno < r; regno++) - do_child_store_inferior_registers (th, regno); + (*the_low_target.store_inferior_register) (th, regno); } /* Map the Windows error number in ERROR to a locale-dependent error @@ -816,10 +739,6 @@ win32_resume (struct thread_resume *resume_info) { if (th->context.ContextFlags) { - if (debug_registers_changed) - if (the_low_target.load_debug_registers != NULL) - (*the_low_target.load_debug_registers) (th); - /* Move register values from the inferior into the thread context structure. */ regcache_invalidate (); @@ -832,7 +751,8 @@ win32_resume (struct thread_resume *resume_info) error ("Single stepping is not supported " "in this configuration.\n"); } - SetThreadContext (th->h, &th->context); + + (*the_low_target.set_thread_context) (th, ¤t_event); th->context.ContextFlags = 0; } } @@ -843,17 +763,13 @@ win32_resume (struct thread_resume *resume_info) child_continue (continue_status, tid); } -static int +static void handle_exception (struct target_waitstatus *ourstatus) { - win32_thread_info *th; DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; ourstatus->kind = TARGET_WAITKIND_STOPPED; - /* Record the context of the current thread. */ - th = thread_rec (current_event.dwThreadId, -1); - switch (code) { case EXCEPTION_ACCESS_VIOLATION: @@ -939,7 +855,10 @@ handle_exception (struct target_waitstatus *ourstatus) break; default: if (current_event.u.Exception.dwFirstChance) - return 0; + { + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + return; + } OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx", current_event.u.Exception.ExceptionRecord.ExceptionCode, (DWORD) current_event.u.Exception.ExceptionRecord. @@ -949,36 +868,25 @@ handle_exception (struct target_waitstatus *ourstatus) } OUTMSG2 (("\n")); last_sig = ourstatus->value.sig; - return 1; } -/* Get the next event from the child. Return 1 if the event requires - handling. */ -static int +/* Get the next event from the child. */ +static void get_child_debug_event (struct target_waitstatus *ourstatus) { BOOL debug_event; - DWORD continue_status, event_code; - win32_thread_info *th = NULL; - static win32_thread_info dummy_thread_info; - int retval = 0; - -in: last_sig = TARGET_SIGNAL_0; ourstatus->kind = TARGET_WAITKIND_SPURIOUS; if (!(debug_event = WaitForDebugEvent (¤t_event, 1000))) - goto out; + return; current_inferior = (struct thread_info *) find_inferior_id (&all_threads, current_event.dwThreadId); - continue_status = DBG_CONTINUE; - event_code = current_event.dwDebugEventCode; - - switch (event_code) + switch (current_event.dwDebugEventCode) { case CREATE_THREAD_DEBUG_EVENT: OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT " @@ -987,10 +895,8 @@ in: (unsigned) current_event.dwThreadId)); /* Record the existence of this thread. */ - th = child_add_thread (current_event.dwThreadId, + child_add_thread (current_event.dwThreadId, current_event.u.CreateThread.hThread); - - retval = current_event.dwThreadId; break; case EXIT_THREAD_DEBUG_EVENT: @@ -999,7 +905,6 @@ in: (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId)); child_delete_thread (current_event.dwThreadId); - th = &dummy_thread_info; break; case CREATE_PROCESS_DEBUG_EVENT: @@ -1016,11 +921,10 @@ in: ourstatus->value.execd_pathname = "Main executable"; /* Add the main thread. */ - th = - child_add_thread (main_thread_id, - current_event.u.CreateProcessInfo.hThread); + child_add_thread (main_thread_id, + current_event.u.CreateProcessInfo.hThread); - retval = ourstatus->value.related_pid = current_event.dwThreadId; + ourstatus->value.related_pid = current_event.dwThreadId; #ifdef _WIN32_WCE /* Windows CE doesn't set the initial breakpoint automatically like the desktop versions of Windows do. We add it explicitly @@ -1040,7 +944,6 @@ in: ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; CloseHandle (current_process_handle); current_process_handle = NULL; - retval = main_thread_id; break; case LOAD_DLL_DEBUG_EVENT: @@ -1052,7 +955,6 @@ in: ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - retval = main_thread_id; break; case UNLOAD_DLL_DEBUG_EVENT: @@ -1067,7 +969,7 @@ in: "for pid=%d tid=%x\n", (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId)); - retval = handle_exception (ourstatus); + handle_exception (ourstatus); break; case OUTPUT_DEBUG_STRING_EVENT: @@ -1091,18 +993,6 @@ in: current_inferior = (struct thread_info *) find_inferior_id (&all_threads, current_event.dwThreadId); - - if (!retval || (event_code != EXCEPTION_DEBUG_EVENT && event_code != EXIT_PROCESS_DEBUG_EVENT)) - { - child_continue (continue_status, -1); - goto in; - } - - if (th == NULL) - thread_rec (current_event.dwThreadId, TRUE); - -out: - return retval; } /* Wait for the inferior process to change state. @@ -1119,8 +1009,9 @@ win32_wait (char *status) { get_child_debug_event (&our_status); - if (our_status.kind == TARGET_WAITKIND_EXITED) + switch (our_status.kind) { + case TARGET_WAITKIND_EXITED: OUTMSG2 (("Child exited with retcode = %x\n", our_status.value.integer)); @@ -1129,9 +1020,7 @@ win32_wait (char *status) child_fetch_inferior_registers (-1); return our_status.value.integer; - } - else if (our_status.kind == TARGET_WAITKIND_STOPPED) - { + case TARGET_WAITKIND_STOPPED: OUTMSG2 (("Child Stopped with signal = %d \n", our_status.value.sig)); @@ -1140,18 +1029,16 @@ win32_wait (char *status) child_fetch_inferior_registers (-1); return our_status.value.sig; + default: + OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind)); + /* fall-through */ + case TARGET_WAITKIND_SPURIOUS: + case TARGET_WAITKIND_LOADED: + case TARGET_WAITKIND_EXECD: + /* do nothing, just continue */ + child_continue (DBG_CONTINUE, -1); + break; } - else - OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind)); - - { - struct thread_resume resume; - resume.thread = -1; - resume.step = 0; - resume.sig = 0; - resume.leave_stopped = 0; - win32_resume (&resume); - } } } diff --git a/gdb/gdbserver/win32-low.h b/gdb/gdbserver/win32-low.h index 68daa62..eb6d757 100644 --- a/gdb/gdbserver/win32-low.h +++ b/gdb/gdbserver/win32-low.h @@ -32,25 +32,26 @@ typedef struct win32_thread_info struct win32_target_ops { - /* 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 - the 4 byte register is located. - 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. */ - const int *regmap; - - /* The number of elements of regmap. */ + /* The number of target registers. */ int num_regs; + /* Perform initializations on startup. */ void (*initial_stuff) (void); - void (*store_debug_registers) (win32_thread_info *); - void (*load_debug_registers) (win32_thread_info *); + /* Fetch the context from the inferior. */ + void (*get_thread_context) (win32_thread_info *th, DEBUG_EVENT *current_event); - /* Fetch register(s) from gdbserver regcache data. */ - void (*fetch_inferior_registers) (win32_thread_info *th, int r); + /* Flush the context back to the inferior. */ + void (*set_thread_context) (win32_thread_info *th, DEBUG_EVENT *current_event); + + /* Called when a thread was added. */ + void (*thread_added) (win32_thread_info *th); + + /* Fetch register from gdbserver regcache data. */ + void (*fetch_inferior_register) (win32_thread_info *th, int r); + + /* Store a new register value into the thread context of TH. */ + void (*store_inferior_register) (win32_thread_info *th, int r); void (*single_step) (win32_thread_info *th); @@ -64,13 +65,6 @@ struct win32_target_ops extern struct win32_target_ops the_low_target; -/* in win32-low.c */ - -/* Return a pointer into a CONTEXT field indexed by gdb register number. - Return a pointer to an dummy register holding zero if there is no - corresponding CONTEXT field for the given register number. */ -extern char * regptr (CONTEXT* c, int r); - /* Map the Windows error number in ERROR to a locale-dependent error message string and return a pointer to it. Typically, the values for ERROR come from GetLastError. -- 2.7.4