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
);
1225 if (dll_name
== nullptr
1226 && event
->lpBaseOfDll
!= nullptr)
1227 dll_name
= win32_add_dll (event
->lpBaseOfDll
);
1229 if (dll_name
== nullptr)
1232 win32_add_one_solib (dll_name
, (CORE_ADDR
) (uintptr_t) event
->lpBaseOfDll
);
1235 /* See nat/windows-nat.h. */
1238 windows_nat::handle_unload_dll ()
1240 CORE_ADDR load_addr
=
1241 (CORE_ADDR
) (uintptr_t) current_event
.u
.UnloadDll
.lpBaseOfDll
;
1243 /* The symbols in a dll are offset by 0x1000, which is the
1244 offset from 0 of the first byte in an image - because
1245 of the file header and the section alignment. */
1246 load_addr
+= 0x1000;
1247 unloaded_dll (NULL
, load_addr
);
1251 suspend_one_thread (thread_info
*thread
)
1253 windows_thread_info
*th
= (windows_thread_info
*) thread_target_data (thread
);
1259 fake_breakpoint_event (void)
1261 OUTMSG2(("fake_breakpoint_event\n"));
1263 faked_breakpoint
= 1;
1265 memset (¤t_event
, 0, sizeof (current_event
));
1266 current_event
.dwThreadId
= main_thread_id
;
1267 current_event
.dwDebugEventCode
= EXCEPTION_DEBUG_EVENT
;
1268 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1269 = EXCEPTION_BREAKPOINT
;
1271 for_each_thread (suspend_one_thread
);
1274 /* See nat/windows-nat.h. */
1277 windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD
*rec
)
1282 /* See nat/windows-nat.h. */
1285 windows_nat::handle_access_violation (const EXCEPTION_RECORD
*rec
)
1290 /* A helper function that will, if needed, set
1291 'stopped_at_software_breakpoint' on the thread and adjust the
1297 struct regcache
*regcache
= get_thread_regcache (current_thread
, 1);
1298 child_fetch_inferior_registers (regcache
, -1);
1300 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
1301 DONT_INVALIDATE_CONTEXT
);
1302 th
->stopped_at_software_breakpoint
= false;
1304 if (current_event
.dwDebugEventCode
== EXCEPTION_DEBUG_EVENT
1305 && ((current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1306 == EXCEPTION_BREAKPOINT
)
1307 || (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1308 == STATUS_WX86_BREAKPOINT
))
1309 && child_initialization_done
)
1311 th
->stopped_at_software_breakpoint
= true;
1312 CORE_ADDR pc
= regcache_read_pc (regcache
);
1313 CORE_ADDR sw_breakpoint_pc
= pc
- the_low_target
.decr_pc_after_break
;
1314 regcache_write_pc (regcache
, sw_breakpoint_pc
);
1318 /* Get the next event from the child. */
1321 get_child_debug_event (DWORD
*continue_status
,
1322 struct target_waitstatus
*ourstatus
)
1326 last_sig
= GDB_SIGNAL_0
;
1327 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1328 *continue_status
= DBG_CONTINUE
;
1330 /* Check if GDB sent us an interrupt request. */
1331 check_remote_input_interrupt_request ();
1333 if (soft_interrupt_requested
)
1335 soft_interrupt_requested
= 0;
1336 fake_breakpoint_event ();
1342 gdb::optional
<pending_stop
> stop
= fetch_pending_stop (debug_threads
);
1343 if (stop
.has_value ())
1345 *ourstatus
= stop
->status
;
1346 current_event
= stop
->event
;
1347 ptid
= debug_event_ptid (¤t_event
);
1348 current_thread
= find_thread_ptid (ptid
);
1352 /* Keep the wait time low enough for comfortable remote
1353 interruption, but high enough so gdbserver doesn't become a
1355 if (!wait_for_debug_event (¤t_event
, 250))
1357 DWORD e
= GetLastError();
1359 if (e
== ERROR_PIPE_NOT_CONNECTED
)
1361 /* This will happen if the loader fails to succesfully
1362 load the application, e.g., if the main executable
1363 tries to pull in a non-existing export from a
1365 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1366 ourstatus
->value
.integer
= 1;
1376 switch (current_event
.dwDebugEventCode
)
1378 case CREATE_THREAD_DEBUG_EVENT
:
1379 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1380 "for pid=%u tid=%x)\n",
1381 (unsigned) current_event
.dwProcessId
,
1382 (unsigned) current_event
.dwThreadId
));
1384 /* Record the existence of this thread. */
1385 child_add_thread (current_event
.dwProcessId
,
1386 current_event
.dwThreadId
,
1387 current_event
.u
.CreateThread
.hThread
,
1388 current_event
.u
.CreateThread
.lpThreadLocalBase
);
1391 case EXIT_THREAD_DEBUG_EVENT
:
1392 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1393 "for pid=%u tid=%x\n",
1394 (unsigned) current_event
.dwProcessId
,
1395 (unsigned) current_event
.dwThreadId
));
1396 child_delete_thread (current_event
.dwProcessId
,
1397 current_event
.dwThreadId
);
1399 current_thread
= get_first_thread ();
1402 case CREATE_PROCESS_DEBUG_EVENT
:
1403 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1404 "for pid=%u tid=%x\n",
1405 (unsigned) current_event
.dwProcessId
,
1406 (unsigned) current_event
.dwThreadId
));
1407 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1409 if (open_process_used
)
1411 CloseHandle (current_process_handle
);
1412 open_process_used
= false;
1415 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1416 main_thread_id
= current_event
.dwThreadId
;
1418 /* Add the main thread. */
1419 child_add_thread (current_event
.dwProcessId
,
1421 current_event
.u
.CreateProcessInfo
.hThread
,
1422 current_event
.u
.CreateProcessInfo
.lpThreadLocalBase
);
1425 case EXIT_PROCESS_DEBUG_EVENT
:
1426 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1427 "for pid=%u tid=%x\n",
1428 (unsigned) current_event
.dwProcessId
,
1429 (unsigned) current_event
.dwThreadId
));
1431 DWORD exit_status
= current_event
.u
.ExitProcess
.dwExitCode
;
1432 /* If the exit status looks like a fatal exception, but we
1433 don't recognize the exception's code, make the original
1434 exit status value available, to avoid losing information. */
1436 = WIFSIGNALED (exit_status
) ? WTERMSIG (exit_status
) : -1;
1437 if (exit_signal
== -1)
1439 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1440 ourstatus
->value
.integer
= exit_status
;
1444 ourstatus
->kind
= TARGET_WAITKIND_SIGNALLED
;
1445 ourstatus
->value
.sig
= gdb_signal_from_host (exit_signal
);
1448 child_continue (DBG_CONTINUE
, desired_stop_thread_id
);
1451 case LOAD_DLL_DEBUG_EVENT
:
1452 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1453 "for pid=%u tid=%x\n",
1454 (unsigned) current_event
.dwProcessId
,
1455 (unsigned) current_event
.dwThreadId
));
1456 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1457 if (! child_initialization_done
)
1461 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1462 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
1465 case UNLOAD_DLL_DEBUG_EVENT
:
1466 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1467 "for pid=%u tid=%x\n",
1468 (unsigned) current_event
.dwProcessId
,
1469 (unsigned) current_event
.dwThreadId
));
1470 if (! child_initialization_done
)
1472 handle_unload_dll ();
1473 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1474 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
1477 case EXCEPTION_DEBUG_EVENT
:
1478 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1479 "for pid=%u tid=%x\n",
1480 (unsigned) current_event
.dwProcessId
,
1481 (unsigned) current_event
.dwThreadId
));
1482 if (handle_exception (ourstatus
, debug_threads
)
1483 == HANDLE_EXCEPTION_UNHANDLED
)
1484 *continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1487 case OUTPUT_DEBUG_STRING_EVENT
:
1488 /* A message from the kernel (or Cygwin). */
1489 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1490 "for pid=%u tid=%x\n",
1491 (unsigned) current_event
.dwProcessId
,
1492 (unsigned) current_event
.dwThreadId
));
1493 handle_output_debug_string (nullptr);
1497 OUTMSG2 (("gdbserver: kernel event unknown "
1498 "for pid=%u tid=%x code=%x\n",
1499 (unsigned) current_event
.dwProcessId
,
1500 (unsigned) current_event
.dwThreadId
,
1501 (unsigned) current_event
.dwDebugEventCode
));
1505 ptid
= debug_event_ptid (¤t_event
);
1507 if (desired_stop_thread_id
!= -1 && desired_stop_thread_id
!= ptid
.lwp ())
1509 /* Pending stop. See the comment by the definition of
1510 "pending_stops" for details on why this is needed. */
1511 OUTMSG2 (("get_windows_debug_event - "
1512 "unexpected stop in 0x%lx (expecting 0x%x)\n",
1513 ptid
.lwp (), desired_stop_thread_id
));
1515 pending_stops
.push_back ({(DWORD
) ptid
.lwp (), *ourstatus
, current_event
});
1516 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1519 current_thread
= find_thread_ptid (ptid
);
1524 /* Wait for the inferior process to change state.
1525 STATUS will be filled in with a response code to send to GDB.
1526 Returns the signal which caused the process to stop. */
1528 win32_process_target::wait (ptid_t ptid
, target_waitstatus
*ourstatus
,
1529 target_wait_flags options
)
1531 if (cached_status
.kind
!= TARGET_WAITKIND_IGNORE
)
1533 /* The core always does a wait after creating the inferior, and
1534 do_initial_child_stuff already ran the inferior to the
1535 initial breakpoint (or an exit, if creating the process
1536 fails). Report it now. */
1537 *ourstatus
= cached_status
;
1538 cached_status
.kind
= TARGET_WAITKIND_IGNORE
;
1539 return debug_event_ptid (¤t_event
);
1544 DWORD continue_status
;
1545 if (!get_child_debug_event (&continue_status
, ourstatus
))
1548 switch (ourstatus
->kind
)
1550 case TARGET_WAITKIND_EXITED
:
1551 OUTMSG2 (("Child exited with retcode = %x\n",
1552 ourstatus
->value
.integer
));
1553 win32_clear_inferiors ();
1554 return ptid_t (current_event
.dwProcessId
);
1555 case TARGET_WAITKIND_STOPPED
:
1556 case TARGET_WAITKIND_SIGNALLED
:
1557 case TARGET_WAITKIND_LOADED
:
1559 OUTMSG2 (("Child Stopped with signal = %d \n",
1560 ourstatus
->value
.sig
));
1562 return debug_event_ptid (¤t_event
);
1565 OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus
->kind
));
1567 case TARGET_WAITKIND_SPURIOUS
:
1568 /* do nothing, just continue */
1569 child_continue (continue_status
, desired_stop_thread_id
);
1575 /* Fetch registers from the inferior process.
1576 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1578 win32_process_target::fetch_registers (regcache
*regcache
, int regno
)
1580 child_fetch_inferior_registers (regcache
, regno
);
1583 /* Store registers to the inferior process.
1584 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1586 win32_process_target::store_registers (regcache
*regcache
, int regno
)
1588 child_store_inferior_registers (regcache
, regno
);
1591 /* Read memory from the inferior process. This should generally be
1592 called through read_inferior_memory, which handles breakpoint shadowing.
1593 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1595 win32_process_target::read_memory (CORE_ADDR memaddr
, unsigned char *myaddr
,
1598 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 0, 0) != len
;
1601 /* Write memory to the inferior process. This should generally be
1602 called through write_inferior_memory, which handles breakpoint shadowing.
1603 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1604 Returns 0 on success and errno on failure. */
1606 win32_process_target::write_memory (CORE_ADDR memaddr
,
1607 const unsigned char *myaddr
, int len
)
1609 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 1, 0) != len
;
1612 /* Send an interrupt request to the inferior process. */
1614 win32_process_target::request_interrupt ()
1616 winapi_DebugBreakProcess DebugBreakProcess
;
1617 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent
;
1619 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
1621 GenerateConsoleCtrlEvent
= GETPROCADDRESS (dll
, GenerateConsoleCtrlEvent
);
1623 if (GenerateConsoleCtrlEvent
!= NULL
1624 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, current_process_id
))
1627 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1628 not a process group id.
1629 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1630 breakpoint exception in the interior process. */
1632 DebugBreakProcess
= GETPROCADDRESS (dll
, DebugBreakProcess
);
1634 if (DebugBreakProcess
!= NULL
1635 && DebugBreakProcess (current_process_handle
))
1638 /* Last resort, suspend all threads manually. */
1639 soft_interrupt_requested
= 1;
1643 win32_process_target::supports_hardware_single_step ()
1649 win32_process_target::supports_qxfer_siginfo ()
1654 /* Write Windows signal info. */
1657 win32_process_target::qxfer_siginfo (const char *annex
,
1658 unsigned char *readbuf
,
1659 unsigned const char *writebuf
,
1660 CORE_ADDR offset
, int len
)
1662 if (siginfo_er
.ExceptionCode
== 0)
1665 if (readbuf
== nullptr)
1668 char *buf
= (char *) &siginfo_er
;
1669 size_t bufsize
= sizeof (siginfo_er
);
1672 EXCEPTION_RECORD32 er32
;
1675 buf
= (char *) &er32
;
1676 bufsize
= sizeof (er32
);
1678 er32
.ExceptionCode
= siginfo_er
.ExceptionCode
;
1679 er32
.ExceptionFlags
= siginfo_er
.ExceptionFlags
;
1680 er32
.ExceptionRecord
= (uintptr_t) siginfo_er
.ExceptionRecord
;
1681 er32
.ExceptionAddress
= (uintptr_t) siginfo_er
.ExceptionAddress
;
1682 er32
.NumberParameters
= siginfo_er
.NumberParameters
;
1684 for (i
= 0; i
< EXCEPTION_MAXIMUM_PARAMETERS
; i
++)
1685 er32
.ExceptionInformation
[i
] = siginfo_er
.ExceptionInformation
[i
];
1689 if (offset
> bufsize
)
1692 if (offset
+ len
> bufsize
)
1693 len
= bufsize
- offset
;
1695 memcpy (readbuf
, buf
+ offset
, len
);
1701 win32_process_target::supports_get_tib_address ()
1706 /* Write Windows OS Thread Information Block address. */
1709 win32_process_target::get_tib_address (ptid_t ptid
, CORE_ADDR
*addr
)
1711 windows_thread_info
*th
;
1712 th
= thread_rec (ptid
, DONT_INVALIDATE_CONTEXT
);
1716 *addr
= th
->thread_local_base
;
1720 /* Implementation of the target_ops method "sw_breakpoint_from_kind". */
1723 win32_process_target::sw_breakpoint_from_kind (int kind
, int *size
)
1725 *size
= the_low_target
.breakpoint_len
;
1726 return the_low_target
.breakpoint
;
1730 win32_process_target::stopped_by_sw_breakpoint ()
1732 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
1733 DONT_INVALIDATE_CONTEXT
);
1734 return th
== nullptr ? false : th
->stopped_at_software_breakpoint
;
1738 win32_process_target::supports_stopped_by_sw_breakpoint ()
1744 win32_process_target::read_pc (struct regcache
*regcache
)
1746 return (*the_low_target
.get_pc
) (regcache
);
1750 win32_process_target::write_pc (struct regcache
*regcache
, CORE_ADDR pc
)
1752 return (*the_low_target
.set_pc
) (regcache
, pc
);
1755 /* The win32 target ops object. */
1757 static win32_process_target the_win32_target
;
1759 /* Initialize the Win32 backend. */
1761 initialize_low (void)
1763 set_target_ops (&the_win32_target
);
1764 the_low_target
.arch_setup ();
1767 /* These functions are loaded dynamically, because they are not available
1769 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
1770 win32_Wow64GetThreadContext
= GETPROCADDRESS (dll
, Wow64GetThreadContext
);
1771 win32_Wow64SetThreadContext
= GETPROCADDRESS (dll
, Wow64SetThreadContext
);