18dffb485Schristos /* Low level interface to Windows debugging, for gdbserver. 2*13ed34faSchristos Copyright (C) 2006-2024 Free Software Foundation, Inc. 38dffb485Schristos 48dffb485Schristos Contributed by Leo Zayas. Based on "win32-nat.c" from GDB. 58dffb485Schristos 68dffb485Schristos This file is part of GDB. 78dffb485Schristos 88dffb485Schristos This program is free software; you can redistribute it and/or modify 98dffb485Schristos it under the terms of the GNU General Public License as published by 108dffb485Schristos the Free Software Foundation; either version 3 of the License, or 118dffb485Schristos (at your option) any later version. 128dffb485Schristos 138dffb485Schristos This program is distributed in the hope that it will be useful, 148dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 158dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 168dffb485Schristos GNU General Public License for more details. 178dffb485Schristos 188dffb485Schristos You should have received a copy of the GNU General Public License 198dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 208dffb485Schristos 218dffb485Schristos #include "regcache.h" 224b169a6bSchristos #include "gdbsupport/fileio.h" 238dffb485Schristos #include "mem-break.h" 248dffb485Schristos #include "win32-low.h" 258dffb485Schristos #include "gdbthread.h" 268dffb485Schristos #include "dll.h" 278dffb485Schristos #include "hostio.h" 288dffb485Schristos #include <windows.h> 298dffb485Schristos #include <winnt.h> 308dffb485Schristos #include <imagehlp.h> 318dffb485Schristos #include <tlhelp32.h> 328dffb485Schristos #include <psapi.h> 338dffb485Schristos #include <process.h> 348dffb485Schristos #include "gdbsupport/gdb_tilde_expand.h" 358dffb485Schristos #include "gdbsupport/common-inferior.h" 368dffb485Schristos #include "gdbsupport/gdb_wait.h" 378dffb485Schristos 388dffb485Schristos using namespace windows_nat; 398dffb485Schristos 404b169a6bSchristos /* See win32-low.h. */ 414b169a6bSchristos gdbserver_windows_process windows_process; 424b169a6bSchristos 438dffb485Schristos #ifndef USE_WIN32API 448dffb485Schristos #include <sys/cygwin.h> 458dffb485Schristos #endif 468dffb485Schristos 478dffb485Schristos #define OUTMSG(X) do { printf X; fflush (stderr); } while (0) 488dffb485Schristos 498dffb485Schristos #define OUTMSG2(X) \ 508dffb485Schristos do \ 518dffb485Schristos { \ 528dffb485Schristos if (debug_threads) \ 538dffb485Schristos { \ 548dffb485Schristos printf X; \ 558dffb485Schristos fflush (stderr); \ 568dffb485Schristos } \ 578dffb485Schristos } while (0) 588dffb485Schristos 598dffb485Schristos #ifndef _T 608dffb485Schristos #define _T(x) TEXT (x) 618dffb485Schristos #endif 628dffb485Schristos 638dffb485Schristos int using_threads = 1; 648dffb485Schristos 658dffb485Schristos const struct target_desc *win32_tdesc; 668dffb485Schristos #ifdef __x86_64__ 678dffb485Schristos const struct target_desc *wow64_win32_tdesc; 688dffb485Schristos #endif 698dffb485Schristos 708dffb485Schristos #define NUM_REGS (the_low_target.num_regs ()) 718dffb485Schristos 728dffb485Schristos /* Get the thread ID from the current selected inferior (the current 738dffb485Schristos thread). */ 748dffb485Schristos static ptid_t 758dffb485Schristos current_thread_ptid (void) 768dffb485Schristos { 778dffb485Schristos return current_ptid; 788dffb485Schristos } 798dffb485Schristos 808dffb485Schristos /* The current debug event from WaitForDebugEvent. */ 818dffb485Schristos static ptid_t 828dffb485Schristos debug_event_ptid (DEBUG_EVENT *event) 838dffb485Schristos { 848dffb485Schristos return ptid_t (event->dwProcessId, event->dwThreadId, 0); 858dffb485Schristos } 868dffb485Schristos 878dffb485Schristos /* Get the thread context of the thread associated with TH. */ 888dffb485Schristos 898dffb485Schristos static void 908dffb485Schristos win32_get_thread_context (windows_thread_info *th) 918dffb485Schristos { 928dffb485Schristos #ifdef __x86_64__ 934b169a6bSchristos if (windows_process.wow64_process) 948dffb485Schristos memset (&th->wow64_context, 0, sizeof (WOW64_CONTEXT)); 958dffb485Schristos else 968dffb485Schristos #endif 978dffb485Schristos memset (&th->context, 0, sizeof (CONTEXT)); 988dffb485Schristos (*the_low_target.get_thread_context) (th); 998dffb485Schristos } 1008dffb485Schristos 1018dffb485Schristos /* Set the thread context of the thread associated with TH. */ 1028dffb485Schristos 1038dffb485Schristos static void 1048dffb485Schristos win32_set_thread_context (windows_thread_info *th) 1058dffb485Schristos { 1068dffb485Schristos #ifdef __x86_64__ 1074b169a6bSchristos if (windows_process.wow64_process) 1084b169a6bSchristos Wow64SetThreadContext (th->h, &th->wow64_context); 1098dffb485Schristos else 1108dffb485Schristos #endif 1118dffb485Schristos SetThreadContext (th->h, &th->context); 1128dffb485Schristos } 1138dffb485Schristos 1148dffb485Schristos /* Set the thread context of the thread associated with TH. */ 1158dffb485Schristos 1168dffb485Schristos static void 1178dffb485Schristos win32_prepare_to_resume (windows_thread_info *th) 1188dffb485Schristos { 1198dffb485Schristos if (the_low_target.prepare_to_resume != NULL) 1208dffb485Schristos (*the_low_target.prepare_to_resume) (th); 1218dffb485Schristos } 1228dffb485Schristos 1238dffb485Schristos /* See win32-low.h. */ 1248dffb485Schristos 1258dffb485Schristos void 1268dffb485Schristos win32_require_context (windows_thread_info *th) 1278dffb485Schristos { 1288dffb485Schristos DWORD context_flags; 1298dffb485Schristos #ifdef __x86_64__ 1304b169a6bSchristos if (windows_process.wow64_process) 1318dffb485Schristos context_flags = th->wow64_context.ContextFlags; 1328dffb485Schristos else 1338dffb485Schristos #endif 1348dffb485Schristos context_flags = th->context.ContextFlags; 1358dffb485Schristos if (context_flags == 0) 1368dffb485Schristos { 1378dffb485Schristos th->suspend (); 1388dffb485Schristos win32_get_thread_context (th); 1398dffb485Schristos } 1408dffb485Schristos } 1418dffb485Schristos 1428dffb485Schristos /* See nat/windows-nat.h. */ 1438dffb485Schristos 1448dffb485Schristos windows_thread_info * 1454b169a6bSchristos gdbserver_windows_process::thread_rec 1464b169a6bSchristos (ptid_t ptid, thread_disposition_type disposition) 1478dffb485Schristos { 1488dffb485Schristos thread_info *thread = find_thread_ptid (ptid); 1498dffb485Schristos if (thread == NULL) 1508dffb485Schristos return NULL; 1518dffb485Schristos 1528dffb485Schristos windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); 1538dffb485Schristos if (disposition != DONT_INVALIDATE_CONTEXT) 1548dffb485Schristos win32_require_context (th); 1558dffb485Schristos return th; 1568dffb485Schristos } 1578dffb485Schristos 1588dffb485Schristos /* Add a thread to the thread list. */ 1598dffb485Schristos static windows_thread_info * 1608dffb485Schristos child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb) 1618dffb485Schristos { 1628dffb485Schristos windows_thread_info *th; 1638dffb485Schristos ptid_t ptid = ptid_t (pid, tid, 0); 1648dffb485Schristos 1654b169a6bSchristos if ((th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT))) 1668dffb485Schristos return th; 1678dffb485Schristos 1688dffb485Schristos CORE_ADDR base = (CORE_ADDR) (uintptr_t) tlb; 1698dffb485Schristos #ifdef __x86_64__ 1708dffb485Schristos /* For WOW64 processes, this is actually the pointer to the 64bit TIB, 1718dffb485Schristos and the 32bit TIB is exactly 2 pages after it. */ 1724b169a6bSchristos if (windows_process.wow64_process) 1738dffb485Schristos base += 2 * 4096; /* page size = 4096 */ 1748dffb485Schristos #endif 1758dffb485Schristos th = new windows_thread_info (tid, h, base); 1768dffb485Schristos 1778dffb485Schristos add_thread (ptid, th); 1788dffb485Schristos 1798dffb485Schristos if (the_low_target.thread_added != NULL) 1808dffb485Schristos (*the_low_target.thread_added) (th); 1818dffb485Schristos 1828dffb485Schristos return th; 1838dffb485Schristos } 1848dffb485Schristos 1858dffb485Schristos /* Delete a thread from the list of threads. */ 1868dffb485Schristos static void 1878dffb485Schristos delete_thread_info (thread_info *thread) 1888dffb485Schristos { 1898dffb485Schristos windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); 1908dffb485Schristos 1918dffb485Schristos remove_thread (thread); 1928dffb485Schristos delete th; 1938dffb485Schristos } 1948dffb485Schristos 1958dffb485Schristos /* Delete a thread from the list of threads. */ 1968dffb485Schristos static void 1978dffb485Schristos child_delete_thread (DWORD pid, DWORD tid) 1988dffb485Schristos { 1998dffb485Schristos /* If the last thread is exiting, just return. */ 2008dffb485Schristos if (all_threads.size () == 1) 2018dffb485Schristos return; 2028dffb485Schristos 2038dffb485Schristos thread_info *thread = find_thread_ptid (ptid_t (pid, tid)); 2048dffb485Schristos if (thread == NULL) 2058dffb485Schristos return; 2068dffb485Schristos 2078dffb485Schristos delete_thread_info (thread); 2088dffb485Schristos } 2098dffb485Schristos 2108dffb485Schristos /* These watchpoint related wrapper functions simply pass on the function call 2118dffb485Schristos if the low target has registered a corresponding function. */ 2128dffb485Schristos 2138dffb485Schristos bool 2148dffb485Schristos win32_process_target::supports_z_point_type (char z_type) 2158dffb485Schristos { 2168dffb485Schristos return (z_type == Z_PACKET_SW_BP 2178dffb485Schristos || (the_low_target.supports_z_point_type != NULL 2188dffb485Schristos && the_low_target.supports_z_point_type (z_type))); 2198dffb485Schristos } 2208dffb485Schristos 2218dffb485Schristos int 2228dffb485Schristos win32_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr, 2238dffb485Schristos int size, raw_breakpoint *bp) 2248dffb485Schristos { 2258dffb485Schristos if (type == raw_bkpt_type_sw) 2268dffb485Schristos return insert_memory_breakpoint (bp); 2278dffb485Schristos else if (the_low_target.insert_point != NULL) 2288dffb485Schristos return the_low_target.insert_point (type, addr, size, bp); 2298dffb485Schristos else 2308dffb485Schristos /* Unsupported (see target.h). */ 2318dffb485Schristos return 1; 2328dffb485Schristos } 2338dffb485Schristos 2348dffb485Schristos int 2358dffb485Schristos win32_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr, 2368dffb485Schristos int size, raw_breakpoint *bp) 2378dffb485Schristos { 2388dffb485Schristos if (type == raw_bkpt_type_sw) 2398dffb485Schristos return remove_memory_breakpoint (bp); 2408dffb485Schristos else if (the_low_target.remove_point != NULL) 2418dffb485Schristos return the_low_target.remove_point (type, addr, size, bp); 2428dffb485Schristos else 2438dffb485Schristos /* Unsupported (see target.h). */ 2448dffb485Schristos return 1; 2458dffb485Schristos } 2468dffb485Schristos 2478dffb485Schristos bool 2488dffb485Schristos win32_process_target::stopped_by_watchpoint () 2498dffb485Schristos { 2508dffb485Schristos if (the_low_target.stopped_by_watchpoint != NULL) 2518dffb485Schristos return the_low_target.stopped_by_watchpoint (); 2528dffb485Schristos else 2538dffb485Schristos return false; 2548dffb485Schristos } 2558dffb485Schristos 2568dffb485Schristos CORE_ADDR 2578dffb485Schristos win32_process_target::stopped_data_address () 2588dffb485Schristos { 2598dffb485Schristos if (the_low_target.stopped_data_address != NULL) 2608dffb485Schristos return the_low_target.stopped_data_address (); 2618dffb485Schristos else 2628dffb485Schristos return 0; 2638dffb485Schristos } 2648dffb485Schristos 2658dffb485Schristos 2668dffb485Schristos /* Transfer memory from/to the debugged process. */ 2678dffb485Schristos static int 2688dffb485Schristos child_xfer_memory (CORE_ADDR memaddr, char *our, int len, 2698dffb485Schristos int write, process_stratum_target *target) 2708dffb485Schristos { 2718dffb485Schristos BOOL success; 2728dffb485Schristos SIZE_T done = 0; 2738dffb485Schristos DWORD lasterror = 0; 2748dffb485Schristos uintptr_t addr = (uintptr_t) memaddr; 2758dffb485Schristos 2768dffb485Schristos if (write) 2778dffb485Schristos { 2784b169a6bSchristos success = WriteProcessMemory (windows_process.handle, (LPVOID) addr, 2798dffb485Schristos (LPCVOID) our, len, &done); 2808dffb485Schristos if (!success) 2818dffb485Schristos lasterror = GetLastError (); 2824b169a6bSchristos FlushInstructionCache (windows_process.handle, (LPCVOID) addr, len); 2838dffb485Schristos } 2848dffb485Schristos else 2858dffb485Schristos { 2864b169a6bSchristos success = ReadProcessMemory (windows_process.handle, (LPCVOID) addr, 2878dffb485Schristos (LPVOID) our, len, &done); 2888dffb485Schristos if (!success) 2898dffb485Schristos lasterror = GetLastError (); 2908dffb485Schristos } 2918dffb485Schristos if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0) 2928dffb485Schristos return done; 2938dffb485Schristos else 2948dffb485Schristos return success ? done : -1; 2958dffb485Schristos } 2968dffb485Schristos 2978dffb485Schristos /* Clear out any old thread list and reinitialize it to a pristine 2988dffb485Schristos state. */ 2998dffb485Schristos static void 3008dffb485Schristos child_init_thread_list (void) 3018dffb485Schristos { 3028dffb485Schristos for_each_thread (delete_thread_info); 3038dffb485Schristos } 3048dffb485Schristos 3058dffb485Schristos static void 3068dffb485Schristos do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) 3078dffb485Schristos { 3088dffb485Schristos struct process_info *proc; 3098dffb485Schristos 3104b169a6bSchristos windows_process.last_sig = GDB_SIGNAL_0; 3114b169a6bSchristos windows_process.handle = proch; 3124b169a6bSchristos windows_process.main_thread_id = 0; 3138dffb485Schristos 3144b169a6bSchristos windows_process.soft_interrupt_requested = 0; 3154b169a6bSchristos windows_process.faked_breakpoint = 0; 3164b169a6bSchristos windows_process.open_process_used = true; 3178dffb485Schristos 3184b169a6bSchristos memset (&windows_process.current_event, 0, 3194b169a6bSchristos sizeof (windows_process.current_event)); 3208dffb485Schristos 3218dffb485Schristos #ifdef __x86_64__ 3228dffb485Schristos BOOL wow64; 3238dffb485Schristos if (!IsWow64Process (proch, &wow64)) 3248dffb485Schristos { 3258dffb485Schristos DWORD err = GetLastError (); 326*13ed34faSchristos throw_winerror_with_name ("Check if WOW64 process failed", err); 3278dffb485Schristos } 3284b169a6bSchristos windows_process.wow64_process = wow64; 3298dffb485Schristos 3304b169a6bSchristos if (windows_process.wow64_process 3314b169a6bSchristos && (Wow64GetThreadContext == nullptr 3324b169a6bSchristos || Wow64SetThreadContext == nullptr)) 3338dffb485Schristos error ("WOW64 debugging is not supported on this system.\n"); 3348dffb485Schristos 3354b169a6bSchristos windows_process.ignore_first_breakpoint 3364b169a6bSchristos = !attached && windows_process.wow64_process; 3378dffb485Schristos #endif 3388dffb485Schristos 3398dffb485Schristos proc = add_process (pid, attached); 3408dffb485Schristos #ifdef __x86_64__ 3414b169a6bSchristos if (windows_process.wow64_process) 3428dffb485Schristos proc->tdesc = wow64_win32_tdesc; 3438dffb485Schristos else 3448dffb485Schristos #endif 3458dffb485Schristos proc->tdesc = win32_tdesc; 3468dffb485Schristos child_init_thread_list (); 3474b169a6bSchristos windows_process.child_initialization_done = 0; 3488dffb485Schristos 3498dffb485Schristos if (the_low_target.initial_stuff != NULL) 3508dffb485Schristos (*the_low_target.initial_stuff) (); 3518dffb485Schristos 3524b169a6bSchristos windows_process.cached_status.set_ignore (); 3538dffb485Schristos 3548dffb485Schristos /* Flush all currently pending debug events (thread and dll list) up 3558dffb485Schristos to the initial breakpoint. */ 3568dffb485Schristos while (1) 3578dffb485Schristos { 3588dffb485Schristos struct target_waitstatus status; 3598dffb485Schristos 3608dffb485Schristos the_target->wait (minus_one_ptid, &status, 0); 3618dffb485Schristos 3628dffb485Schristos /* Note win32_wait doesn't return thread events. */ 3634b169a6bSchristos if (status.kind () != TARGET_WAITKIND_LOADED) 3648dffb485Schristos { 3654b169a6bSchristos windows_process.cached_status = status; 3668dffb485Schristos break; 3678dffb485Schristos } 3688dffb485Schristos 3698dffb485Schristos { 3708dffb485Schristos struct thread_resume resume; 3718dffb485Schristos 3728dffb485Schristos resume.thread = minus_one_ptid; 3738dffb485Schristos resume.kind = resume_continue; 3748dffb485Schristos resume.sig = 0; 3758dffb485Schristos 3768dffb485Schristos the_target->resume (&resume, 1); 3778dffb485Schristos } 3788dffb485Schristos } 3798dffb485Schristos 3808dffb485Schristos /* Now that the inferior has been started and all DLLs have been mapped, 3818dffb485Schristos we can iterate over all DLLs and load them in. 3828dffb485Schristos 3838dffb485Schristos We avoid doing it any earlier because, on certain versions of Windows, 3848dffb485Schristos LOAD_DLL_DEBUG_EVENTs are sometimes not complete. In particular, 3858dffb485Schristos we have seen on Windows 8.1 that the ntdll.dll load event does not 3868dffb485Schristos include the DLL name, preventing us from creating an associated SO. 3878dffb485Schristos A possible explanation is that ntdll.dll might be mapped before 3888dffb485Schristos the SO info gets created by the Windows system -- ntdll.dll is 3898dffb485Schristos the first DLL to be reported via LOAD_DLL_DEBUG_EVENT and other DLLs 3908dffb485Schristos do not seem to suffer from that problem. 3918dffb485Schristos 3928dffb485Schristos Rather than try to work around this sort of issue, it is much 3938dffb485Schristos simpler to just ignore DLL load/unload events during the startup 3948dffb485Schristos phase, and then process them all in one batch now. */ 3954b169a6bSchristos windows_process.add_all_dlls (); 3968dffb485Schristos 3974b169a6bSchristos windows_process.child_initialization_done = 1; 3988dffb485Schristos } 3998dffb485Schristos 4008dffb485Schristos /* Resume all artificially suspended threads if we are continuing 4018dffb485Schristos execution. */ 4028dffb485Schristos static void 4038dffb485Schristos continue_one_thread (thread_info *thread, int thread_id) 4048dffb485Schristos { 4058dffb485Schristos windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); 4068dffb485Schristos 4078dffb485Schristos if (thread_id == -1 || thread_id == th->tid) 4088dffb485Schristos { 4098dffb485Schristos win32_prepare_to_resume (th); 4108dffb485Schristos 4118dffb485Schristos if (th->suspended) 4128dffb485Schristos { 4138dffb485Schristos DWORD *context_flags; 4148dffb485Schristos #ifdef __x86_64__ 4154b169a6bSchristos if (windows_process.wow64_process) 4168dffb485Schristos context_flags = &th->wow64_context.ContextFlags; 4178dffb485Schristos else 4188dffb485Schristos #endif 4198dffb485Schristos context_flags = &th->context.ContextFlags; 4208dffb485Schristos if (*context_flags) 4218dffb485Schristos { 4228dffb485Schristos win32_set_thread_context (th); 4238dffb485Schristos *context_flags = 0; 4248dffb485Schristos } 4258dffb485Schristos 4268dffb485Schristos th->resume (); 4278dffb485Schristos } 4288dffb485Schristos } 4298dffb485Schristos } 4308dffb485Schristos 4318dffb485Schristos static BOOL 4328dffb485Schristos child_continue (DWORD continue_status, int thread_id) 4338dffb485Schristos { 4344b169a6bSchristos windows_process.desired_stop_thread_id = thread_id; 4354b169a6bSchristos if (windows_process.matching_pending_stop (debug_threads)) 4368dffb485Schristos return TRUE; 4378dffb485Schristos 4388dffb485Schristos /* The inferior will only continue after the ContinueDebugEvent 4398dffb485Schristos call. */ 4408dffb485Schristos for_each_thread ([&] (thread_info *thread) 4418dffb485Schristos { 4428dffb485Schristos continue_one_thread (thread, thread_id); 4438dffb485Schristos }); 4444b169a6bSchristos windows_process.faked_breakpoint = 0; 4458dffb485Schristos 4468dffb485Schristos return continue_last_debug_event (continue_status, debug_threads); 4478dffb485Schristos } 4488dffb485Schristos 4498dffb485Schristos /* Fetch register(s) from the current thread context. */ 4508dffb485Schristos static void 4518dffb485Schristos child_fetch_inferior_registers (struct regcache *regcache, int r) 4528dffb485Schristos { 4538dffb485Schristos int regno; 4544b169a6bSchristos windows_thread_info *th 4554b169a6bSchristos = windows_process.thread_rec (current_thread_ptid (), 4568dffb485Schristos INVALIDATE_CONTEXT); 4578dffb485Schristos if (r == -1 || r > NUM_REGS) 4588dffb485Schristos child_fetch_inferior_registers (regcache, NUM_REGS); 4598dffb485Schristos else 4608dffb485Schristos for (regno = 0; regno < r; regno++) 4618dffb485Schristos (*the_low_target.fetch_inferior_register) (regcache, th, regno); 4628dffb485Schristos } 4638dffb485Schristos 4648dffb485Schristos /* Store a new register value into the current thread context. We don't 4658dffb485Schristos change the program's context until later, when we resume it. */ 4668dffb485Schristos static void 4678dffb485Schristos child_store_inferior_registers (struct regcache *regcache, int r) 4688dffb485Schristos { 4698dffb485Schristos int regno; 4704b169a6bSchristos windows_thread_info *th 4714b169a6bSchristos = windows_process.thread_rec (current_thread_ptid (), 4728dffb485Schristos INVALIDATE_CONTEXT); 4738dffb485Schristos if (r == -1 || r == 0 || r > NUM_REGS) 4748dffb485Schristos child_store_inferior_registers (regcache, NUM_REGS); 4758dffb485Schristos else 4768dffb485Schristos for (regno = 0; regno < r; regno++) 4778dffb485Schristos (*the_low_target.store_inferior_register) (regcache, th, regno); 4788dffb485Schristos } 4798dffb485Schristos 4808dffb485Schristos static BOOL 4818dffb485Schristos create_process (const char *program, char *args, 4828dffb485Schristos DWORD flags, PROCESS_INFORMATION *pi) 4838dffb485Schristos { 4844b169a6bSchristos const std::string &inferior_cwd = get_inferior_cwd (); 4858dffb485Schristos BOOL ret; 4868dffb485Schristos size_t argslen, proglen; 4878dffb485Schristos 4888dffb485Schristos proglen = strlen (program) + 1; 4898dffb485Schristos argslen = strlen (args) + proglen; 4908dffb485Schristos 4918dffb485Schristos STARTUPINFOA si = { sizeof (STARTUPINFOA) }; 4928dffb485Schristos char *program_and_args = (char *) alloca (argslen + 1); 4938dffb485Schristos 4948dffb485Schristos strcpy (program_and_args, program); 4958dffb485Schristos strcat (program_and_args, " "); 4968dffb485Schristos strcat (program_and_args, args); 4974b169a6bSchristos ret = create_process (program, /* image name */ 4988dffb485Schristos program_and_args, /* command line */ 4998dffb485Schristos flags, /* start flags */ 5008dffb485Schristos NULL, /* environment */ 5018dffb485Schristos /* current directory */ 5024b169a6bSchristos (inferior_cwd.empty () 5038dffb485Schristos ? NULL 5044b169a6bSchristos : gdb_tilde_expand (inferior_cwd.c_str ()).c_str()), 5054b169a6bSchristos get_client_state ().disable_randomization, 5068dffb485Schristos &si, /* start info */ 5078dffb485Schristos pi); /* proc info */ 5088dffb485Schristos 5098dffb485Schristos return ret; 5108dffb485Schristos } 5118dffb485Schristos 5128dffb485Schristos /* Start a new process. 5138dffb485Schristos PROGRAM is the program name. 5148dffb485Schristos PROGRAM_ARGS is the vector containing the inferior's args. 5158dffb485Schristos Returns the new PID on success, -1 on failure. Registers the new 5168dffb485Schristos process with the process list. */ 5178dffb485Schristos int 5188dffb485Schristos win32_process_target::create_inferior (const char *program, 5198dffb485Schristos const std::vector<char *> &program_args) 5208dffb485Schristos { 5218dffb485Schristos client_state &cs = get_client_state (); 5228dffb485Schristos #ifndef USE_WIN32API 5238dffb485Schristos char real_path[PATH_MAX]; 5248dffb485Schristos char *orig_path, *new_path, *path_ptr; 5258dffb485Schristos #endif 5268dffb485Schristos BOOL ret; 5278dffb485Schristos DWORD flags; 5288dffb485Schristos PROCESS_INFORMATION pi; 5298dffb485Schristos DWORD err; 5308dffb485Schristos std::string str_program_args = construct_inferior_arguments (program_args); 5318dffb485Schristos char *args = (char *) str_program_args.c_str (); 5328dffb485Schristos 5338dffb485Schristos /* win32_wait needs to know we're not attaching. */ 5344b169a6bSchristos windows_process.attaching = 0; 5358dffb485Schristos 5368dffb485Schristos if (!program) 5378dffb485Schristos error ("No executable specified, specify executable to debug.\n"); 5388dffb485Schristos 5398dffb485Schristos flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS; 5408dffb485Schristos 5418dffb485Schristos #ifndef USE_WIN32API 5428dffb485Schristos orig_path = NULL; 5438dffb485Schristos path_ptr = getenv ("PATH"); 5448dffb485Schristos if (path_ptr) 5458dffb485Schristos { 5468dffb485Schristos int size = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, NULL, 0); 5478dffb485Schristos orig_path = (char *) alloca (strlen (path_ptr) + 1); 5488dffb485Schristos new_path = (char *) alloca (size); 5498dffb485Schristos strcpy (orig_path, path_ptr); 5508dffb485Schristos cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, new_path, size); 5518dffb485Schristos setenv ("PATH", new_path, 1); 5528dffb485Schristos } 5538dffb485Schristos cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path, PATH_MAX); 5548dffb485Schristos program = real_path; 5558dffb485Schristos #endif 5568dffb485Schristos 5578dffb485Schristos OUTMSG2 (("Command line is \"%s %s\"\n", program, args)); 5588dffb485Schristos 5598dffb485Schristos #ifdef CREATE_NEW_PROCESS_GROUP 5608dffb485Schristos flags |= CREATE_NEW_PROCESS_GROUP; 5618dffb485Schristos #endif 5628dffb485Schristos 5638dffb485Schristos ret = create_process (program, args, flags, &pi); 5648dffb485Schristos err = GetLastError (); 5658dffb485Schristos if (!ret && err == ERROR_FILE_NOT_FOUND) 5668dffb485Schristos { 5678dffb485Schristos char *exename = (char *) alloca (strlen (program) + 5); 5688dffb485Schristos strcat (strcpy (exename, program), ".exe"); 5698dffb485Schristos ret = create_process (exename, args, flags, &pi); 5708dffb485Schristos err = GetLastError (); 5718dffb485Schristos } 5728dffb485Schristos 5738dffb485Schristos #ifndef USE_WIN32API 5748dffb485Schristos if (orig_path) 5758dffb485Schristos setenv ("PATH", orig_path, 1); 5768dffb485Schristos #endif 5778dffb485Schristos 5788dffb485Schristos if (!ret) 5798dffb485Schristos { 580*13ed34faSchristos std::string msg = string_printf (_("Error creating process \"%s %s\""), 581*13ed34faSchristos program, args); 582*13ed34faSchristos throw_winerror_with_name (msg.c_str (), err); 5838dffb485Schristos } 5848dffb485Schristos else 5858dffb485Schristos { 5868dffb485Schristos OUTMSG2 (("Process created: %s %s\n", program, (char *) args)); 5878dffb485Schristos } 5888dffb485Schristos 5898dffb485Schristos CloseHandle (pi.hThread); 5908dffb485Schristos 5918dffb485Schristos do_initial_child_stuff (pi.hProcess, pi.dwProcessId, 0); 5928dffb485Schristos 5938dffb485Schristos /* Wait till we are at 1st instruction in program, return new pid 5948dffb485Schristos (assuming success). */ 5954b169a6bSchristos cs.last_ptid = wait (ptid_t (pi.dwProcessId), &cs.last_status, 0); 5968dffb485Schristos 5978dffb485Schristos /* Necessary for handle_v_kill. */ 5984b169a6bSchristos signal_pid = pi.dwProcessId; 5998dffb485Schristos 6004b169a6bSchristos return pi.dwProcessId; 6018dffb485Schristos } 6028dffb485Schristos 6038dffb485Schristos /* Attach to a running process. 6048dffb485Schristos PID is the process ID to attach to, specified by the user 6058dffb485Schristos or a higher layer. */ 6068dffb485Schristos int 6078dffb485Schristos win32_process_target::attach (unsigned long pid) 6088dffb485Schristos { 6098dffb485Schristos HANDLE h; 6108dffb485Schristos DWORD err; 6118dffb485Schristos 6128dffb485Schristos h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); 6138dffb485Schristos if (h != NULL) 6148dffb485Schristos { 6158dffb485Schristos if (DebugActiveProcess (pid)) 6168dffb485Schristos { 6178dffb485Schristos DebugSetProcessKillOnExit (FALSE); 6188dffb485Schristos 6198dffb485Schristos /* win32_wait needs to know we're attaching. */ 6204b169a6bSchristos windows_process.attaching = 1; 6218dffb485Schristos do_initial_child_stuff (h, pid, 1); 6228dffb485Schristos return 0; 6238dffb485Schristos } 6248dffb485Schristos 6258dffb485Schristos CloseHandle (h); 6268dffb485Schristos } 6278dffb485Schristos 6288dffb485Schristos err = GetLastError (); 629*13ed34faSchristos throw_winerror_with_name ("Attach to process failed", err); 6308dffb485Schristos } 6318dffb485Schristos 6328dffb485Schristos /* See nat/windows-nat.h. */ 6338dffb485Schristos 6348dffb485Schristos int 6354b169a6bSchristos gdbserver_windows_process::handle_output_debug_string 6364b169a6bSchristos (struct target_waitstatus *ourstatus) 6378dffb485Schristos { 6388dffb485Schristos #define READ_BUFFER_LEN 1024 6398dffb485Schristos CORE_ADDR addr; 6408dffb485Schristos char s[READ_BUFFER_LEN + 1] = { 0 }; 6418dffb485Schristos DWORD nbytes = current_event.u.DebugString.nDebugStringLength; 6428dffb485Schristos 6438dffb485Schristos if (nbytes == 0) 6448dffb485Schristos return 0; 6458dffb485Schristos 6468dffb485Schristos if (nbytes > READ_BUFFER_LEN) 6478dffb485Schristos nbytes = READ_BUFFER_LEN; 6488dffb485Schristos 6498dffb485Schristos addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData; 6508dffb485Schristos 6518dffb485Schristos if (current_event.u.DebugString.fUnicode) 6528dffb485Schristos { 6538dffb485Schristos /* The event tells us how many bytes, not chars, even 6548dffb485Schristos in Unicode. */ 6558dffb485Schristos WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 }; 6568dffb485Schristos if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0) 6578dffb485Schristos return 0; 6588dffb485Schristos wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR)); 6598dffb485Schristos } 6608dffb485Schristos else 6618dffb485Schristos { 6628dffb485Schristos if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0) 6638dffb485Schristos return 0; 6648dffb485Schristos } 6658dffb485Schristos 6668dffb485Schristos if (!startswith (s, "cYg")) 6678dffb485Schristos { 6688dffb485Schristos if (!server_waiting) 6698dffb485Schristos { 6708dffb485Schristos OUTMSG2(("%s", s)); 6718dffb485Schristos return 0; 6728dffb485Schristos } 6738dffb485Schristos 6748dffb485Schristos monitor_output (s); 6758dffb485Schristos } 6768dffb485Schristos #undef READ_BUFFER_LEN 6778dffb485Schristos 6788dffb485Schristos return 0; 6798dffb485Schristos } 6808dffb485Schristos 6818dffb485Schristos static void 6828dffb485Schristos win32_clear_inferiors (void) 6838dffb485Schristos { 6844b169a6bSchristos if (windows_process.open_process_used) 6858dffb485Schristos { 6864b169a6bSchristos CloseHandle (windows_process.handle); 6874b169a6bSchristos windows_process.open_process_used = false; 6888dffb485Schristos } 6898dffb485Schristos 6908dffb485Schristos for_each_thread (delete_thread_info); 6914b169a6bSchristos windows_process.siginfo_er.ExceptionCode = 0; 6928dffb485Schristos clear_inferiors (); 6938dffb485Schristos } 6948dffb485Schristos 6958dffb485Schristos /* Implementation of target_ops::kill. */ 6968dffb485Schristos 6978dffb485Schristos int 6988dffb485Schristos win32_process_target::kill (process_info *process) 6998dffb485Schristos { 7004b169a6bSchristos TerminateProcess (windows_process.handle, 0); 7018dffb485Schristos for (;;) 7028dffb485Schristos { 7038dffb485Schristos if (!child_continue (DBG_CONTINUE, -1)) 7048dffb485Schristos break; 7054b169a6bSchristos if (!wait_for_debug_event (&windows_process.current_event, INFINITE)) 7068dffb485Schristos break; 7074b169a6bSchristos if (windows_process.current_event.dwDebugEventCode 7084b169a6bSchristos == EXIT_PROCESS_DEBUG_EVENT) 7098dffb485Schristos break; 7104b169a6bSchristos else if (windows_process.current_event.dwDebugEventCode 7114b169a6bSchristos == OUTPUT_DEBUG_STRING_EVENT) 7124b169a6bSchristos windows_process.handle_output_debug_string (nullptr); 7138dffb485Schristos } 7148dffb485Schristos 7158dffb485Schristos win32_clear_inferiors (); 7168dffb485Schristos 7178dffb485Schristos remove_process (process); 7188dffb485Schristos return 0; 7198dffb485Schristos } 7208dffb485Schristos 7218dffb485Schristos /* Implementation of target_ops::detach. */ 7228dffb485Schristos 7238dffb485Schristos int 7248dffb485Schristos win32_process_target::detach (process_info *process) 7258dffb485Schristos { 7268dffb485Schristos struct thread_resume resume; 7278dffb485Schristos resume.thread = minus_one_ptid; 7288dffb485Schristos resume.kind = resume_continue; 7298dffb485Schristos resume.sig = 0; 7308dffb485Schristos this->resume (&resume, 1); 7318dffb485Schristos 7324b169a6bSchristos if (!DebugActiveProcessStop (process->pid)) 7338dffb485Schristos return -1; 7348dffb485Schristos 7358dffb485Schristos DebugSetProcessKillOnExit (FALSE); 736*13ed34faSchristos win32_clear_inferiors (); 7378dffb485Schristos remove_process (process); 7388dffb485Schristos 7398dffb485Schristos return 0; 7408dffb485Schristos } 7418dffb485Schristos 7428dffb485Schristos void 7438dffb485Schristos win32_process_target::mourn (struct process_info *process) 7448dffb485Schristos { 7458dffb485Schristos remove_process (process); 7468dffb485Schristos } 7478dffb485Schristos 7488dffb485Schristos /* Implementation of target_ops::join. */ 7498dffb485Schristos 7508dffb485Schristos void 7518dffb485Schristos win32_process_target::join (int pid) 7528dffb485Schristos { 7538dffb485Schristos HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); 7548dffb485Schristos if (h != NULL) 7558dffb485Schristos { 7568dffb485Schristos WaitForSingleObject (h, INFINITE); 7578dffb485Schristos CloseHandle (h); 7588dffb485Schristos } 7598dffb485Schristos } 7608dffb485Schristos 7618dffb485Schristos /* Return true iff the thread with thread ID TID is alive. */ 7628dffb485Schristos bool 7638dffb485Schristos win32_process_target::thread_alive (ptid_t ptid) 7648dffb485Schristos { 7658dffb485Schristos /* Our thread list is reliable; don't bother to poll target 7668dffb485Schristos threads. */ 7678dffb485Schristos return find_thread_ptid (ptid) != NULL; 7688dffb485Schristos } 7698dffb485Schristos 7708dffb485Schristos /* Resume the inferior process. RESUME_INFO describes how we want 7718dffb485Schristos to resume. */ 7728dffb485Schristos void 7738dffb485Schristos win32_process_target::resume (thread_resume *resume_info, size_t n) 7748dffb485Schristos { 7758dffb485Schristos DWORD tid; 7768dffb485Schristos enum gdb_signal sig; 7778dffb485Schristos int step; 7788dffb485Schristos windows_thread_info *th; 7798dffb485Schristos DWORD continue_status = DBG_CONTINUE; 7808dffb485Schristos ptid_t ptid; 7818dffb485Schristos 7828dffb485Schristos /* This handles the very limited set of resume packets that GDB can 7838dffb485Schristos currently produce. */ 7848dffb485Schristos 7858dffb485Schristos if (n == 1 && resume_info[0].thread == minus_one_ptid) 7868dffb485Schristos tid = -1; 7878dffb485Schristos else if (n > 1) 7888dffb485Schristos tid = -1; 7898dffb485Schristos else 7908dffb485Schristos /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make 7918dffb485Schristos the Windows resume code do the right thing for thread switching. */ 7924b169a6bSchristos tid = windows_process.current_event.dwThreadId; 7938dffb485Schristos 7948dffb485Schristos if (resume_info[0].thread != minus_one_ptid) 7958dffb485Schristos { 7968dffb485Schristos sig = gdb_signal_from_host (resume_info[0].sig); 7978dffb485Schristos step = resume_info[0].kind == resume_step; 7988dffb485Schristos } 7998dffb485Schristos else 8008dffb485Schristos { 8018dffb485Schristos sig = GDB_SIGNAL_0; 8028dffb485Schristos step = 0; 8038dffb485Schristos } 8048dffb485Schristos 8058dffb485Schristos if (sig != GDB_SIGNAL_0) 8068dffb485Schristos { 8074b169a6bSchristos if (windows_process.current_event.dwDebugEventCode 8084b169a6bSchristos != EXCEPTION_DEBUG_EVENT) 8098dffb485Schristos { 8108dffb485Schristos OUTMSG (("Cannot continue with signal %s here.\n", 8118dffb485Schristos gdb_signal_to_string (sig))); 8128dffb485Schristos } 8134b169a6bSchristos else if (sig == windows_process.last_sig) 8148dffb485Schristos continue_status = DBG_EXCEPTION_NOT_HANDLED; 8158dffb485Schristos else 8168dffb485Schristos OUTMSG (("Can only continue with received signal %s.\n", 8174b169a6bSchristos gdb_signal_to_string (windows_process.last_sig))); 8188dffb485Schristos } 8198dffb485Schristos 8204b169a6bSchristos windows_process.last_sig = GDB_SIGNAL_0; 8218dffb485Schristos 8228dffb485Schristos /* Get context for the currently selected thread. */ 8234b169a6bSchristos ptid = debug_event_ptid (&windows_process.current_event); 8244b169a6bSchristos th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT); 8258dffb485Schristos if (th) 8268dffb485Schristos { 8278dffb485Schristos win32_prepare_to_resume (th); 8288dffb485Schristos 8298dffb485Schristos DWORD *context_flags; 8308dffb485Schristos #ifdef __x86_64__ 8314b169a6bSchristos if (windows_process.wow64_process) 8328dffb485Schristos context_flags = &th->wow64_context.ContextFlags; 8338dffb485Schristos else 8348dffb485Schristos #endif 8358dffb485Schristos context_flags = &th->context.ContextFlags; 8368dffb485Schristos if (*context_flags) 8378dffb485Schristos { 8388dffb485Schristos /* Move register values from the inferior into the thread 8398dffb485Schristos context structure. */ 8408dffb485Schristos regcache_invalidate (); 8418dffb485Schristos 8428dffb485Schristos if (step) 8438dffb485Schristos { 8448dffb485Schristos if (the_low_target.single_step != NULL) 8458dffb485Schristos (*the_low_target.single_step) (th); 8468dffb485Schristos else 8478dffb485Schristos error ("Single stepping is not supported " 8488dffb485Schristos "in this configuration.\n"); 8498dffb485Schristos } 8508dffb485Schristos 8518dffb485Schristos win32_set_thread_context (th); 8528dffb485Schristos *context_flags = 0; 8538dffb485Schristos } 8548dffb485Schristos } 8558dffb485Schristos 8568dffb485Schristos /* Allow continuing with the same signal that interrupted us. 8578dffb485Schristos Otherwise complain. */ 8588dffb485Schristos 8598dffb485Schristos child_continue (continue_status, tid); 8608dffb485Schristos } 8618dffb485Schristos 8624b169a6bSchristos /* See nat/windows-nat.h. */ 8634b169a6bSchristos 8644b169a6bSchristos void 8654b169a6bSchristos gdbserver_windows_process::handle_load_dll (const char *name, LPVOID base) 8668dffb485Schristos { 8674b169a6bSchristos CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) base; 8684b169a6bSchristos 8698dffb485Schristos char buf[MAX_PATH + 1]; 8708dffb485Schristos char buf2[MAX_PATH + 1]; 8718dffb485Schristos 8728dffb485Schristos WIN32_FIND_DATAA w32_fd; 8738dffb485Schristos HANDLE h = FindFirstFileA (name, &w32_fd); 8748dffb485Schristos 8758dffb485Schristos /* The symbols in a dll are offset by 0x1000, which is the 8768dffb485Schristos offset from 0 of the first byte in an image - because 8778dffb485Schristos of the file header and the section alignment. */ 8788dffb485Schristos load_addr += 0x1000; 8798dffb485Schristos 8808dffb485Schristos if (h == INVALID_HANDLE_VALUE) 8818dffb485Schristos strcpy (buf, name); 8828dffb485Schristos else 8838dffb485Schristos { 8848dffb485Schristos FindClose (h); 8858dffb485Schristos strcpy (buf, name); 8868dffb485Schristos { 8878dffb485Schristos char cwd[MAX_PATH + 1]; 8888dffb485Schristos char *p; 8898dffb485Schristos if (GetCurrentDirectoryA (MAX_PATH + 1, cwd)) 8908dffb485Schristos { 8918dffb485Schristos p = strrchr (buf, '\\'); 8928dffb485Schristos if (p) 8938dffb485Schristos p[1] = '\0'; 8948dffb485Schristos SetCurrentDirectoryA (buf); 8958dffb485Schristos GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p); 8968dffb485Schristos SetCurrentDirectoryA (cwd); 8978dffb485Schristos } 8988dffb485Schristos } 8998dffb485Schristos } 9008dffb485Schristos 9018dffb485Schristos if (strcasecmp (buf, "ntdll.dll") == 0) 9028dffb485Schristos { 9038dffb485Schristos GetSystemDirectoryA (buf, sizeof (buf)); 9048dffb485Schristos strcat (buf, "\\ntdll.dll"); 9058dffb485Schristos } 9068dffb485Schristos 9078dffb485Schristos #ifdef __CYGWIN__ 9088dffb485Schristos cygwin_conv_path (CCP_WIN_A_TO_POSIX, buf, buf2, sizeof (buf2)); 9098dffb485Schristos #else 9108dffb485Schristos strcpy (buf2, buf); 9118dffb485Schristos #endif 9128dffb485Schristos 9138dffb485Schristos loaded_dll (buf2, load_addr); 9148dffb485Schristos } 9158dffb485Schristos 9168dffb485Schristos /* See nat/windows-nat.h. */ 9178dffb485Schristos 9188dffb485Schristos void 9194b169a6bSchristos gdbserver_windows_process::handle_unload_dll () 9208dffb485Schristos { 9218dffb485Schristos CORE_ADDR load_addr = 9228dffb485Schristos (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll; 9238dffb485Schristos 9248dffb485Schristos /* The symbols in a dll are offset by 0x1000, which is the 9258dffb485Schristos offset from 0 of the first byte in an image - because 9268dffb485Schristos of the file header and the section alignment. */ 9278dffb485Schristos load_addr += 0x1000; 9288dffb485Schristos unloaded_dll (NULL, load_addr); 9298dffb485Schristos } 9308dffb485Schristos 9318dffb485Schristos static void 9328dffb485Schristos suspend_one_thread (thread_info *thread) 9338dffb485Schristos { 9348dffb485Schristos windows_thread_info *th = (windows_thread_info *) thread_target_data (thread); 9358dffb485Schristos 9368dffb485Schristos th->suspend (); 9378dffb485Schristos } 9388dffb485Schristos 9398dffb485Schristos static void 9408dffb485Schristos fake_breakpoint_event (void) 9418dffb485Schristos { 9428dffb485Schristos OUTMSG2(("fake_breakpoint_event\n")); 9438dffb485Schristos 9444b169a6bSchristos windows_process.faked_breakpoint = 1; 9458dffb485Schristos 9464b169a6bSchristos memset (&windows_process.current_event, 0, 9474b169a6bSchristos sizeof (windows_process.current_event)); 9484b169a6bSchristos windows_process.current_event.dwThreadId = windows_process.main_thread_id; 9494b169a6bSchristos windows_process.current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT; 9504b169a6bSchristos windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode 9518dffb485Schristos = EXCEPTION_BREAKPOINT; 9528dffb485Schristos 9538dffb485Schristos for_each_thread (suspend_one_thread); 9548dffb485Schristos } 9558dffb485Schristos 9568dffb485Schristos /* See nat/windows-nat.h. */ 9578dffb485Schristos 9588dffb485Schristos bool 9594b169a6bSchristos gdbserver_windows_process::handle_access_violation 9604b169a6bSchristos (const EXCEPTION_RECORD *rec) 9618dffb485Schristos { 9628dffb485Schristos return false; 9638dffb485Schristos } 9648dffb485Schristos 9658dffb485Schristos /* A helper function that will, if needed, set 9668dffb485Schristos 'stopped_at_software_breakpoint' on the thread and adjust the 9678dffb485Schristos PC. */ 9688dffb485Schristos 9698dffb485Schristos static void 9708dffb485Schristos maybe_adjust_pc () 9718dffb485Schristos { 9728dffb485Schristos struct regcache *regcache = get_thread_regcache (current_thread, 1); 9738dffb485Schristos child_fetch_inferior_registers (regcache, -1); 9748dffb485Schristos 9754b169a6bSchristos windows_thread_info *th 9764b169a6bSchristos = windows_process.thread_rec (current_thread_ptid (), 9778dffb485Schristos DONT_INVALIDATE_CONTEXT); 9788dffb485Schristos th->stopped_at_software_breakpoint = false; 9798dffb485Schristos 9804b169a6bSchristos if (windows_process.current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT 9814b169a6bSchristos && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode 9828dffb485Schristos == EXCEPTION_BREAKPOINT) 9834b169a6bSchristos || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode 9848dffb485Schristos == STATUS_WX86_BREAKPOINT)) 9854b169a6bSchristos && windows_process.child_initialization_done) 9868dffb485Schristos { 9878dffb485Schristos th->stopped_at_software_breakpoint = true; 9888dffb485Schristos CORE_ADDR pc = regcache_read_pc (regcache); 9898dffb485Schristos CORE_ADDR sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break; 9908dffb485Schristos regcache_write_pc (regcache, sw_breakpoint_pc); 9918dffb485Schristos } 9928dffb485Schristos } 9938dffb485Schristos 9948dffb485Schristos /* Get the next event from the child. */ 9958dffb485Schristos 9968dffb485Schristos static int 9978dffb485Schristos get_child_debug_event (DWORD *continue_status, 9988dffb485Schristos struct target_waitstatus *ourstatus) 9998dffb485Schristos { 10008dffb485Schristos ptid_t ptid; 10018dffb485Schristos 10024b169a6bSchristos windows_process.last_sig = GDB_SIGNAL_0; 10034b169a6bSchristos ourstatus->set_spurious (); 10048dffb485Schristos *continue_status = DBG_CONTINUE; 10058dffb485Schristos 10068dffb485Schristos /* Check if GDB sent us an interrupt request. */ 10078dffb485Schristos check_remote_input_interrupt_request (); 10088dffb485Schristos 10094b169a6bSchristos DEBUG_EVENT *current_event = &windows_process.current_event; 10104b169a6bSchristos 10114b169a6bSchristos if (windows_process.soft_interrupt_requested) 10128dffb485Schristos { 10134b169a6bSchristos windows_process.soft_interrupt_requested = 0; 10148dffb485Schristos fake_breakpoint_event (); 10158dffb485Schristos goto gotevent; 10168dffb485Schristos } 10178dffb485Schristos 10184b169a6bSchristos windows_process.attaching = 0; 10198dffb485Schristos { 1020*13ed34faSchristos std::optional<pending_stop> stop 10214b169a6bSchristos = windows_process.fetch_pending_stop (debug_threads); 10228dffb485Schristos if (stop.has_value ()) 10238dffb485Schristos { 10248dffb485Schristos *ourstatus = stop->status; 10254b169a6bSchristos windows_process.current_event = stop->event; 10264b169a6bSchristos ptid = debug_event_ptid (&windows_process.current_event); 10274b169a6bSchristos switch_to_thread (find_thread_ptid (ptid)); 10288dffb485Schristos return 1; 10298dffb485Schristos } 10308dffb485Schristos 10318dffb485Schristos /* Keep the wait time low enough for comfortable remote 10328dffb485Schristos interruption, but high enough so gdbserver doesn't become a 10338dffb485Schristos bottleneck. */ 10344b169a6bSchristos if (!wait_for_debug_event (&windows_process.current_event, 250)) 10358dffb485Schristos { 10368dffb485Schristos DWORD e = GetLastError(); 10378dffb485Schristos 10388dffb485Schristos if (e == ERROR_PIPE_NOT_CONNECTED) 10398dffb485Schristos { 1040*13ed34faSchristos /* This will happen if the loader fails to successfully 10418dffb485Schristos load the application, e.g., if the main executable 10428dffb485Schristos tries to pull in a non-existing export from a 10438dffb485Schristos DLL. */ 10444b169a6bSchristos ourstatus->set_exited (1); 10458dffb485Schristos return 1; 10468dffb485Schristos } 10478dffb485Schristos 10488dffb485Schristos return 0; 10498dffb485Schristos } 10508dffb485Schristos } 10518dffb485Schristos 10528dffb485Schristos gotevent: 10538dffb485Schristos 10544b169a6bSchristos switch (current_event->dwDebugEventCode) 10558dffb485Schristos { 10568dffb485Schristos case CREATE_THREAD_DEBUG_EVENT: 10578dffb485Schristos OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT " 10588dffb485Schristos "for pid=%u tid=%x)\n", 10594b169a6bSchristos (unsigned) current_event->dwProcessId, 10604b169a6bSchristos (unsigned) current_event->dwThreadId)); 10618dffb485Schristos 10628dffb485Schristos /* Record the existence of this thread. */ 10634b169a6bSchristos child_add_thread (current_event->dwProcessId, 10644b169a6bSchristos current_event->dwThreadId, 10654b169a6bSchristos current_event->u.CreateThread.hThread, 10664b169a6bSchristos current_event->u.CreateThread.lpThreadLocalBase); 10678dffb485Schristos break; 10688dffb485Schristos 10698dffb485Schristos case EXIT_THREAD_DEBUG_EVENT: 10708dffb485Schristos OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT " 10718dffb485Schristos "for pid=%u tid=%x\n", 10724b169a6bSchristos (unsigned) current_event->dwProcessId, 10734b169a6bSchristos (unsigned) current_event->dwThreadId)); 10744b169a6bSchristos child_delete_thread (current_event->dwProcessId, 10754b169a6bSchristos current_event->dwThreadId); 10768dffb485Schristos 10774b169a6bSchristos switch_to_thread (get_first_thread ()); 10788dffb485Schristos return 1; 10798dffb485Schristos 10808dffb485Schristos case CREATE_PROCESS_DEBUG_EVENT: 10818dffb485Schristos OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT " 10828dffb485Schristos "for pid=%u tid=%x\n", 10834b169a6bSchristos (unsigned) current_event->dwProcessId, 10844b169a6bSchristos (unsigned) current_event->dwThreadId)); 10854b169a6bSchristos CloseHandle (current_event->u.CreateProcessInfo.hFile); 10868dffb485Schristos 10874b169a6bSchristos if (windows_process.open_process_used) 10888dffb485Schristos { 10894b169a6bSchristos CloseHandle (windows_process.handle); 10904b169a6bSchristos windows_process.open_process_used = false; 10918dffb485Schristos } 10928dffb485Schristos 10934b169a6bSchristos windows_process.handle = current_event->u.CreateProcessInfo.hProcess; 10944b169a6bSchristos windows_process.main_thread_id = current_event->dwThreadId; 10958dffb485Schristos 10968dffb485Schristos /* Add the main thread. */ 10974b169a6bSchristos child_add_thread (current_event->dwProcessId, 10984b169a6bSchristos windows_process.main_thread_id, 10994b169a6bSchristos current_event->u.CreateProcessInfo.hThread, 11004b169a6bSchristos current_event->u.CreateProcessInfo.lpThreadLocalBase); 11018dffb485Schristos break; 11028dffb485Schristos 11038dffb485Schristos case EXIT_PROCESS_DEBUG_EVENT: 11048dffb485Schristos OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT " 11058dffb485Schristos "for pid=%u tid=%x\n", 11064b169a6bSchristos (unsigned) current_event->dwProcessId, 11074b169a6bSchristos (unsigned) current_event->dwThreadId)); 11088dffb485Schristos { 11094b169a6bSchristos DWORD exit_status = current_event->u.ExitProcess.dwExitCode; 11108dffb485Schristos /* If the exit status looks like a fatal exception, but we 11118dffb485Schristos don't recognize the exception's code, make the original 11128dffb485Schristos exit status value available, to avoid losing information. */ 11138dffb485Schristos int exit_signal 11148dffb485Schristos = WIFSIGNALED (exit_status) ? WTERMSIG (exit_status) : -1; 11158dffb485Schristos if (exit_signal == -1) 11164b169a6bSchristos ourstatus->set_exited (exit_status); 11178dffb485Schristos else 11184b169a6bSchristos ourstatus->set_signalled (gdb_signal_from_host (exit_signal)); 11198dffb485Schristos } 11204b169a6bSchristos child_continue (DBG_CONTINUE, windows_process.desired_stop_thread_id); 11218dffb485Schristos break; 11228dffb485Schristos 11238dffb485Schristos case LOAD_DLL_DEBUG_EVENT: 11248dffb485Schristos OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT " 11258dffb485Schristos "for pid=%u tid=%x\n", 11264b169a6bSchristos (unsigned) current_event->dwProcessId, 11274b169a6bSchristos (unsigned) current_event->dwThreadId)); 11284b169a6bSchristos CloseHandle (current_event->u.LoadDll.hFile); 11294b169a6bSchristos if (! windows_process.child_initialization_done) 11308dffb485Schristos break; 11314b169a6bSchristos windows_process.dll_loaded_event (); 11328dffb485Schristos 11334b169a6bSchristos ourstatus->set_loaded (); 11348dffb485Schristos break; 11358dffb485Schristos 11368dffb485Schristos case UNLOAD_DLL_DEBUG_EVENT: 11378dffb485Schristos OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT " 11388dffb485Schristos "for pid=%u tid=%x\n", 11394b169a6bSchristos (unsigned) current_event->dwProcessId, 11404b169a6bSchristos (unsigned) current_event->dwThreadId)); 11414b169a6bSchristos if (! windows_process.child_initialization_done) 11428dffb485Schristos break; 11434b169a6bSchristos windows_process.handle_unload_dll (); 11444b169a6bSchristos ourstatus->set_loaded (); 11458dffb485Schristos break; 11468dffb485Schristos 11478dffb485Schristos case EXCEPTION_DEBUG_EVENT: 11488dffb485Schristos OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT " 11498dffb485Schristos "for pid=%u tid=%x\n", 11504b169a6bSchristos (unsigned) current_event->dwProcessId, 11514b169a6bSchristos (unsigned) current_event->dwThreadId)); 11524b169a6bSchristos if (windows_process.handle_exception (ourstatus, debug_threads) 11538dffb485Schristos == HANDLE_EXCEPTION_UNHANDLED) 11548dffb485Schristos *continue_status = DBG_EXCEPTION_NOT_HANDLED; 11558dffb485Schristos break; 11568dffb485Schristos 11578dffb485Schristos case OUTPUT_DEBUG_STRING_EVENT: 11588dffb485Schristos /* A message from the kernel (or Cygwin). */ 11598dffb485Schristos OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT " 11608dffb485Schristos "for pid=%u tid=%x\n", 11614b169a6bSchristos (unsigned) current_event->dwProcessId, 11624b169a6bSchristos (unsigned) current_event->dwThreadId)); 11634b169a6bSchristos windows_process.handle_output_debug_string (nullptr); 11648dffb485Schristos break; 11658dffb485Schristos 11668dffb485Schristos default: 11678dffb485Schristos OUTMSG2 (("gdbserver: kernel event unknown " 11688dffb485Schristos "for pid=%u tid=%x code=%x\n", 11694b169a6bSchristos (unsigned) current_event->dwProcessId, 11704b169a6bSchristos (unsigned) current_event->dwThreadId, 11714b169a6bSchristos (unsigned) current_event->dwDebugEventCode)); 11728dffb485Schristos break; 11738dffb485Schristos } 11748dffb485Schristos 11754b169a6bSchristos ptid = debug_event_ptid (&windows_process.current_event); 11768dffb485Schristos 11774b169a6bSchristos if (windows_process.desired_stop_thread_id != -1 11784b169a6bSchristos && windows_process.desired_stop_thread_id != ptid.lwp ()) 11798dffb485Schristos { 11808dffb485Schristos /* Pending stop. See the comment by the definition of 11818dffb485Schristos "pending_stops" for details on why this is needed. */ 11828dffb485Schristos OUTMSG2 (("get_windows_debug_event - " 11838dffb485Schristos "unexpected stop in 0x%lx (expecting 0x%x)\n", 11844b169a6bSchristos ptid.lwp (), windows_process.desired_stop_thread_id)); 11858dffb485Schristos maybe_adjust_pc (); 11864b169a6bSchristos windows_process.pending_stops.push_back 11874b169a6bSchristos ({(DWORD) ptid.lwp (), *ourstatus, *current_event}); 11884b169a6bSchristos ourstatus->set_spurious (); 11898dffb485Schristos } 11908dffb485Schristos else 11914b169a6bSchristos switch_to_thread (find_thread_ptid (ptid)); 11928dffb485Schristos 11938dffb485Schristos return 1; 11948dffb485Schristos } 11958dffb485Schristos 11968dffb485Schristos /* Wait for the inferior process to change state. 11978dffb485Schristos STATUS will be filled in with a response code to send to GDB. 11988dffb485Schristos Returns the signal which caused the process to stop. */ 11998dffb485Schristos ptid_t 12008dffb485Schristos win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, 12014b169a6bSchristos target_wait_flags options) 12028dffb485Schristos { 12034b169a6bSchristos if (windows_process.cached_status.kind () != TARGET_WAITKIND_IGNORE) 12048dffb485Schristos { 12058dffb485Schristos /* The core always does a wait after creating the inferior, and 12068dffb485Schristos do_initial_child_stuff already ran the inferior to the 12078dffb485Schristos initial breakpoint (or an exit, if creating the process 12088dffb485Schristos fails). Report it now. */ 12094b169a6bSchristos *ourstatus = windows_process.cached_status; 12104b169a6bSchristos windows_process.cached_status.set_ignore (); 12114b169a6bSchristos return debug_event_ptid (&windows_process.current_event); 12128dffb485Schristos } 12138dffb485Schristos 12148dffb485Schristos while (1) 12158dffb485Schristos { 12168dffb485Schristos DWORD continue_status; 12178dffb485Schristos if (!get_child_debug_event (&continue_status, ourstatus)) 12188dffb485Schristos continue; 12198dffb485Schristos 12204b169a6bSchristos switch (ourstatus->kind ()) 12218dffb485Schristos { 12228dffb485Schristos case TARGET_WAITKIND_EXITED: 12238dffb485Schristos OUTMSG2 (("Child exited with retcode = %x\n", 12244b169a6bSchristos ourstatus->exit_status ())); 12258dffb485Schristos win32_clear_inferiors (); 12264b169a6bSchristos return ptid_t (windows_process.current_event.dwProcessId); 12278dffb485Schristos case TARGET_WAITKIND_STOPPED: 12288dffb485Schristos case TARGET_WAITKIND_SIGNALLED: 12298dffb485Schristos case TARGET_WAITKIND_LOADED: 12308dffb485Schristos { 12318dffb485Schristos OUTMSG2 (("Child Stopped with signal = %d \n", 12324b169a6bSchristos ourstatus->sig ())); 12338dffb485Schristos maybe_adjust_pc (); 12344b169a6bSchristos return debug_event_ptid (&windows_process.current_event); 12358dffb485Schristos } 12368dffb485Schristos default: 12374b169a6bSchristos OUTMSG (("Ignoring unknown internal event, %d\n", 12384b169a6bSchristos ourstatus->kind ())); 1239*13ed34faSchristos [[fallthrough]]; 12408dffb485Schristos case TARGET_WAITKIND_SPURIOUS: 12418dffb485Schristos /* do nothing, just continue */ 12424b169a6bSchristos child_continue (continue_status, 12434b169a6bSchristos windows_process.desired_stop_thread_id); 12448dffb485Schristos break; 12458dffb485Schristos } 12468dffb485Schristos } 12478dffb485Schristos } 12488dffb485Schristos 12498dffb485Schristos /* Fetch registers from the inferior process. 12508dffb485Schristos If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */ 12518dffb485Schristos void 12528dffb485Schristos win32_process_target::fetch_registers (regcache *regcache, int regno) 12538dffb485Schristos { 12548dffb485Schristos child_fetch_inferior_registers (regcache, regno); 12558dffb485Schristos } 12568dffb485Schristos 12578dffb485Schristos /* Store registers to the inferior process. 12588dffb485Schristos If REGNO is -1, store all registers; otherwise, store at least REGNO. */ 12598dffb485Schristos void 12608dffb485Schristos win32_process_target::store_registers (regcache *regcache, int regno) 12618dffb485Schristos { 12628dffb485Schristos child_store_inferior_registers (regcache, regno); 12638dffb485Schristos } 12648dffb485Schristos 12658dffb485Schristos /* Read memory from the inferior process. This should generally be 12668dffb485Schristos called through read_inferior_memory, which handles breakpoint shadowing. 12678dffb485Schristos Read LEN bytes at MEMADDR into a buffer at MYADDR. */ 12688dffb485Schristos int 12698dffb485Schristos win32_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr, 12708dffb485Schristos int len) 12718dffb485Schristos { 12728dffb485Schristos return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len; 12738dffb485Schristos } 12748dffb485Schristos 12758dffb485Schristos /* Write memory to the inferior process. This should generally be 12768dffb485Schristos called through write_inferior_memory, which handles breakpoint shadowing. 12778dffb485Schristos Write LEN bytes from the buffer at MYADDR to MEMADDR. 12788dffb485Schristos Returns 0 on success and errno on failure. */ 12798dffb485Schristos int 12808dffb485Schristos win32_process_target::write_memory (CORE_ADDR memaddr, 12818dffb485Schristos const unsigned char *myaddr, int len) 12828dffb485Schristos { 12838dffb485Schristos return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len; 12848dffb485Schristos } 12858dffb485Schristos 12868dffb485Schristos /* Send an interrupt request to the inferior process. */ 12878dffb485Schristos void 12888dffb485Schristos win32_process_target::request_interrupt () 12898dffb485Schristos { 12904b169a6bSchristos if (GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, signal_pid)) 12918dffb485Schristos return; 12928dffb485Schristos 12938dffb485Schristos /* GenerateConsoleCtrlEvent can fail if process id being debugged is 12948dffb485Schristos not a process group id. 12958dffb485Schristos Fallback to XP/Vista 'DebugBreakProcess', which generates a 12968dffb485Schristos breakpoint exception in the interior process. */ 12978dffb485Schristos 12984b169a6bSchristos if (DebugBreakProcess (windows_process.handle)) 12998dffb485Schristos return; 13008dffb485Schristos 13018dffb485Schristos /* Last resort, suspend all threads manually. */ 13024b169a6bSchristos windows_process.soft_interrupt_requested = 1; 13038dffb485Schristos } 13048dffb485Schristos 13058dffb485Schristos bool 13068dffb485Schristos win32_process_target::supports_hardware_single_step () 13078dffb485Schristos { 13088dffb485Schristos return true; 13098dffb485Schristos } 13108dffb485Schristos 13118dffb485Schristos bool 13128dffb485Schristos win32_process_target::supports_qxfer_siginfo () 13138dffb485Schristos { 13148dffb485Schristos return true; 13158dffb485Schristos } 13168dffb485Schristos 13178dffb485Schristos /* Write Windows signal info. */ 13188dffb485Schristos 13198dffb485Schristos int 13208dffb485Schristos win32_process_target::qxfer_siginfo (const char *annex, 13218dffb485Schristos unsigned char *readbuf, 13228dffb485Schristos unsigned const char *writebuf, 13238dffb485Schristos CORE_ADDR offset, int len) 13248dffb485Schristos { 13254b169a6bSchristos if (windows_process.siginfo_er.ExceptionCode == 0) 13268dffb485Schristos return -1; 13278dffb485Schristos 13288dffb485Schristos if (readbuf == nullptr) 13298dffb485Schristos return -1; 13308dffb485Schristos 13314b169a6bSchristos char *buf = (char *) &windows_process.siginfo_er; 13324b169a6bSchristos size_t bufsize = sizeof (windows_process.siginfo_er); 13338dffb485Schristos 13348dffb485Schristos #ifdef __x86_64__ 13358dffb485Schristos EXCEPTION_RECORD32 er32; 13364b169a6bSchristos if (windows_process.wow64_process) 13378dffb485Schristos { 13388dffb485Schristos buf = (char *) &er32; 13398dffb485Schristos bufsize = sizeof (er32); 13408dffb485Schristos 13414b169a6bSchristos er32.ExceptionCode = windows_process.siginfo_er.ExceptionCode; 13424b169a6bSchristos er32.ExceptionFlags = windows_process.siginfo_er.ExceptionFlags; 13434b169a6bSchristos er32.ExceptionRecord 13444b169a6bSchristos = (uintptr_t) windows_process.siginfo_er.ExceptionRecord; 13454b169a6bSchristos er32.ExceptionAddress 13464b169a6bSchristos = (uintptr_t) windows_process.siginfo_er.ExceptionAddress; 13474b169a6bSchristos er32.NumberParameters = windows_process.siginfo_er.NumberParameters; 13488dffb485Schristos int i; 13498dffb485Schristos for (i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++) 13504b169a6bSchristos er32.ExceptionInformation[i] 13514b169a6bSchristos = windows_process.siginfo_er.ExceptionInformation[i]; 13528dffb485Schristos } 13538dffb485Schristos #endif 13548dffb485Schristos 13558dffb485Schristos if (offset > bufsize) 13568dffb485Schristos return -1; 13578dffb485Schristos 13588dffb485Schristos if (offset + len > bufsize) 13598dffb485Schristos len = bufsize - offset; 13608dffb485Schristos 13618dffb485Schristos memcpy (readbuf, buf + offset, len); 13628dffb485Schristos 13638dffb485Schristos return len; 13648dffb485Schristos } 13658dffb485Schristos 13668dffb485Schristos bool 13678dffb485Schristos win32_process_target::supports_get_tib_address () 13688dffb485Schristos { 13698dffb485Schristos return true; 13708dffb485Schristos } 13718dffb485Schristos 13728dffb485Schristos /* Write Windows OS Thread Information Block address. */ 13738dffb485Schristos 13748dffb485Schristos int 13758dffb485Schristos win32_process_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr) 13768dffb485Schristos { 13778dffb485Schristos windows_thread_info *th; 13784b169a6bSchristos th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT); 13798dffb485Schristos if (th == NULL) 13808dffb485Schristos return 0; 13818dffb485Schristos if (addr != NULL) 13828dffb485Schristos *addr = th->thread_local_base; 13838dffb485Schristos return 1; 13848dffb485Schristos } 13858dffb485Schristos 13868dffb485Schristos /* Implementation of the target_ops method "sw_breakpoint_from_kind". */ 13878dffb485Schristos 13888dffb485Schristos const gdb_byte * 13898dffb485Schristos win32_process_target::sw_breakpoint_from_kind (int kind, int *size) 13908dffb485Schristos { 13918dffb485Schristos *size = the_low_target.breakpoint_len; 13928dffb485Schristos return the_low_target.breakpoint; 13938dffb485Schristos } 13948dffb485Schristos 13958dffb485Schristos bool 13968dffb485Schristos win32_process_target::stopped_by_sw_breakpoint () 13978dffb485Schristos { 13984b169a6bSchristos windows_thread_info *th 13994b169a6bSchristos = windows_process.thread_rec (current_thread_ptid (), 14008dffb485Schristos DONT_INVALIDATE_CONTEXT); 14018dffb485Schristos return th == nullptr ? false : th->stopped_at_software_breakpoint; 14028dffb485Schristos } 14038dffb485Schristos 14048dffb485Schristos bool 14058dffb485Schristos win32_process_target::supports_stopped_by_sw_breakpoint () 14068dffb485Schristos { 14078dffb485Schristos return true; 14088dffb485Schristos } 14098dffb485Schristos 14108dffb485Schristos CORE_ADDR 14118dffb485Schristos win32_process_target::read_pc (struct regcache *regcache) 14128dffb485Schristos { 14138dffb485Schristos return (*the_low_target.get_pc) (regcache); 14148dffb485Schristos } 14158dffb485Schristos 14168dffb485Schristos void 14178dffb485Schristos win32_process_target::write_pc (struct regcache *regcache, CORE_ADDR pc) 14188dffb485Schristos { 14198dffb485Schristos return (*the_low_target.set_pc) (regcache, pc); 14208dffb485Schristos } 14218dffb485Schristos 14224b169a6bSchristos const char * 14234b169a6bSchristos win32_process_target::thread_name (ptid_t thread) 14244b169a6bSchristos { 14254b169a6bSchristos windows_thread_info *th 14264b169a6bSchristos = windows_process.thread_rec (current_thread_ptid (), 14274b169a6bSchristos DONT_INVALIDATE_CONTEXT); 14284b169a6bSchristos return th->thread_name (); 14294b169a6bSchristos } 14304b169a6bSchristos 14314b169a6bSchristos const char * 14324b169a6bSchristos win32_process_target::pid_to_exec_file (int pid) 14334b169a6bSchristos { 14344b169a6bSchristos return windows_process.pid_to_exec_file (pid); 14354b169a6bSchristos } 14364b169a6bSchristos 14378dffb485Schristos /* The win32 target ops object. */ 14388dffb485Schristos 14398dffb485Schristos static win32_process_target the_win32_target; 14408dffb485Schristos 14418dffb485Schristos /* Initialize the Win32 backend. */ 14428dffb485Schristos void 14438dffb485Schristos initialize_low (void) 14448dffb485Schristos { 14458dffb485Schristos set_target_ops (&the_win32_target); 14468dffb485Schristos the_low_target.arch_setup (); 14478dffb485Schristos 14484b169a6bSchristos initialize_loadable (); 14498dffb485Schristos } 1450