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 typedef HANDLE (WINAPI
*winapi_CreateToolhelp32Snapshot
) (DWORD
, DWORD
);
1215 typedef BOOL (WINAPI
*winapi_Module32First
) (HANDLE
, LPMODULEENTRY32
);
1216 typedef BOOL (WINAPI
*winapi_Module32Next
) (HANDLE
, LPMODULEENTRY32
);
1218 /* See nat/windows-nat.h. */
1221 windows_nat::handle_load_dll ()
1223 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
1224 const char *dll_name
;
1226 dll_name
= get_image_name (current_process_handle
,
1227 event
->lpImageName
, event
->fUnicode
);
1229 if (dll_name
== nullptr
1230 && event
->lpBaseOfDll
!= nullptr)
1231 dll_name
= win32_add_dll (event
->lpBaseOfDll
);
1233 if (dll_name
== nullptr)
1236 win32_add_one_solib (dll_name
, (CORE_ADDR
) (uintptr_t) event
->lpBaseOfDll
);
1239 /* See nat/windows-nat.h. */
1242 windows_nat::handle_unload_dll ()
1244 CORE_ADDR load_addr
=
1245 (CORE_ADDR
) (uintptr_t) current_event
.u
.UnloadDll
.lpBaseOfDll
;
1247 /* The symbols in a dll are offset by 0x1000, which is the
1248 offset from 0 of the first byte in an image - because
1249 of the file header and the section alignment. */
1250 load_addr
+= 0x1000;
1251 unloaded_dll (NULL
, load_addr
);
1255 suspend_one_thread (thread_info
*thread
)
1257 windows_thread_info
*th
= (windows_thread_info
*) thread_target_data (thread
);
1263 fake_breakpoint_event (void)
1265 OUTMSG2(("fake_breakpoint_event\n"));
1267 faked_breakpoint
= 1;
1269 memset (¤t_event
, 0, sizeof (current_event
));
1270 current_event
.dwThreadId
= main_thread_id
;
1271 current_event
.dwDebugEventCode
= EXCEPTION_DEBUG_EVENT
;
1272 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1273 = EXCEPTION_BREAKPOINT
;
1275 for_each_thread (suspend_one_thread
);
1278 /* See nat/windows-nat.h. */
1281 windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD
*rec
)
1286 /* See nat/windows-nat.h. */
1289 windows_nat::handle_access_violation (const EXCEPTION_RECORD
*rec
)
1294 /* A helper function that will, if needed, set
1295 'stopped_at_software_breakpoint' on the thread and adjust the
1301 struct regcache
*regcache
= get_thread_regcache (current_thread
, 1);
1302 child_fetch_inferior_registers (regcache
, -1);
1304 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
1305 DONT_INVALIDATE_CONTEXT
);
1306 th
->stopped_at_software_breakpoint
= false;
1308 if (current_event
.dwDebugEventCode
== EXCEPTION_DEBUG_EVENT
1309 && ((current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1310 == EXCEPTION_BREAKPOINT
)
1311 || (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
1312 == STATUS_WX86_BREAKPOINT
))
1313 && child_initialization_done
)
1315 th
->stopped_at_software_breakpoint
= true;
1316 CORE_ADDR pc
= regcache_read_pc (regcache
);
1317 CORE_ADDR sw_breakpoint_pc
= pc
- the_low_target
.decr_pc_after_break
;
1318 regcache_write_pc (regcache
, sw_breakpoint_pc
);
1322 /* Get the next event from the child. */
1325 get_child_debug_event (DWORD
*continue_status
,
1326 struct target_waitstatus
*ourstatus
)
1330 last_sig
= GDB_SIGNAL_0
;
1331 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1332 *continue_status
= DBG_CONTINUE
;
1334 /* Check if GDB sent us an interrupt request. */
1335 check_remote_input_interrupt_request ();
1337 if (soft_interrupt_requested
)
1339 soft_interrupt_requested
= 0;
1340 fake_breakpoint_event ();
1346 gdb::optional
<pending_stop
> stop
= fetch_pending_stop (debug_threads
);
1347 if (stop
.has_value ())
1349 *ourstatus
= stop
->status
;
1350 current_event
= stop
->event
;
1351 ptid
= debug_event_ptid (¤t_event
);
1352 current_thread
= find_thread_ptid (ptid
);
1356 /* Keep the wait time low enough for comfortable remote
1357 interruption, but high enough so gdbserver doesn't become a
1359 if (!wait_for_debug_event (¤t_event
, 250))
1361 DWORD e
= GetLastError();
1363 if (e
== ERROR_PIPE_NOT_CONNECTED
)
1365 /* This will happen if the loader fails to succesfully
1366 load the application, e.g., if the main executable
1367 tries to pull in a non-existing export from a
1369 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1370 ourstatus
->value
.integer
= 1;
1380 switch (current_event
.dwDebugEventCode
)
1382 case CREATE_THREAD_DEBUG_EVENT
:
1383 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1384 "for pid=%u tid=%x)\n",
1385 (unsigned) current_event
.dwProcessId
,
1386 (unsigned) current_event
.dwThreadId
));
1388 /* Record the existence of this thread. */
1389 child_add_thread (current_event
.dwProcessId
,
1390 current_event
.dwThreadId
,
1391 current_event
.u
.CreateThread
.hThread
,
1392 current_event
.u
.CreateThread
.lpThreadLocalBase
);
1395 case EXIT_THREAD_DEBUG_EVENT
:
1396 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1397 "for pid=%u tid=%x\n",
1398 (unsigned) current_event
.dwProcessId
,
1399 (unsigned) current_event
.dwThreadId
));
1400 child_delete_thread (current_event
.dwProcessId
,
1401 current_event
.dwThreadId
);
1403 current_thread
= get_first_thread ();
1406 case CREATE_PROCESS_DEBUG_EVENT
:
1407 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1408 "for pid=%u tid=%x\n",
1409 (unsigned) current_event
.dwProcessId
,
1410 (unsigned) current_event
.dwThreadId
));
1411 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1413 if (open_process_used
)
1415 CloseHandle (current_process_handle
);
1416 open_process_used
= false;
1419 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1420 main_thread_id
= current_event
.dwThreadId
;
1422 /* Add the main thread. */
1423 child_add_thread (current_event
.dwProcessId
,
1425 current_event
.u
.CreateProcessInfo
.hThread
,
1426 current_event
.u
.CreateProcessInfo
.lpThreadLocalBase
);
1429 case EXIT_PROCESS_DEBUG_EVENT
:
1430 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1431 "for pid=%u tid=%x\n",
1432 (unsigned) current_event
.dwProcessId
,
1433 (unsigned) current_event
.dwThreadId
));
1435 DWORD exit_status
= current_event
.u
.ExitProcess
.dwExitCode
;
1436 /* If the exit status looks like a fatal exception, but we
1437 don't recognize the exception's code, make the original
1438 exit status value available, to avoid losing information. */
1440 = WIFSIGNALED (exit_status
) ? WTERMSIG (exit_status
) : -1;
1441 if (exit_signal
== -1)
1443 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1444 ourstatus
->value
.integer
= exit_status
;
1448 ourstatus
->kind
= TARGET_WAITKIND_SIGNALLED
;
1449 ourstatus
->value
.sig
= gdb_signal_from_host (exit_signal
);
1452 child_continue (DBG_CONTINUE
, desired_stop_thread_id
);
1455 case LOAD_DLL_DEBUG_EVENT
:
1456 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1457 "for pid=%u tid=%x\n",
1458 (unsigned) current_event
.dwProcessId
,
1459 (unsigned) current_event
.dwThreadId
));
1460 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1461 if (! child_initialization_done
)
1465 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1466 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
1469 case UNLOAD_DLL_DEBUG_EVENT
:
1470 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1471 "for pid=%u tid=%x\n",
1472 (unsigned) current_event
.dwProcessId
,
1473 (unsigned) current_event
.dwThreadId
));
1474 if (! child_initialization_done
)
1476 handle_unload_dll ();
1477 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1478 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
1481 case EXCEPTION_DEBUG_EVENT
:
1482 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1483 "for pid=%u tid=%x\n",
1484 (unsigned) current_event
.dwProcessId
,
1485 (unsigned) current_event
.dwThreadId
));
1486 if (handle_exception (ourstatus
, debug_threads
)
1487 == HANDLE_EXCEPTION_UNHANDLED
)
1488 *continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1491 case OUTPUT_DEBUG_STRING_EVENT
:
1492 /* A message from the kernel (or Cygwin). */
1493 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1494 "for pid=%u tid=%x\n",
1495 (unsigned) current_event
.dwProcessId
,
1496 (unsigned) current_event
.dwThreadId
));
1497 handle_output_debug_string (nullptr);
1501 OUTMSG2 (("gdbserver: kernel event unknown "
1502 "for pid=%u tid=%x code=%x\n",
1503 (unsigned) current_event
.dwProcessId
,
1504 (unsigned) current_event
.dwThreadId
,
1505 (unsigned) current_event
.dwDebugEventCode
));
1509 ptid
= debug_event_ptid (¤t_event
);
1511 if (desired_stop_thread_id
!= -1 && desired_stop_thread_id
!= ptid
.lwp ())
1513 /* Pending stop. See the comment by the definition of
1514 "pending_stops" for details on why this is needed. */
1515 OUTMSG2 (("get_windows_debug_event - "
1516 "unexpected stop in 0x%lx (expecting 0x%x)\n",
1517 ptid
.lwp (), desired_stop_thread_id
));
1519 pending_stops
.push_back ({(DWORD
) ptid
.lwp (), *ourstatus
, current_event
});
1520 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1523 current_thread
= find_thread_ptid (ptid
);
1528 /* Wait for the inferior process to change state.
1529 STATUS will be filled in with a response code to send to GDB.
1530 Returns the signal which caused the process to stop. */
1532 win32_process_target::wait (ptid_t ptid
, target_waitstatus
*ourstatus
,
1533 target_wait_flags options
)
1535 if (cached_status
.kind
!= TARGET_WAITKIND_IGNORE
)
1537 /* The core always does a wait after creating the inferior, and
1538 do_initial_child_stuff already ran the inferior to the
1539 initial breakpoint (or an exit, if creating the process
1540 fails). Report it now. */
1541 *ourstatus
= cached_status
;
1542 cached_status
.kind
= TARGET_WAITKIND_IGNORE
;
1543 return debug_event_ptid (¤t_event
);
1548 DWORD continue_status
;
1549 if (!get_child_debug_event (&continue_status
, ourstatus
))
1552 switch (ourstatus
->kind
)
1554 case TARGET_WAITKIND_EXITED
:
1555 OUTMSG2 (("Child exited with retcode = %x\n",
1556 ourstatus
->value
.integer
));
1557 win32_clear_inferiors ();
1558 return ptid_t (current_event
.dwProcessId
);
1559 case TARGET_WAITKIND_STOPPED
:
1560 case TARGET_WAITKIND_SIGNALLED
:
1561 case TARGET_WAITKIND_LOADED
:
1563 OUTMSG2 (("Child Stopped with signal = %d \n",
1564 ourstatus
->value
.sig
));
1566 return debug_event_ptid (¤t_event
);
1569 OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus
->kind
));
1571 case TARGET_WAITKIND_SPURIOUS
:
1572 /* do nothing, just continue */
1573 child_continue (continue_status
, desired_stop_thread_id
);
1579 /* Fetch registers from the inferior process.
1580 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1582 win32_process_target::fetch_registers (regcache
*regcache
, int regno
)
1584 child_fetch_inferior_registers (regcache
, regno
);
1587 /* Store registers to the inferior process.
1588 If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1590 win32_process_target::store_registers (regcache
*regcache
, int regno
)
1592 child_store_inferior_registers (regcache
, regno
);
1595 /* Read memory from the inferior process. This should generally be
1596 called through read_inferior_memory, which handles breakpoint shadowing.
1597 Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1599 win32_process_target::read_memory (CORE_ADDR memaddr
, unsigned char *myaddr
,
1602 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 0, 0) != len
;
1605 /* Write memory to the inferior process. This should generally be
1606 called through write_inferior_memory, which handles breakpoint shadowing.
1607 Write LEN bytes from the buffer at MYADDR to MEMADDR.
1608 Returns 0 on success and errno on failure. */
1610 win32_process_target::write_memory (CORE_ADDR memaddr
,
1611 const unsigned char *myaddr
, int len
)
1613 return child_xfer_memory (memaddr
, (char *) myaddr
, len
, 1, 0) != len
;
1616 /* Send an interrupt request to the inferior process. */
1618 win32_process_target::request_interrupt ()
1620 winapi_DebugBreakProcess DebugBreakProcess
;
1621 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent
;
1623 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
1625 GenerateConsoleCtrlEvent
= GETPROCADDRESS (dll
, GenerateConsoleCtrlEvent
);
1627 if (GenerateConsoleCtrlEvent
!= NULL
1628 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, current_process_id
))
1631 /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1632 not a process group id.
1633 Fallback to XP/Vista 'DebugBreakProcess', which generates a
1634 breakpoint exception in the interior process. */
1636 DebugBreakProcess
= GETPROCADDRESS (dll
, DebugBreakProcess
);
1638 if (DebugBreakProcess
!= NULL
1639 && DebugBreakProcess (current_process_handle
))
1642 /* Last resort, suspend all threads manually. */
1643 soft_interrupt_requested
= 1;
1647 win32_process_target::supports_hardware_single_step ()
1653 win32_process_target::supports_qxfer_siginfo ()
1658 /* Write Windows signal info. */
1661 win32_process_target::qxfer_siginfo (const char *annex
,
1662 unsigned char *readbuf
,
1663 unsigned const char *writebuf
,
1664 CORE_ADDR offset
, int len
)
1666 if (siginfo_er
.ExceptionCode
== 0)
1669 if (readbuf
== nullptr)
1672 char *buf
= (char *) &siginfo_er
;
1673 size_t bufsize
= sizeof (siginfo_er
);
1676 EXCEPTION_RECORD32 er32
;
1679 buf
= (char *) &er32
;
1680 bufsize
= sizeof (er32
);
1682 er32
.ExceptionCode
= siginfo_er
.ExceptionCode
;
1683 er32
.ExceptionFlags
= siginfo_er
.ExceptionFlags
;
1684 er32
.ExceptionRecord
= (uintptr_t) siginfo_er
.ExceptionRecord
;
1685 er32
.ExceptionAddress
= (uintptr_t) siginfo_er
.ExceptionAddress
;
1686 er32
.NumberParameters
= siginfo_er
.NumberParameters
;
1688 for (i
= 0; i
< EXCEPTION_MAXIMUM_PARAMETERS
; i
++)
1689 er32
.ExceptionInformation
[i
] = siginfo_er
.ExceptionInformation
[i
];
1693 if (offset
> bufsize
)
1696 if (offset
+ len
> bufsize
)
1697 len
= bufsize
- offset
;
1699 memcpy (readbuf
, buf
+ offset
, len
);
1705 win32_process_target::supports_get_tib_address ()
1710 /* Write Windows OS Thread Information Block address. */
1713 win32_process_target::get_tib_address (ptid_t ptid
, CORE_ADDR
*addr
)
1715 windows_thread_info
*th
;
1716 th
= thread_rec (ptid
, DONT_INVALIDATE_CONTEXT
);
1720 *addr
= th
->thread_local_base
;
1724 /* Implementation of the target_ops method "sw_breakpoint_from_kind". */
1727 win32_process_target::sw_breakpoint_from_kind (int kind
, int *size
)
1729 *size
= the_low_target
.breakpoint_len
;
1730 return the_low_target
.breakpoint
;
1734 win32_process_target::stopped_by_sw_breakpoint ()
1736 windows_thread_info
*th
= thread_rec (current_thread_ptid (),
1737 DONT_INVALIDATE_CONTEXT
);
1738 return th
== nullptr ? false : th
->stopped_at_software_breakpoint
;
1742 win32_process_target::supports_stopped_by_sw_breakpoint ()
1748 win32_process_target::read_pc (struct regcache
*regcache
)
1750 return (*the_low_target
.get_pc
) (regcache
);
1754 win32_process_target::write_pc (struct regcache
*regcache
, CORE_ADDR pc
)
1756 return (*the_low_target
.set_pc
) (regcache
, pc
);
1759 /* The win32 target ops object. */
1761 static win32_process_target the_win32_target
;
1763 /* Initialize the Win32 backend. */
1765 initialize_low (void)
1767 set_target_ops (&the_win32_target
);
1768 the_low_target
.arch_setup ();
1771 /* These functions are loaded dynamically, because they are not available
1773 HMODULE dll
= GetModuleHandle (_T("KERNEL32.DLL"));
1774 win32_Wow64GetThreadContext
= GETPROCADDRESS (dll
, Wow64GetThreadContext
);
1775 win32_Wow64SetThreadContext
= GETPROCADDRESS (dll
, Wow64SetThreadContext
);