1 /* Low level interface to Windows debugging, for gdbserver.
2 Copyright (C) 2006-2021 Free Software Foundation, Inc.
4 Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "gdb/fileio.h"
24 #include "mem-break.h"
25 #include "win32-low.h"
26 #include "gdbthread.h"
35 #include "gdbsupport/gdb_tilde_expand.h"
36 #include "gdbsupport/common-inferior.h"
37 #include "gdbsupport/gdb_wait.h"
39 using namespace windows_nat
;
42 #include <sys/cygwin.h>
45 #define OUTMSG(X) do { printf X; fflush (stderr); } while (0)
58 #define _T(x) TEXT (x)
62 #define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
65 #define GETPROCADDRESS(DLL, PROC) \
66 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
68 int using_threads
= 1;
71 static int attaching
= 0;
73 /* A status that hasn't been reported to the core yet, and so
74 win32_wait should return it next, instead of fetching the next
75 debug event off the win32 API. */
76 static struct target_waitstatus cached_status
;
78 /* Non zero if an interrupt request is to be satisfied by suspending
80 static int soft_interrupt_requested
= 0;
82 /* Non zero if the inferior is stopped in a simulated breakpoint done
83 by suspending all the threads. */
84 static int faked_breakpoint
= 0;
86 /* True if current_process_handle needs to be closed. */
87 static bool open_process_used
= false;
89 const struct target_desc
*win32_tdesc
;
91 const struct target_desc
*wow64_win32_tdesc
;
94 #define NUM_REGS (the_low_target.num_regs ())
96 typedef BOOL (WINAPI
*winapi_DebugActiveProcessStop
) (DWORD dwProcessId
);
97 typedef BOOL (WINAPI
*winapi_DebugSetProcessKillOnExit
) (BOOL KillOnExit
);
98 typedef BOOL (WINAPI
*winapi_DebugBreakProcess
) (HANDLE
);
99 typedef BOOL (WINAPI
*winapi_GenerateConsoleCtrlEvent
) (DWORD
, DWORD
);
102 typedef BOOL (WINAPI
*winapi_Wow64SetThreadContext
) (HANDLE
,
103 const WOW64_CONTEXT
*);
105 winapi_Wow64GetThreadContext win32_Wow64GetThreadContext
;
106 static winapi_Wow64SetThreadContext win32_Wow64SetThreadContext
;
109 static void win32_add_all_dlls (void);
111 /* Get the thread ID from the current selected inferior (the current
114 current_thread_ptid (void)
119 /* The current debug event from WaitForDebugEvent. */
121 debug_event_ptid (DEBUG_EVENT
*event
)
123 return ptid_t (event
->dwProcessId
, event
->dwThreadId
, 0);
126 /* Get the thread context of the thread associated with TH. */
129 win32_get_thread_context (windows_thread_info
*th
)
133 memset (&th
->wow64_context
, 0, sizeof (WOW64_CONTEXT
));
136 memset (&th
->context
, 0, sizeof (CONTEXT
));
137 (*the_low_target
.get_thread_context
) (th
);
140 /* Set the thread context of the thread associated with TH. */
143 win32_set_thread_context (windows_thread_info
*th
)
147 win32_Wow64SetThreadContext (th
->h
, &th
->wow64_context
);
150 SetThreadContext (th
->h
, &th
->context
);
153 /* Set the thread context of the thread associated with TH. */
156 win32_prepare_to_resume (windows_thread_info
*th
)
158 if (the_low_target
.prepare_to_resume
!= NULL
)
159 (*the_low_target
.prepare_to_resume
) (th
);
162 /* See win32-low.h. */
165 win32_require_context (windows_thread_info
*th
)
170 context_flags
= th
->wow64_context
.ContextFlags
;
173 context_flags
= th
->context
.ContextFlags
;
174 if (context_flags
== 0)
177 win32_get_thread_context (th
);
181 /* See nat/windows-nat.h. */
183 windows_thread_info
*
184 windows_nat::thread_rec (ptid_t ptid
, thread_disposition_type disposition
)
186 thread_info
*thread
= find_thread_ptid (ptid
);
190 windows_thread_info
*th
= (windows_thread_info
*) thread_target_data (thread
);
191 if (disposition
!= DONT_INVALIDATE_CONTEXT
)
192 win32_require_context (th
);
196 /* Add a thread to the thread list. */
197 static windows_thread_info
*
198 child_add_thread (DWORD pid
, DWORD tid
, HANDLE h
, void *tlb
)
200 windows_thread_info
*th
;
201 ptid_t ptid
= ptid_t (pid
, tid
, 0);
203 if ((th
= thread_rec (ptid
, DONT_INVALIDATE_CONTEXT
)))
206 CORE_ADDR base
= (CORE_ADDR
) (uintptr_t) tlb
;
208 /* For WOW64 processes, this is actually the pointer to the 64bit TIB,
209 and the 32bit TIB is exactly 2 pages after it. */
211 base
+= 2 * 4096; /* page size = 4096 */
213 th
= new windows_thread_info (tid
, h
, base
);
215 add_thread (ptid
, th
);
217 if (the_low_target
.thread_added
!= NULL
)
218 (*the_low_target
.thread_added
) (th
);
223 /* Delete a thread from the list of threads. */
225 delete_thread_info (thread_info
*thread
)
227 windows_thread_info
*th
= (windows_thread_info
*) thread_target_data (thread
);
229 remove_thread (thread
);
233 /* Delete a thread from the list of threads. */
235 child_delete_thread (DWORD pid
, DWORD tid
)
237 /* If the last thread is exiting, just return. */
238 if (all_threads
.size () == 1)
241 thread_info
*thread
= find_thread_ptid (ptid_t (pid
, tid
));
245 delete_thread_info (thread
);
248 /* These watchpoint related wrapper functions simply pass on the function call
249 if the low target has registered a corresponding function. */
252 win32_process_target::supports_z_point_type (char z_type
)
254 return (z_type
== Z_PACKET_SW_BP
255 || (the_low_target
.supports_z_point_type
!= NULL
256 && the_low_target
.supports_z_point_type (z_type
)));
260 win32_process_target::insert_point (enum raw_bkpt_type type
, CORE_ADDR addr
,
261 int size
, raw_breakpoint
*bp
)
263 if (type
== raw_bkpt_type_sw
)
264 return insert_memory_breakpoint (bp
);
265 else if (the_low_target
.insert_point
!= NULL
)
266 return the_low_target
.insert_point (type
, addr
, size
, bp
);
268 /* Unsupported (see target.h). */
273 win32_process_target::remove_point (enum raw_bkpt_type type
, CORE_ADDR addr
,
274 int size
, raw_breakpoint
*bp
)
276 if (type
== raw_bkpt_type_sw
)
277 return remove_memory_breakpoint (bp
);
278 else if (the_low_target
.remove_point
!= NULL
)
279 return the_low_target
.remove_point (type
, addr
, size
, bp
);
281 /* Unsupported (see target.h). */
286 win32_process_target::stopped_by_watchpoint ()
288 if (the_low_target
.stopped_by_watchpoint
!= NULL
)
289 return the_low_target
.stopped_by_watchpoint ();
295 win32_process_target::stopped_data_address ()
297 if (the_low_target
.stopped_data_address
!= NULL
)
298 return the_low_target
.stopped_data_address ();
304 /* Transfer memory from/to the debugged process. */
306 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
307 int write
, process_stratum_target
*target
)
312 uintptr_t addr
= (uintptr_t) memaddr
;
316 success
= WriteProcessMemory (current_process_handle
, (LPVOID
) addr
,
317 (LPCVOID
) our
, len
, &done
);
319 lasterror
= GetLastError ();
320 FlushInstructionCache (current_process_handle
, (LPCVOID
) addr
, len
);
324 success
= ReadProcessMemory (current_process_handle
, (LPCVOID
) addr
,
325 (LPVOID
) our
, len
, &done
);
327 lasterror
= GetLastError ();
329 if (!success
&& lasterror
== ERROR_PARTIAL_COPY
&& done
> 0)
332 return success
? done
: -1;
335 /* Clear out any old thread list and reinitialize it to a pristine
338 child_init_thread_list (void)
340 for_each_thread (delete_thread_info
);
343 /* Zero during the child initialization phase, and nonzero otherwise. */
345 static int child_initialization_done
= 0;
348 do_initial_child_stuff (HANDLE proch
, DWORD pid
, int attached
)
350 struct process_info
*proc
;
352 last_sig
= GDB_SIGNAL_0
;
354 current_process_handle
= proch
;
355 current_process_id
= pid
;
358 soft_interrupt_requested
= 0;
359 faked_breakpoint
= 0;
360 open_process_used
= true;
362 memset (¤t_event
, 0, sizeof (current_event
));
366 if (!IsWow64Process (proch
, &wow64
))
368 DWORD err
= GetLastError ();
369 error ("Check if WOW64 process failed (error %d): %s\n",
370 (int) err
, strwinerror (err
));
372 wow64_process
= wow64
;
375 && (win32_Wow64GetThreadContext
== nullptr
376 || win32_Wow64SetThreadContext
== nullptr))
377 error ("WOW64 debugging is not supported on this system.\n");
379 ignore_first_breakpoint
= !attached
&& wow64_process
;
382 proc
= add_process (pid
, attached
);
385 proc
->tdesc
= wow64_win32_tdesc
;
388 proc
->tdesc
= win32_tdesc
;
389 child_init_thread_list ();
390 child_initialization_done
= 0;
392 if (the_low_target
.initial_stuff
!= NULL
)
393 (*the_low_target
.initial_stuff
) ();
395 cached_status
.kind
= TARGET_WAITKIND_IGNORE
;
397 /* Flush all currently pending debug events (thread and dll list) up
398 to the initial breakpoint. */
401 struct target_waitstatus status
;
403 the_target
->wait (minus_one_ptid
, &status
, 0);
405 /* Note win32_wait doesn't return thread events. */
406 if (status
.kind
!= TARGET_WAITKIND_LOADED
)
408 cached_status
= status
;
413 struct thread_resume resume
;
415 resume
.thread
= minus_one_ptid
;
416 resume
.kind
= resume_continue
;
419 the_target
->resume (&resume
, 1);
423 /* Now that the inferior has been started and all DLLs have been mapped,
424 we can iterate over all DLLs and load them in.
426 We avoid doing it any earlier because, on certain versions of Windows,
427 LOAD_DLL_DEBUG_EVENTs are sometimes not complete. In particular,
428 we have seen on Windows 8.1 that the ntdll.dll load event does not
429 include the DLL name, preventing us from creating an associated SO.
430 A possible explanation is that ntdll.dll might be mapped before
431 the SO info gets created by the Windows system -- ntdll.dll is
432 the first DLL to be reported via LOAD_DLL_DEBUG_EVENT and other DLLs
433 do not seem to suffer from that problem.
435 Rather than try to work around this sort of issue, it is much
436 simpler to just ignore DLL load/unload events during the startup
437 phase, and then process them all in one batch now. */
438 win32_add_all_dlls ();
440 child_initialization_done
= 1;
443 /* Resume all artificially suspended threads if we are continuing
446 continue_one_thread (thread_info
*thread
, int thread_id
)
448 windows_thread_info
*th
= (windows_thread_info
*) thread_target_data (thread
);
450 if (thread_id
== -1 || thread_id
== th
->tid
)
452 win32_prepare_to_resume (th
);
456 DWORD
*context_flags
;
459 context_flags
= &th
->wow64_context
.ContextFlags
;
462 context_flags
= &th
->context
.ContextFlags
;
465 win32_set_thread_context (th
);
475 child_continue (DWORD continue_status
, int thread_id
)
477 desired_stop_thread_id
= thread_id
;
478 if (matching_pending_stop (debug_threads
))
481 /* The inferior will only continue after the ContinueDebugEvent
483 for_each_thread ([&] (thread_info
*thread
)
485 continue_one_thread (thread
, thread_id
);
487 faked_breakpoint
= 0;
489 return continue_last_debug_event (continue_status
, debug_threads
);
492 /* Fetch register(s) from the current thread context. */
494 child_fetch_inferior_registers (struct regcache
*regcache
, int r
)
497 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
499 if (r
== -1 || r
> NUM_REGS
)
500 child_fetch_inferior_registers (regcache
, NUM_REGS
);
502 for (regno
= 0; regno
< r
; regno
++)
503 (*the_low_target
.fetch_inferior_register
) (regcache
, th
, regno
);
506 /* Store a new register value into the current thread context. We don't
507 change the program's context until later, when we resume it. */
509 child_store_inferior_registers (struct regcache
*regcache
, int r
)
512 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
514 if (r
== -1 || r
== 0 || r
> NUM_REGS
)
515 child_store_inferior_registers (regcache
, NUM_REGS
);
517 for (regno
= 0; regno
< r
; regno
++)
518 (*the_low_target
.store_inferior_register
) (regcache
, th
, regno
);
521 /* Map the Windows error number in ERROR to a locale-dependent error
522 message string and return a pointer to it. Typically, the values
523 for ERROR come from GetLastError.
525 The string pointed to shall not be modified by the application,
526 but may be overwritten by a subsequent call to strwinerror
528 The strwinerror function does not change the current setting
532 strwinerror (DWORD error
)
534 static char buf
[1024];
536 DWORD lasterr
= GetLastError ();
537 DWORD chars
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
538 | FORMAT_MESSAGE_ALLOCATE_BUFFER
,
541 0, /* Default language */
547 /* If there is an \r\n appended, zap it. */
549 && msgbuf
[chars
- 2] == '\r'
550 && msgbuf
[chars
- 1] == '\n')
556 if (chars
> ((COUNTOF (buf
)) - 1))
558 chars
= COUNTOF (buf
) - 1;
563 wcstombs (buf
, msgbuf
, chars
+ 1);
565 strncpy (buf
, msgbuf
, chars
+ 1);
570 sprintf (buf
, "unknown win32 error (%u)", (unsigned) error
);
572 SetLastError (lasterr
);
577 create_process (const char *program
, char *args
,
578 DWORD flags
, PROCESS_INFORMATION
*pi
)
580 const char *inferior_cwd
= get_inferior_cwd ();
582 size_t argslen
, proglen
;
584 proglen
= strlen (program
) + 1;
585 argslen
= strlen (args
) + proglen
;
587 STARTUPINFOA si
= { sizeof (STARTUPINFOA
) };
588 char *program_and_args
= (char *) alloca (argslen
+ 1);
590 strcpy (program_and_args
, program
);
591 strcat (program_and_args
, " ");
592 strcat (program_and_args
, args
);
593 ret
= CreateProcessA (program
, /* image name */
594 program_and_args
, /* command line */
597 TRUE
, /* inherit handles */
598 flags
, /* start flags */
599 NULL
, /* environment */
600 /* current directory */
601 (inferior_cwd
== NULL
603 : gdb_tilde_expand (inferior_cwd
).c_str()),
604 &si
, /* start info */
610 /* Start a new process.
611 PROGRAM is the program name.
612 PROGRAM_ARGS is the vector containing the inferior's args.
613 Returns the new PID on success, -1 on failure. Registers the new
614 process with the process list. */
616 win32_process_target::create_inferior (const char *program
,
617 const std::vector
<char *> &program_args
)
619 client_state
&cs
= get_client_state ();
621 char real_path
[PATH_MAX
];
622 char *orig_path
, *new_path
, *path_ptr
;
626 PROCESS_INFORMATION pi
;
628 std::string str_program_args
= construct_inferior_arguments (program_args
);
629 char *args
= (char *) str_program_args
.c_str ();
631 /* win32_wait needs to know we're not attaching. */
635 error ("No executable specified, specify executable to debug.\n");
637 flags
= DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
;
641 path_ptr
= getenv ("PATH");
644 int size
= cygwin_conv_path_list (CCP_POSIX_TO_WIN_A
, path_ptr
, NULL
, 0);
645 orig_path
= (char *) alloca (strlen (path_ptr
) + 1);
646 new_path
= (char *) alloca (size
);
647 strcpy (orig_path
, path_ptr
);
648 cygwin_conv_path_list (CCP_POSIX_TO_WIN_A
, path_ptr
, new_path
, size
);
649 setenv ("PATH", new_path
, 1);
651 cygwin_conv_path (CCP_POSIX_TO_WIN_A
, program
, real_path
, PATH_MAX
);
655 OUTMSG2 (("Command line is \"%s %s\"\n", program
, args
));
657 #ifdef CREATE_NEW_PROCESS_GROUP
658 flags
|= CREATE_NEW_PROCESS_GROUP
;
661 ret
= create_process (program
, args
, flags
, &pi
);
662 err
= GetLastError ();
663 if (!ret
&& err
== ERROR_FILE_NOT_FOUND
)
665 char *exename
= (char *) alloca (strlen (program
) + 5);
666 strcat (strcpy (exename
, program
), ".exe");
667 ret
= create_process (exename
, args
, flags
, &pi
);
668 err
= GetLastError ();
673 setenv ("PATH", orig_path
, 1);
678 error ("Error creating process \"%s %s\", (error %d): %s\n",
679 program
, args
, (int) err
, strwinerror (err
));
683 OUTMSG2 (("Process created: %s %s\n", program
, (char *) args
));
686 CloseHandle (pi
.hThread
);
688 do_initial_child_stuff (pi
.hProcess
, pi
.dwProcessId
, 0);
690 /* Wait till we are at 1st instruction in program, return new pid
691 (assuming success). */
692 cs
.last_ptid
= wait (ptid_t (current_process_id
), &cs
.last_status
, 0);
694 /* Necessary for handle_v_kill. */
695 signal_pid
= current_process_id
;
697 return current_process_id
;
700 /* Attach to a running process.
701 PID is the process ID to attach to, specified by the user
702 or a higher layer. */
704 win32_process_target::attach (unsigned long pid
)
707 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit
= NULL
;
709 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
710 DebugSetProcessKillOnExit
= GETPROCADDRESS (dll
, DebugSetProcessKillOnExit
);
712 h
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
, pid
);
715 if (DebugActiveProcess (pid
))
717 if (DebugSetProcessKillOnExit
!= NULL
)
718 DebugSetProcessKillOnExit (FALSE
);
720 /* win32_wait needs to know we're attaching. */
722 do_initial_child_stuff (h
, pid
, 1);
729 err
= GetLastError ();
730 error ("Attach to process failed (error %d): %s\n",
731 (int) err
, strwinerror (err
));
734 /* See nat/windows-nat.h. */
737 windows_nat::handle_output_debug_string (struct target_waitstatus
*ourstatus
)
739 #define READ_BUFFER_LEN 1024
741 char s
[READ_BUFFER_LEN
+ 1] = { 0 };
742 DWORD nbytes
= current_event
.u
.DebugString
.nDebugStringLength
;
747 if (nbytes
> READ_BUFFER_LEN
)
748 nbytes
= READ_BUFFER_LEN
;
750 addr
= (CORE_ADDR
) (size_t) current_event
.u
.DebugString
.lpDebugStringData
;
752 if (current_event
.u
.DebugString
.fUnicode
)
754 /* The event tells us how many bytes, not chars, even
756 WCHAR buffer
[(READ_BUFFER_LEN
+ 1) / sizeof (WCHAR
)] = { 0 };
757 if (read_inferior_memory (addr
, (unsigned char *) buffer
, nbytes
) != 0)
759 wcstombs (s
, buffer
, (nbytes
+ 1) / sizeof (WCHAR
));
763 if (read_inferior_memory (addr
, (unsigned char *) s
, nbytes
) != 0)
767 if (!startswith (s
, "cYg"))
777 #undef READ_BUFFER_LEN
783 win32_clear_inferiors (void)
785 if (open_process_used
)
787 CloseHandle (current_process_handle
);
788 open_process_used
= false;
791 for_each_thread (delete_thread_info
);
792 siginfo_er
.ExceptionCode
= 0;
796 /* Implementation of target_ops::kill. */
799 win32_process_target::kill (process_info
*process
)
801 TerminateProcess (current_process_handle
, 0);
804 if (!child_continue (DBG_CONTINUE
, -1))
806 if (!wait_for_debug_event (¤t_event
, INFINITE
))
808 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
810 else if (current_event
.dwDebugEventCode
== OUTPUT_DEBUG_STRING_EVENT
)
811 handle_output_debug_string (nullptr);
814 win32_clear_inferiors ();
816 remove_process (process
);
820 /* Implementation of target_ops::detach. */
823 win32_process_target::detach (process_info
*process
)
825 winapi_DebugActiveProcessStop DebugActiveProcessStop
= NULL
;
826 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit
= NULL
;
827 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
828 DebugActiveProcessStop
= GETPROCADDRESS (dll
, DebugActiveProcessStop
);
829 DebugSetProcessKillOnExit
= GETPROCADDRESS (dll
, DebugSetProcessKillOnExit
);
831 if (DebugSetProcessKillOnExit
== NULL
832 || DebugActiveProcessStop
== NULL
)
836 struct thread_resume resume
;
837 resume
.thread
= minus_one_ptid
;
838 resume
.kind
= resume_continue
;
840 this->resume (&resume
, 1);
843 if (!DebugActiveProcessStop (current_process_id
))
846 DebugSetProcessKillOnExit (FALSE
);
847 remove_process (process
);
849 win32_clear_inferiors ();
854 win32_process_target::mourn (struct process_info
*process
)
856 remove_process (process
);
859 /* Implementation of target_ops::join. */
862 win32_process_target::join (int pid
)
864 HANDLE h
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
, pid
);
867 WaitForSingleObject (h
, INFINITE
);
872 /* Return true iff the thread with thread ID TID is alive. */
874 win32_process_target::thread_alive (ptid_t ptid
)
876 /* Our thread list is reliable; don't bother to poll target
878 return find_thread_ptid (ptid
) != NULL
;
881 /* Resume the inferior process. RESUME_INFO describes how we want
884 win32_process_target::resume (thread_resume
*resume_info
, size_t n
)
889 windows_thread_info
*th
;
890 DWORD continue_status
= DBG_CONTINUE
;
893 /* This handles the very limited set of resume packets that GDB can
894 currently produce. */
896 if (n
== 1 && resume_info
[0].thread
== minus_one_ptid
)
901 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
902 the Windows resume code do the right thing for thread switching. */
903 tid
= current_event
.dwThreadId
;
905 if (resume_info
[0].thread
!= minus_one_ptid
)
907 sig
= gdb_signal_from_host (resume_info
[0].sig
);
908 step
= resume_info
[0].kind
== resume_step
;
916 if (sig
!= GDB_SIGNAL_0
)
918 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
920 OUTMSG (("Cannot continue with signal %s here.\n",
921 gdb_signal_to_string (sig
)));
923 else if (sig
== last_sig
)
924 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
926 OUTMSG (("Can only continue with received signal %s.\n",
927 gdb_signal_to_string (last_sig
)));
930 last_sig
= GDB_SIGNAL_0
;
932 /* Get context for the currently selected thread. */
933 ptid
= debug_event_ptid (¤t_event
);
934 th
= thread_rec (ptid
, DONT_INVALIDATE_CONTEXT
);
937 win32_prepare_to_resume (th
);
939 DWORD
*context_flags
;
942 context_flags
= &th
->wow64_context
.ContextFlags
;
945 context_flags
= &th
->context
.ContextFlags
;
948 /* Move register values from the inferior into the thread
949 context structure. */
950 regcache_invalidate ();
954 if (the_low_target
.single_step
!= NULL
)
955 (*the_low_target
.single_step
) (th
);
957 error ("Single stepping is not supported "
958 "in this configuration.\n");
961 win32_set_thread_context (th
);
966 /* Allow continuing with the same signal that interrupted us.
967 Otherwise complain. */
969 child_continue (continue_status
, tid
);
973 win32_add_one_solib (const char *name
, CORE_ADDR load_addr
)
975 char buf
[MAX_PATH
+ 1];
976 char buf2
[MAX_PATH
+ 1];
978 WIN32_FIND_DATAA w32_fd
;
979 HANDLE h
= FindFirstFileA (name
, &w32_fd
);
981 /* The symbols in a dll are offset by 0x1000, which is the
982 offset from 0 of the first byte in an image - because
983 of the file header and the section alignment. */
986 if (h
== INVALID_HANDLE_VALUE
)
993 char cwd
[MAX_PATH
+ 1];
995 if (GetCurrentDirectoryA (MAX_PATH
+ 1, cwd
))
997 p
= strrchr (buf
, '\\');
1000 SetCurrentDirectoryA (buf
);
1001 GetFullPathNameA (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
1002 SetCurrentDirectoryA (cwd
);
1007 if (strcasecmp (buf
, "ntdll.dll") == 0)
1009 GetSystemDirectoryA (buf
, sizeof (buf
));
1010 strcat (buf
, "\\ntdll.dll");
1014 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, buf
, buf2
, sizeof (buf2
));
1019 loaded_dll (buf2
, load_addr
);
1022 typedef BOOL (WINAPI
*winapi_EnumProcessModules
) (HANDLE
, HMODULE
*,
1025 typedef BOOL (WINAPI
*winapi_EnumProcessModulesEx
) (HANDLE
, HMODULE
*, DWORD
,
1028 typedef BOOL (WINAPI
*winapi_GetModuleInformation
) (HANDLE
, HMODULE
,
1029 LPMODULEINFO
, DWORD
);
1030 typedef DWORD (WINAPI
*winapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
,
1033 static winapi_EnumProcessModules win32_EnumProcessModules
;
1035 static winapi_EnumProcessModulesEx win32_EnumProcessModulesEx
;
1037 static winapi_GetModuleInformation win32_GetModuleInformation
;
1038 static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA
;
1043 static int psapi_loaded
= 0;
1044 static HMODULE dll
= NULL
;
1049 dll
= LoadLibrary (TEXT("psapi.dll"));
1052 win32_EnumProcessModules
=
1053 GETPROCADDRESS (dll
, EnumProcessModules
);
1055 win32_EnumProcessModulesEx
=
1056 GETPROCADDRESS (dll
, EnumProcessModulesEx
);
1058 win32_GetModuleInformation
=
1059 GETPROCADDRESS (dll
, GetModuleInformation
);
1060 win32_GetModuleFileNameExA
=
1061 GETPROCADDRESS (dll
, GetModuleFileNameExA
);
1065 if (wow64_process
&& win32_EnumProcessModulesEx
== nullptr)
1069 return (win32_EnumProcessModules
!= NULL
1070 && win32_GetModuleInformation
!= NULL
1071 && win32_GetModuleFileNameExA
!= NULL
);
1074 /* Iterate over all DLLs currently mapped by our inferior, looking for
1075 a DLL loaded at LOAD_ADDR; if found, return its file name,
1076 otherwise return NULL. If LOAD_ADDR is NULL, add all mapped DLLs
1077 to our list of solibs. */
1080 win32_add_dll (LPVOID load_addr
)
1084 HMODULE
*DllHandle
= dh_buf
;
1094 ok
= (*win32_EnumProcessModulesEx
) (current_process_handle
,
1098 LIST_MODULES_32BIT
);
1101 ok
= (*win32_EnumProcessModules
) (current_process_handle
,
1106 if (!ok
|| !cbNeeded
)
1109 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
1115 ok
= (*win32_EnumProcessModulesEx
) (current_process_handle
,
1119 LIST_MODULES_32BIT
);
1122 ok
= (*win32_EnumProcessModules
) (current_process_handle
,
1129 char system_dir
[MAX_PATH
];
1130 char syswow_dir
[MAX_PATH
];
1131 size_t system_dir_len
= 0;
1132 bool convert_syswow_dir
= false;
1137 /* This fails on 32bit Windows because it has no SysWOW64 directory,
1138 and in this case a path conversion isn't necessary. */
1139 UINT len
= GetSystemWow64DirectoryA (syswow_dir
, sizeof (syswow_dir
));
1142 /* Check that we have passed a large enough buffer. */
1143 gdb_assert (len
< sizeof (syswow_dir
));
1145 len
= GetSystemDirectoryA (system_dir
, sizeof (system_dir
));
1147 gdb_assert (len
!= 0);
1148 /* Check that we have passed a large enough buffer. */
1149 gdb_assert (len
< sizeof (system_dir
));
1151 strcat (system_dir
, "\\");
1152 strcat (syswow_dir
, "\\");
1153 system_dir_len
= strlen (system_dir
);
1155 convert_syswow_dir
= true;
1160 for (i
= 1; i
< ((size_t) cbNeeded
/ sizeof (HMODULE
)); i
++)
1163 static char dll_name
[MAX_PATH
];
1165 if (!(*win32_GetModuleInformation
) (current_process_handle
,
1170 if ((*win32_GetModuleFileNameExA
) (current_process_handle
,
1176 if (load_addr
!= nullptr && mi
.lpBaseOfDll
!= load_addr
)
1179 const char *name
= dll_name
;
1180 /* Convert the DLL path of 32bit processes returned by
1181 GetModuleFileNameEx from the 64bit system directory to the
1182 32bit syswow64 directory if necessary. */
1183 std::string syswow_dll_path
;
1184 if (convert_syswow_dir
1185 && strncasecmp (dll_name
, system_dir
, system_dir_len
) == 0
1186 && strchr (dll_name
+ system_dir_len
, '\\') == nullptr)
1188 syswow_dll_path
= syswow_dir
;
1189 syswow_dll_path
+= dll_name
+ system_dir_len
;
1190 name
= syswow_dll_path
.c_str();
1193 if (load_addr
!= nullptr)
1195 if (name
!= dll_name
)
1196 strcpy (dll_name
, name
);
1200 win32_add_one_solib (name
, (CORE_ADDR
) (uintptr_t) mi
.lpBaseOfDll
);
1205 /* Iterate over all DLLs currently mapped by our inferior, and
1206 add them to our list of solibs. */
1209 win32_add_all_dlls (void)
1211 win32_add_dll (NULL
);
1214 /* See nat/windows-nat.h. */
1217 windows_nat::handle_load_dll ()
1219 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
1220 const char *dll_name
;
1222 dll_name
= get_image_name (current_process_handle
,
1223 event
->lpImageName
, event
->fUnicode
);
1224 if (dll_name
== nullptr
1225 && event
->lpBaseOfDll
!= nullptr)
1226 dll_name
= win32_add_dll (event
->lpBaseOfDll
);
1227 if (dll_name
== nullptr)
1230 win32_add_one_solib (dll_name
, (CORE_ADDR
) (uintptr_t) event
->lpBaseOfDll
);
1233 /* See nat/windows-nat.h. */
1236 windows_nat::handle_unload_dll ()
1238 CORE_ADDR load_addr
=
1239 (CORE_ADDR
) (uintptr_t) current_event
.u
.UnloadDll
.lpBaseOfDll
;
1241 /* The symbols in a dll are offset by 0x1000, which is the
1242 offset from 0 of the first byte in an image - because
1243 of the file header and the section alignment. */
1244 load_addr
+= 0x1000;
1245 unloaded_dll (NULL
, load_addr
);
1249 suspend_one_thread (thread_info
*thread
)
1251 windows_thread_info
*th
= (windows_thread_info
*) thread_target_data (thread
);
1257 fake_breakpoint_event (void)
1259 OUTMSG2(("fake_breakpoint_event\n"));
1261 faked_breakpoint
= 1;
1263 memset (¤t_event
, 0, sizeof (current_event
));
1264 current_event
.dwThreadId
= main_thread_id
;
1265 current_event
.dwDebugEventCode
= EXCEPTION_DEBUG_EVENT
;
1266 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1267 = EXCEPTION_BREAKPOINT
;
1269 for_each_thread (suspend_one_thread
);
1272 /* See nat/windows-nat.h. */
1275 windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD
*rec
)
1280 /* See nat/windows-nat.h. */
1283 windows_nat::handle_access_violation (const EXCEPTION_RECORD
*rec
)
1288 /* A helper function that will, if needed, set
1289 'stopped_at_software_breakpoint' on the thread and adjust the
1295 struct regcache
*regcache
= get_thread_regcache (current_thread
, 1);
1296 child_fetch_inferior_registers (regcache
, -1);
1298 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
1299 DONT_INVALIDATE_CONTEXT
);
1300 th
->stopped_at_software_breakpoint
= false;
1302 if (current_event
.dwDebugEventCode
== EXCEPTION_DEBUG_EVENT
1303 && ((current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1304 == EXCEPTION_BREAKPOINT
)
1305 || (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1306 == STATUS_WX86_BREAKPOINT
))
1307 && child_initialization_done
)
1309 th
->stopped_at_software_breakpoint
= true;
1310 CORE_ADDR pc
= regcache_read_pc (regcache
);
1311 CORE_ADDR sw_breakpoint_pc
= pc
- the_low_target
.decr_pc_after_break
;
1312 regcache_write_pc (regcache
, sw_breakpoint_pc
);
1316 /* Get the next event from the child. */
1319 get_child_debug_event (DWORD
*continue_status
,
1320 struct target_waitstatus
*ourstatus
)
1324 last_sig
= GDB_SIGNAL_0
;
1325 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1326 *continue_status
= DBG_CONTINUE
;
1328 /* Check if GDB sent us an interrupt request. */
1329 check_remote_input_interrupt_request ();
1331 if (soft_interrupt_requested
)
1333 soft_interrupt_requested
= 0;
1334 fake_breakpoint_event ();
1340 gdb::optional
<pending_stop
> stop
= fetch_pending_stop (debug_threads
);
1341 if (stop
.has_value ())
1343 *ourstatus
= stop
->status
;
1344 current_event
= stop
->event
;
1345 ptid
= debug_event_ptid (¤t_event
);
1346 current_thread
= find_thread_ptid (ptid
);
1350 /* Keep the wait time low enough for comfortable remote
1351 interruption, but high enough so gdbserver doesn't become a
1353 if (!wait_for_debug_event (¤t_event
, 250))
1355 DWORD e
= GetLastError();
1357 if (e
== ERROR_PIPE_NOT_CONNECTED
)
1359 /* This will happen if the loader fails to succesfully
1360 load the application, e.g., if the main executable
1361 tries to pull in a non-existing export from a
1363 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1364 ourstatus
->value
.integer
= 1;
1374 switch (current_event
.dwDebugEventCode
)
1376 case CREATE_THREAD_DEBUG_EVENT
:
1377 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1378 "for pid=%u tid=%x)\n",
1379 (unsigned) current_event
.dwProcessId
,
1380 (unsigned) current_event
.dwThreadId
));
1382 /* Record the existence of this thread. */
1383 child_add_thread (current_event
.dwProcessId
,
1384 current_event
.dwThreadId
,
1385 current_event
.u
.CreateThread
.hThread
,
1386 current_event
.u
.CreateThread
.lpThreadLocalBase
);
1389 case EXIT_THREAD_DEBUG_EVENT
:
1390 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1391 "for pid=%u tid=%x\n",
1392 (unsigned) current_event
.dwProcessId
,
1393 (unsigned) current_event
.dwThreadId
));
1394 child_delete_thread (current_event
.dwProcessId
,
1395 current_event
.dwThreadId
);
1397 current_thread
= get_first_thread ();
1400 case CREATE_PROCESS_DEBUG_EVENT
:
1401 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1402 "for pid=%u tid=%x\n",
1403 (unsigned) current_event
.dwProcessId
,
1404 (unsigned) current_event
.dwThreadId
));
1405 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1407 if (open_process_used
)
1409 CloseHandle (current_process_handle
);
1410 open_process_used
= false;
1413 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1414 main_thread_id
= current_event
.dwThreadId
;
1416 /* Add the main thread. */
1417 child_add_thread (current_event
.dwProcessId
,
1419 current_event
.u
.CreateProcessInfo
.hThread
,
1420 current_event
.u
.CreateProcessInfo
.lpThreadLocalBase
);
1423 case EXIT_PROCESS_DEBUG_EVENT
:
1424 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1425 "for pid=%u tid=%x\n",
1426 (unsigned) current_event
.dwProcessId
,
1427 (unsigned) current_event
.dwThreadId
));
1429 DWORD exit_status
= current_event
.u
.ExitProcess
.dwExitCode
;
1430 /* If the exit status looks like a fatal exception, but we
1431 don't recognize the exception's code, make the original
1432 exit status value available, to avoid losing information. */
1434 = WIFSIGNALED (exit_status
) ? WTERMSIG (exit_status
) : -1;
1435 if (exit_signal
== -1)
1437 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1438 ourstatus
->value
.integer
= exit_status
;
1442 ourstatus
->kind
= TARGET_WAITKIND_SIGNALLED
;
1443 ourstatus
->value
.sig
= gdb_signal_from_host (exit_signal
);
1446 child_continue (DBG_CONTINUE
, desired_stop_thread_id
);
1449 case LOAD_DLL_DEBUG_EVENT
:
1450 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1451 "for pid=%u tid=%x\n",
1452 (unsigned) current_event
.dwProcessId
,
1453 (unsigned) current_event
.dwThreadId
));
1454 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1455 if (! child_initialization_done
)
1459 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1460 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
1463 case UNLOAD_DLL_DEBUG_EVENT
:
1464 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1465 "for pid=%u tid=%x\n",
1466 (unsigned) current_event
.dwProcessId
,
1467 (unsigned) current_event
.dwThreadId
));
1468 if (! child_initialization_done
)
1470 handle_unload_dll ();
1471 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1472 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
1475 case EXCEPTION_DEBUG_EVENT
:
1476 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1477 "for pid=%u tid=%x\n",
1478 (unsigned) current_event
.dwProcessId
,
1479 (unsigned) current_event
.dwThreadId
));
1480 if (handle_exception (ourstatus
, debug_threads
)
1481 == HANDLE_EXCEPTION_UNHANDLED
)
1482 *continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1485 case OUTPUT_DEBUG_STRING_EVENT
:
1486 /* A message from the kernel (or Cygwin). */
1487 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1488 "for pid=%u tid=%x\n",
1489 (unsigned) current_event
.dwProcessId
,
1490 (unsigned) current_event
.dwThreadId
));
1491 handle_output_debug_string (nullptr);
1495 OUTMSG2 (("gdbserver: kernel event unknown "
1496 "for pid=%u tid=%x code=%x\n",
1497 (unsigned) current_event
.dwProcessId
,
1498 (unsigned) current_event
.dwThreadId
,
1499 (unsigned) current_event
.dwDebugEventCode
));
1503 ptid
= debug_event_ptid (¤t_event
);
1505 if (desired_stop_thread_id
!= -1 && desired_stop_thread_id
!= ptid
.lwp ())
1507 /* Pending stop. See the comment by the definition of
1508 "pending_stops" for details on why this is needed. */
1509 OUTMSG2 (("get_windows_debug_event - "
1510 "unexpected stop in 0x%lx (expecting 0x%x)\n",
1511 ptid
.lwp (), desired_stop_thread_id
));
1513 pending_stops
.push_back ({(DWORD
) ptid
.lwp (), *ourstatus
, current_event
});
1514 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1517 current_thread
= find_thread_ptid (ptid
);
1522 /* Wait for the inferior process to change state.
1523 STATUS will be filled in with a response code to send to GDB.
1524 Returns the signal which caused the process to stop. */
1526 win32_process_target::wait (ptid_t ptid
, target_waitstatus
*ourstatus
,
1527 target_wait_flags options
)
1529 if (cached_status
.kind
!= TARGET_WAITKIND_IGNORE
)
1531 /* The core always does a wait after creating the inferior, and
1532 do_initial_child_stuff already ran the inferior to the
1533 initial breakpoint (or an exit, if creating the process
1534 fails). Report it now. */
1535 *ourstatus
= cached_status
;
1536 cached_status
.kind
= TARGET_WAITKIND_IGNORE
;
1537 return debug_event_ptid (¤t_event
);
1542 DWORD continue_status
;
1543 if (!get_child_debug_event (&continue_status
, ourstatus
))
1546 switch (ourstatus
->kind
)
1548 case TARGET_WAITKIND_EXITED
:
1549 OUTMSG2 (("Child exited with retcode = %x\n",
1550 ourstatus
->value
.integer
));
1551 win32_clear_inferiors ();
1552 return ptid_t (current_event
.dwProcessId
);
1553 case TARGET_WAITKIND_STOPPED
:
1554 case TARGET_WAITKIND_SIGNALLED
:
1555 case TARGET_WAITKIND_LOADED
:
1557 OUTMSG2 (("Child Stopped with signal = %d \n",
1558 ourstatus
->value
.sig
));
1560 return debug_event_ptid (¤t_event
);
1563 OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus
->kind
));
1565 case TARGET_WAITKIND_SPURIOUS
:
1566 /* do nothing, just continue */
1567 child_continue (continue_status
, desired_stop_thread_id
);
1573 /* Fetch registers from the inferior process.
1574 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1576 win32_process_target::fetch_registers (regcache
*regcache
, int regno
)
1578 child_fetch_inferior_registers (regcache
, regno
);
1581 /* Store registers to the inferior process.
1582 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1584 win32_process_target::store_registers (regcache
*regcache
, int regno
)
1586 child_store_inferior_registers (regcache
, regno
);
1589 /* Read memory from the inferior process. This should generally be
1590 called through read_inferior_memory, which handles breakpoint shadowing.
1591 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1593 win32_process_target::read_memory (CORE_ADDR memaddr
, unsigned char *myaddr
,
1596 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 0, 0) != len
;
1599 /* Write memory to the inferior process. This should generally be
1600 called through write_inferior_memory, which handles breakpoint shadowing.
1601 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1602 Returns 0 on success and errno on failure. */
1604 win32_process_target::write_memory (CORE_ADDR memaddr
,
1605 const unsigned char *myaddr
, int len
)
1607 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 1, 0) != len
;
1610 /* Send an interrupt request to the inferior process. */
1612 win32_process_target::request_interrupt ()
1614 winapi_DebugBreakProcess DebugBreakProcess
;
1615 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent
;
1617 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
1619 GenerateConsoleCtrlEvent
= GETPROCADDRESS (dll
, GenerateConsoleCtrlEvent
);
1621 if (GenerateConsoleCtrlEvent
!= NULL
1622 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, current_process_id
))
1625 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1626 not a process group id.
1627 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1628 breakpoint exception in the interior process. */
1630 DebugBreakProcess
= GETPROCADDRESS (dll
, DebugBreakProcess
);
1632 if (DebugBreakProcess
!= NULL
1633 && DebugBreakProcess (current_process_handle
))
1636 /* Last resort, suspend all threads manually. */
1637 soft_interrupt_requested
= 1;
1641 win32_process_target::supports_hardware_single_step ()
1647 win32_process_target::supports_qxfer_siginfo ()
1652 /* Write Windows signal info. */
1655 win32_process_target::qxfer_siginfo (const char *annex
,
1656 unsigned char *readbuf
,
1657 unsigned const char *writebuf
,
1658 CORE_ADDR offset
, int len
)
1660 if (siginfo_er
.ExceptionCode
== 0)
1663 if (readbuf
== nullptr)
1666 char *buf
= (char *) &siginfo_er
;
1667 size_t bufsize
= sizeof (siginfo_er
);
1670 EXCEPTION_RECORD32 er32
;
1673 buf
= (char *) &er32
;
1674 bufsize
= sizeof (er32
);
1676 er32
.ExceptionCode
= siginfo_er
.ExceptionCode
;
1677 er32
.ExceptionFlags
= siginfo_er
.ExceptionFlags
;
1678 er32
.ExceptionRecord
= (uintptr_t) siginfo_er
.ExceptionRecord
;
1679 er32
.ExceptionAddress
= (uintptr_t) siginfo_er
.ExceptionAddress
;
1680 er32
.NumberParameters
= siginfo_er
.NumberParameters
;
1682 for (i
= 0; i
< EXCEPTION_MAXIMUM_PARAMETERS
; i
++)
1683 er32
.ExceptionInformation
[i
] = siginfo_er
.ExceptionInformation
[i
];
1687 if (offset
> bufsize
)
1690 if (offset
+ len
> bufsize
)
1691 len
= bufsize
- offset
;
1693 memcpy (readbuf
, buf
+ offset
, len
);
1699 win32_process_target::supports_get_tib_address ()
1704 /* Write Windows OS Thread Information Block address. */
1707 win32_process_target::get_tib_address (ptid_t ptid
, CORE_ADDR
*addr
)
1709 windows_thread_info
*th
;
1710 th
= thread_rec (ptid
, DONT_INVALIDATE_CONTEXT
);
1714 *addr
= th
->thread_local_base
;
1718 /* Implementation of the target_ops method "sw_breakpoint_from_kind". */
1721 win32_process_target::sw_breakpoint_from_kind (int kind
, int *size
)
1723 *size
= the_low_target
.breakpoint_len
;
1724 return the_low_target
.breakpoint
;
1728 win32_process_target::stopped_by_sw_breakpoint ()
1730 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
1731 DONT_INVALIDATE_CONTEXT
);
1732 return th
== nullptr ? false : th
->stopped_at_software_breakpoint
;
1736 win32_process_target::supports_stopped_by_sw_breakpoint ()
1742 win32_process_target::read_pc (struct regcache
*regcache
)
1744 return (*the_low_target
.get_pc
) (regcache
);
1748 win32_process_target::write_pc (struct regcache
*regcache
, CORE_ADDR pc
)
1750 return (*the_low_target
.set_pc
) (regcache
, pc
);
1753 /* The win32 target ops object. */
1755 static win32_process_target the_win32_target
;
1757 /* Initialize the Win32 backend. */
1759 initialize_low (void)
1761 set_target_ops (&the_win32_target
);
1762 the_low_target
.arch_setup ();
1765 /* These functions are loaded dynamically, because they are not available
1767 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
1768 win32_Wow64GetThreadContext
= GETPROCADDRESS (dll
, Wow64GetThreadContext
);
1769 win32_Wow64SetThreadContext
= GETPROCADDRESS (dll
, Wow64SetThreadContext
);