X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdbserver%2Fwin32-low.cc;h=4312bb3ab7cc3a8bb988febf680a09c5cb227ac8;hb=523d4f80c32f43a6b009645947b94f87df35f79f;hp=23c23bc7ed8ea8d77e9e98c05b3fdf419aa6c6f1;hpb=d7abedf7e7d18c8a32f63b0e44bee4a4f3b581ba;p=deliverable%2Fbinutils-gdb.git diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 23c23bc7ed..4312bb3ab7 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -36,6 +36,8 @@ #include "gdbsupport/common-inferior.h" #include "gdbsupport/gdb_wait.h" +using namespace windows_nat; + #ifndef USE_WIN32API #include #endif @@ -72,14 +74,6 @@ int using_threads = 1; /* Globals. */ 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. */ -static DEBUG_EVENT current_event; /* A status that hasn't been reported to the core yet, and so win32_wait should return it next, instead of fetching the next @@ -125,7 +119,7 @@ debug_event_ptid (DEBUG_EVENT *event) /* Get the thread context of the thread associated with TH. */ static void -win32_get_thread_context (win32_thread_info *th) +win32_get_thread_context (windows_thread_info *th) { memset (&th->context, 0, sizeof (CONTEXT)); (*the_low_target.get_thread_context) (th); @@ -137,7 +131,7 @@ win32_get_thread_context (win32_thread_info *th) /* Set the thread context of the thread associated with TH. */ static void -win32_set_thread_context (win32_thread_info *th) +win32_set_thread_context (windows_thread_info *th) { #ifdef _WIN32_WCE /* Calling SuspendThread on a thread that is running kernel code @@ -158,7 +152,7 @@ win32_set_thread_context (win32_thread_info *th) /* Set the thread context of the thread associated with TH. */ static void -win32_prepare_to_resume (win32_thread_info *th) +win32_prepare_to_resume (windows_thread_info *th) { if (the_low_target.prepare_to_resume != NULL) (*the_low_target.prepare_to_resume) (th); @@ -167,55 +161,41 @@ win32_prepare_to_resume (win32_thread_info *th) /* See win32-low.h. */ void -win32_require_context (win32_thread_info *th) +win32_require_context (windows_thread_info *th) { if (th->context.ContextFlags == 0) { - if (!th->suspended) - { - if (SuspendThread (th->h) == (DWORD) -1) - { - DWORD err = GetLastError (); - OUTMSG (("warning: SuspendThread failed in thread_rec, " - "(error %d): %s\n", (int) err, strwinerror (err))); - } - else - th->suspended = 1; - } - + th->suspend (); win32_get_thread_context (th); } } -/* Find a thread record given a thread id. If GET_CONTEXT is set then - also retrieve the context for this thread. */ -static win32_thread_info * -thread_rec (ptid_t ptid, int get_context) +/* See nat/windows-nat.h. */ + +windows_thread_info * +windows_nat::thread_rec (ptid_t ptid, thread_disposition_type disposition) { thread_info *thread = find_thread_ptid (ptid); if (thread == NULL) return NULL; - win32_thread_info *th = (win32_thread_info *) thread_target_data (thread); - if (get_context) + windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); + if (disposition != DONT_INVALIDATE_CONTEXT) win32_require_context (th); return th; } /* Add a thread to the thread list. */ -static win32_thread_info * +static windows_thread_info * child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb) { - win32_thread_info *th; + windows_thread_info *th; ptid_t ptid = ptid_t (pid, tid, 0); - if ((th = thread_rec (ptid, FALSE))) + if ((th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT))) return th; - th = XCNEW (win32_thread_info); - th->tid = tid; - th->h = h; - th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb; + th = new windows_thread_info (tid, h, (CORE_ADDR) (uintptr_t) tlb); add_thread (ptid, th); @@ -229,11 +209,10 @@ child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb) static void delete_thread_info (thread_info *thread) { - win32_thread_info *th = (win32_thread_info *) thread_target_data (thread); + windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); remove_thread (thread); - CloseHandle (th->h); - free (th); + delete th; } /* Delete a thread from the list of threads. */ @@ -257,15 +236,18 @@ child_delete_thread (DWORD pid, DWORD tid) bool win32_process_target::supports_z_point_type (char z_type) { - return (the_low_target.supports_z_point_type != NULL - && the_low_target.supports_z_point_type (z_type)); + return (z_type == Z_PACKET_SW_BP + || (the_low_target.supports_z_point_type != NULL + && the_low_target.supports_z_point_type (z_type))); } int win32_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, raw_breakpoint *bp) { - if (the_low_target.insert_point != NULL) + if (type == raw_bkpt_type_sw) + return insert_memory_breakpoint (bp); + else if (the_low_target.insert_point != NULL) return the_low_target.insert_point (type, addr, size, bp); else /* Unsupported (see target.h). */ @@ -276,7 +258,9 @@ int win32_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, raw_breakpoint *bp) { - if (the_low_target.remove_point != NULL) + if (type == raw_bkpt_type_sw) + return remove_memory_breakpoint (bp); + else if (the_low_target.remove_point != NULL) return the_low_target.remove_point (type, addr, size, bp); else /* Unsupported (see target.h). */ @@ -377,7 +361,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) { struct target_waitstatus status; - the_target->pt->wait (minus_one_ptid, &status, 0); + the_target->wait (minus_one_ptid, &status, 0); /* Note win32_wait doesn't return thread events. */ if (status.kind != TARGET_WAITKIND_LOADED) @@ -393,7 +377,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) resume.kind = resume_continue; resume.sig = 0; - the_target->pt->resume (&resume, 1); + the_target->resume (&resume, 1); } } @@ -424,7 +408,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) static void continue_one_thread (thread_info *thread, int thread_id) { - win32_thread_info *th = (win32_thread_info *) thread_target_data (thread); + windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); if (thread_id == -1 || thread_id == th->tid) { @@ -438,13 +422,7 @@ continue_one_thread (thread_info *thread, int thread_id) th->context.ContextFlags = 0; } - if (ResumeThread (th->h) == (DWORD) -1) - { - DWORD err = GetLastError (); - OUTMSG (("warning: ResumeThread failed in continue_one_thread, " - "(error %d): %s\n", (int) err, strwinerror (err))); - } - th->suspended = 0; + th->resume (); } } } @@ -460,12 +438,7 @@ child_continue (DWORD continue_status, int thread_id) }); faked_breakpoint = 0; - if (!ContinueDebugEvent (current_event.dwProcessId, - current_event.dwThreadId, - continue_status)) - return FALSE; - - return TRUE; + return continue_last_debug_event (continue_status, debug_threads); } /* Fetch register(s) from the current thread context. */ @@ -473,7 +446,8 @@ static void child_fetch_inferior_registers (struct regcache *regcache, int r) { int regno; - win32_thread_info *th = thread_rec (current_thread_ptid (), TRUE); + windows_thread_info *th = thread_rec (current_thread_ptid (), + INVALIDATE_CONTEXT); if (r == -1 || r > NUM_REGS) child_fetch_inferior_registers (regcache, NUM_REGS); else @@ -487,7 +461,8 @@ static void child_store_inferior_registers (struct regcache *regcache, int r) { int regno; - win32_thread_info *th = thread_rec (current_thread_ptid (), TRUE); + windows_thread_info *th = thread_rec (current_thread_ptid (), + INVALIDATE_CONTEXT); if (r == -1 || r == 0 || r > NUM_REGS) child_store_inferior_registers (regcache, NUM_REGS); else @@ -758,9 +733,10 @@ win32_process_target::attach (unsigned long pid) (int) err, strwinerror (err)); } -/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */ -static void -handle_output_debug_string (void) +/* See nat/windows-nat.h. */ + +int +windows_nat::handle_output_debug_string (struct target_waitstatus *ourstatus) { #define READ_BUFFER_LEN 1024 CORE_ADDR addr; @@ -768,7 +744,7 @@ handle_output_debug_string (void) DWORD nbytes = current_event.u.DebugString.nDebugStringLength; if (nbytes == 0) - return; + return 0; if (nbytes > READ_BUFFER_LEN) nbytes = READ_BUFFER_LEN; @@ -781,13 +757,13 @@ handle_output_debug_string (void) in Unicode. */ WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 }; if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0) - return; + return 0; wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR)); } else { if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0) - return; + return 0; } if (!startswith (s, "cYg")) @@ -795,12 +771,14 @@ handle_output_debug_string (void) if (!server_waiting) { OUTMSG2(("%s", s)); - return; + return 0; } monitor_output (s); } #undef READ_BUFFER_LEN + + return 0; } static void @@ -824,12 +802,12 @@ win32_process_target::kill (process_info *process) { if (!child_continue (DBG_CONTINUE, -1)) break; - if (!WaitForDebugEvent (¤t_event, INFINITE)) + if (!wait_for_debug_event (¤t_event, INFINITE)) break; if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) - handle_output_debug_string (); + handle_output_debug_string (nullptr); } win32_clear_inferiors (); @@ -911,7 +889,7 @@ win32_process_target::resume (thread_resume *resume_info, size_t n) DWORD tid; enum gdb_signal sig; int step; - win32_thread_info *th; + windows_thread_info *th; DWORD continue_status = DBG_CONTINUE; ptid_t ptid; @@ -956,7 +934,7 @@ win32_process_target::resume (thread_resume *resume_info, size_t n) /* Get context for the currently selected thread. */ ptid = debug_event_ptid (¤t_event); - th = thread_rec (ptid, FALSE); + th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT); if (th) { win32_prepare_to_resume (th); @@ -1048,55 +1026,6 @@ win32_add_one_solib (const char *name, CORE_ADDR load_addr) loaded_dll (buf2, load_addr); } -static char * -get_image_name (HANDLE h, void *address, int unicode) -{ - static char buf[(2 * MAX_PATH) + 1]; - DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); - char *address_ptr; - int len = 0; - char b[2]; - SIZE_T done; - - /* Attempt to read the name of the dll that was detected. - This is documented to work only when actively debugging - a program. It will not work for attached processes. */ - if (address == NULL) - return NULL; - -#ifdef _WIN32_WCE - /* Windows CE reports the address of the image name, - instead of an address of a pointer into the image name. */ - address_ptr = address; -#else - /* See if we could read the address of a string, and that the - address isn't null. */ - if (!ReadProcessMemory (h, address, &address_ptr, - sizeof (address_ptr), &done) - || done != sizeof (address_ptr) - || !address_ptr) - return NULL; -#endif - - /* Find the length of the string */ - while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) - && (b[0] != 0 || b[size - 1] != 0) && done == size) - continue; - - if (!unicode) - ReadProcessMemory (h, address_ptr, buf, len, &done); - else - { - WCHAR *unicode_address = XALLOCAVEC (WCHAR, len); - ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR), - &done); - - WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0); - } - - return buf; -} - typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD); typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE, @@ -1194,18 +1123,13 @@ typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD); typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32); typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32); -/* Handle a DLL load event. - - This function assumes that this event did not occur during inferior - initialization, where their event info may be incomplete (see - do_initial_child_stuff and win32_add_all_dlls for more info on - how we handle DLL loading during that phase). */ +/* See nat/windows-nat.h. */ -static void -handle_load_dll (void) +void +windows_nat::handle_load_dll () { LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; - char *dll_name; + const char *dll_name; dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode); @@ -1215,15 +1139,10 @@ handle_load_dll (void) win32_add_one_solib (dll_name, (CORE_ADDR) (uintptr_t) event->lpBaseOfDll); } -/* Handle a DLL unload event. +/* See nat/windows-nat.h. */ - This function assumes that this event did not occur during inferior - initialization, where their event info may be incomplete (see - do_initial_child_stuff and win32_add_one_solib for more info - on how we handle DLL loading during that phase). */ - -static void -handle_unload_dll (void) +void +windows_nat::handle_unload_dll () { CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll; @@ -1235,133 +1154,12 @@ handle_unload_dll (void) unloaded_dll (NULL, load_addr); } -static void -handle_exception (struct target_waitstatus *ourstatus) -{ - DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; - - memcpy (&siginfo_er, ¤t_event.u.Exception.ExceptionRecord, - sizeof siginfo_er); - - ourstatus->kind = TARGET_WAITKIND_STOPPED; - - switch (code) - { - case EXCEPTION_ACCESS_VIOLATION: - OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION")); - ourstatus->value.sig = GDB_SIGNAL_SEGV; - break; - case STATUS_STACK_OVERFLOW: - OUTMSG2 (("STATUS_STACK_OVERFLOW")); - ourstatus->value.sig = GDB_SIGNAL_SEGV; - break; - case STATUS_FLOAT_DENORMAL_OPERAND: - OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_FLOAT_INEXACT_RESULT: - OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_FLOAT_INVALID_OPERATION: - OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_FLOAT_OVERFLOW: - OUTMSG2 (("STATUS_FLOAT_OVERFLOW")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_FLOAT_STACK_CHECK: - OUTMSG2 (("STATUS_FLOAT_STACK_CHECK")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_FLOAT_UNDERFLOW: - OUTMSG2 (("STATUS_FLOAT_UNDERFLOW")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_FLOAT_DIVIDE_BY_ZERO: - OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_INTEGER_DIVIDE_BY_ZERO: - OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case STATUS_INTEGER_OVERFLOW: - OUTMSG2 (("STATUS_INTEGER_OVERFLOW")); - ourstatus->value.sig = GDB_SIGNAL_FPE; - break; - case EXCEPTION_BREAKPOINT: - OUTMSG2 (("EXCEPTION_BREAKPOINT")); - ourstatus->value.sig = GDB_SIGNAL_TRAP; -#ifdef _WIN32_WCE - /* Remove the initial breakpoint. */ - check_breakpoints ((CORE_ADDR) (long) current_event - .u.Exception.ExceptionRecord.ExceptionAddress); -#endif - break; - case DBG_CONTROL_C: - OUTMSG2 (("DBG_CONTROL_C")); - ourstatus->value.sig = GDB_SIGNAL_INT; - break; - case DBG_CONTROL_BREAK: - OUTMSG2 (("DBG_CONTROL_BREAK")); - ourstatus->value.sig = GDB_SIGNAL_INT; - break; - case EXCEPTION_SINGLE_STEP: - OUTMSG2 (("EXCEPTION_SINGLE_STEP")); - ourstatus->value.sig = GDB_SIGNAL_TRAP; - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION")); - ourstatus->value.sig = GDB_SIGNAL_ILL; - break; - case EXCEPTION_PRIV_INSTRUCTION: - OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION")); - ourstatus->value.sig = GDB_SIGNAL_ILL; - break; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION")); - ourstatus->value.sig = GDB_SIGNAL_ILL; - break; - default: - if (current_event.u.Exception.dwFirstChance) - { - ourstatus->kind = TARGET_WAITKIND_SPURIOUS; - return; - } - OUTMSG2 (("gdbserver: unknown target exception 0x%08x at 0x%s", - (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode, - phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord. - ExceptionAddress, sizeof (uintptr_t)))); - ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; - break; - } - OUTMSG2 (("\n")); - last_sig = ourstatus->value.sig; -} - - static void suspend_one_thread (thread_info *thread) { - win32_thread_info *th = (win32_thread_info *) thread_target_data (thread); + windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); - if (!th->suspended) - { - if (SuspendThread (th->h) == (DWORD) -1) - { - DWORD err = GetLastError (); - OUTMSG (("warning: SuspendThread failed in suspend_one_thread, " - "(error %d): %s\n", (int) err, strwinerror (err))); - } - else - th->suspended = 1; - } + th->suspend (); } static void @@ -1388,15 +1186,51 @@ auto_delete_breakpoint (CORE_ADDR stop_pc) } #endif +/* See nat/windows-nat.h. */ + +bool +windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec) +{ + return false; +} + +/* A helper function that will, if needed, set + 'stopped_at_software_breakpoint' on the thread and adjust the + PC. */ + +static void +maybe_adjust_pc () +{ + struct regcache *regcache = get_thread_regcache (current_thread, 1); + child_fetch_inferior_registers (regcache, -1); + + windows_thread_info *th = thread_rec (current_thread_ptid (), + DONT_INVALIDATE_CONTEXT); + th->stopped_at_software_breakpoint = false; + + if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT + && (current_event.u.Exception.ExceptionRecord.ExceptionCode + == EXCEPTION_BREAKPOINT) + && child_initialization_done) + { + th->stopped_at_software_breakpoint = true; + CORE_ADDR pc = regcache_read_pc (regcache); + CORE_ADDR sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break; + regcache_write_pc (regcache, sw_breakpoint_pc); + } +} + /* Get the next event from the child. */ static int -get_child_debug_event (struct target_waitstatus *ourstatus) +get_child_debug_event (DWORD *continue_status, + struct target_waitstatus *ourstatus) { ptid_t ptid; last_sig = GDB_SIGNAL_0; ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + *continue_status = DBG_CONTINUE; /* Check if GDB sent us an interrupt request. */ check_remote_input_interrupt_request (); @@ -1428,7 +1262,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus) happen is the user will see a spurious breakpoint. */ current_event.dwDebugEventCode = 0; - if (!WaitForDebugEvent (¤t_event, 0)) + if (!wait_for_debug_event (¤t_event, 0)) { OUTMSG2(("no attach events left\n")); fake_breakpoint_event (); @@ -1443,7 +1277,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus) /* Keep the wait time low enough for comfortable remote interruption, but high enough so gdbserver doesn't become a bottleneck. */ - if (!WaitForDebugEvent (¤t_event, 250)) + if (!wait_for_debug_event (¤t_event, 250)) { DWORD e = GetLastError(); @@ -1579,7 +1413,9 @@ get_child_debug_event (struct target_waitstatus *ourstatus) "for pid=%u tid=%x\n", (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId)); - handle_exception (ourstatus); + if (handle_exception (ourstatus, debug_threads) + == HANDLE_EXCEPTION_UNHANDLED) + *continue_status = DBG_EXCEPTION_NOT_HANDLED; break; case OUTPUT_DEBUG_STRING_EVENT: @@ -1588,7 +1424,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus) "for pid=%u tid=%x\n", (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId)); - handle_output_debug_string (); + handle_output_debug_string (nullptr); break; default: @@ -1612,8 +1448,6 @@ ptid_t win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, int options) { - struct regcache *regcache; - if (cached_status.kind != TARGET_WAITKIND_IGNORE) { /* The core always does a wait after creating the inferior, and @@ -1627,7 +1461,8 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, while (1) { - if (!get_child_debug_event (ourstatus)) + DWORD continue_status; + if (!get_child_debug_event (&continue_status, ourstatus)) continue; switch (ourstatus->kind) @@ -1640,18 +1475,18 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, case TARGET_WAITKIND_STOPPED: case TARGET_WAITKIND_SIGNALLED: case TARGET_WAITKIND_LOADED: - OUTMSG2 (("Child Stopped with signal = %d \n", - ourstatus->value.sig)); - - regcache = get_thread_regcache (current_thread, 1); - child_fetch_inferior_registers (regcache, -1); - return debug_event_ptid (¤t_event); + { + OUTMSG2 (("Child Stopped with signal = %d \n", + ourstatus->value.sig)); + maybe_adjust_pc (); + return debug_event_ptid (¤t_event); + } default: OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind)); /* fall-through */ case TARGET_WAITKIND_SPURIOUS: /* do nothing, just continue */ - child_continue (DBG_CONTINUE, -1); + child_continue (continue_status, -1); break; } } @@ -1824,13 +1659,19 @@ win32_process_target::qxfer_siginfo (const char *annex, return len; } +bool +win32_process_target::supports_get_tib_address () +{ + return true; +} + /* Write Windows OS Thread Information Block address. */ -static int -win32_get_tib_address (ptid_t ptid, CORE_ADDR *addr) +int +win32_process_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr) { - win32_thread_info *th; - th = thread_rec (ptid, 0); + windows_thread_info *th; + th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT); if (th == NULL) return 0; if (addr != NULL) @@ -1840,68 +1681,47 @@ win32_get_tib_address (ptid_t ptid, CORE_ADDR *addr) /* Implementation of the target_ops method "sw_breakpoint_from_kind". */ -static const gdb_byte * -win32_sw_breakpoint_from_kind (int kind, int *size) +const gdb_byte * +win32_process_target::sw_breakpoint_from_kind (int kind, int *size) { *size = the_low_target.breakpoint_len; return the_low_target.breakpoint; } +bool +win32_process_target::stopped_by_sw_breakpoint () +{ + windows_thread_info *th = thread_rec (current_thread_ptid (), + DONT_INVALIDATE_CONTEXT); + return th == nullptr ? false : th->stopped_at_software_breakpoint; +} + +bool +win32_process_target::supports_stopped_by_sw_breakpoint () +{ + return true; +} + +CORE_ADDR +win32_process_target::read_pc (struct regcache *regcache) +{ + return (*the_low_target.get_pc) (regcache); +} + +void +win32_process_target::write_pc (struct regcache *regcache, CORE_ADDR pc) +{ + return (*the_low_target.set_pc) (regcache, pc); +} + /* The win32 target ops object. */ static win32_process_target the_win32_target; -static process_stratum_target win32_target_ops = { - NULL, /* supports_non_stop */ - NULL, /* async */ - NULL, /* start_non_stop */ - NULL, /* supports_multi_process */ - NULL, /* supports_fork_events */ - NULL, /* supports_vfork_events */ - NULL, /* supports_exec_events */ - NULL, /* handle_new_gdb_connection */ - NULL, /* handle_monitor_command */ - NULL, /* core_of_thread */ - NULL, /* read_loadmap */ - NULL, /* process_qsupported */ - NULL, /* supports_tracepoints */ - NULL, /* read_pc */ - NULL, /* write_pc */ - NULL, /* thread_stopped */ - win32_get_tib_address, - NULL, /* pause_all */ - NULL, /* unpause_all */ - NULL, /* stabilize_threads */ - NULL, /* install_fast_tracepoint_jump_pad */ - NULL, /* emit_ops */ - NULL, /* supports_disable_randomization */ - NULL, /* get_min_fast_tracepoint_insn_len */ - NULL, /* qxfer_libraries_svr4 */ - NULL, /* support_agent */ - NULL, /* enable_btrace */ - NULL, /* disable_btrace */ - NULL, /* read_btrace */ - NULL, /* read_btrace_conf */ - NULL, /* supports_range_stepping */ - NULL, /* pid_to_exec_file */ - NULL, /* multifs_open */ - NULL, /* multifs_unlink */ - NULL, /* multifs_readlink */ - NULL, /* breakpoint_kind_from_pc */ - win32_sw_breakpoint_from_kind, - NULL, /* thread_name */ - NULL, /* breakpoint_kind_from_current_state */ - NULL, /* supports_software_single_step */ - NULL, /* supports_catch_syscall */ - NULL, /* get_ipa_tdesc_idx */ - NULL, /* thread_handle */ - &the_win32_target, -}; - /* Initialize the Win32 backend. */ void initialize_low (void) { - set_target_ops (&win32_target_ops); + set_target_ops (&the_win32_target); the_low_target.arch_setup (); }