1 /* Internal interfaces for the Windows code 2 Copyright (C) 1995-2021 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #ifndef NAT_WINDOWS_NAT_H 20 #define NAT_WINDOWS_NAT_H 21 22 #include <windows.h> 23 #include <psapi.h> 24 #include <vector> 25 26 #include "gdbsupport/gdb_optional.h" 27 #include "target/waitstatus.h" 28 29 #define STATUS_WX86_BREAKPOINT 0x4000001F 30 #define STATUS_WX86_SINGLE_STEP 0x4000001E 31 32 namespace windows_nat 33 { 34 35 /* Thread information structure used to track extra information about 36 each thread. */ 37 struct windows_thread_info 38 { windows_thread_infowindows_thread_info39 windows_thread_info (DWORD tid_, HANDLE h_, CORE_ADDR tlb) 40 : tid (tid_), 41 h (h_), 42 thread_local_base (tlb) 43 { 44 } 45 46 ~windows_thread_info (); 47 48 DISABLE_COPY_AND_ASSIGN (windows_thread_info); 49 50 /* Ensure that this thread has been suspended. */ 51 void suspend (); 52 53 /* Resume the thread if it has been suspended. */ 54 void resume (); 55 56 /* The Win32 thread identifier. */ 57 DWORD tid; 58 59 /* The handle to the thread. */ 60 HANDLE h; 61 62 /* Thread Information Block address. */ 63 CORE_ADDR thread_local_base; 64 65 /* This keeps track of whether SuspendThread was called on this 66 thread. -1 means there was a failure or that the thread was 67 explicitly not suspended, 1 means it was called, and 0 means it 68 was not. */ 69 int suspended = 0; 70 71 /* The context of the thread, including any manipulations. */ 72 union 73 { 74 CONTEXT context {}; 75 #ifdef __x86_64__ 76 WOW64_CONTEXT wow64_context; 77 #endif 78 }; 79 80 /* Whether debug registers changed since we last set CONTEXT back to 81 the thread. */ 82 bool debug_registers_changed = false; 83 84 /* Nonzero if CONTEXT is invalidated and must be re-read from the 85 inferior thread. */ 86 bool reload_context = false; 87 88 /* True if this thread is currently stopped at a software 89 breakpoint. This is used to offset the PC when needed. */ 90 bool stopped_at_software_breakpoint = false; 91 92 /* True if we've adjusted the PC after hitting a software 93 breakpoint, false otherwise. This lets us avoid multiple 94 adjustments if the registers are read multiple times. */ 95 bool pc_adjusted = false; 96 97 /* The name of the thread, allocated by xmalloc. */ 98 gdb::unique_xmalloc_ptr<char> name; 99 }; 100 101 102 /* Possible values to pass to 'thread_rec'. */ 103 enum thread_disposition_type 104 { 105 /* Do not invalidate the thread's context, and do not suspend the 106 thread. */ 107 DONT_INVALIDATE_CONTEXT, 108 /* Invalidate the context, but do not suspend the thread. */ 109 DONT_SUSPEND, 110 /* Invalidate the context and suspend the thread. */ 111 INVALIDATE_CONTEXT 112 }; 113 114 /* Find a thread record given a thread id. THREAD_DISPOSITION 115 controls whether the thread is suspended, and whether the context 116 is invalidated. 117 118 This function must be supplied by the embedding application. */ 119 extern windows_thread_info *thread_rec (ptid_t ptid, 120 thread_disposition_type disposition); 121 122 123 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. Updates 124 OURSTATUS and returns the thread id if this represents a thread 125 change (this is specific to Cygwin), otherwise 0. 126 127 Cygwin prepends its messages with a "cygwin:". Interpret this as 128 a Cygwin signal. Otherwise just print the string as a warning. 129 130 This function must be supplied by the embedding application. */ 131 extern int handle_output_debug_string (struct target_waitstatus *ourstatus); 132 133 /* Handle a DLL load event. 134 135 This function assumes that the current event did not occur during 136 inferior initialization. 137 138 DLL_NAME is the name of the library. BASE is the base load 139 address. 140 141 This function must be supplied by the embedding application. */ 142 143 extern void handle_load_dll (const char *dll_name, LPVOID base); 144 145 /* Handle a DLL unload event. 146 147 This function assumes that this event did not occur during inferior 148 initialization. 149 150 This function must be supplied by the embedding application. */ 151 152 extern void handle_unload_dll (); 153 154 /* Handle MS_VC_EXCEPTION when processing a stop. MS_VC_EXCEPTION is 155 somewhat undocumented but is used to tell the debugger the name of 156 a thread. 157 158 Return true if the exception was handled; return false otherwise. 159 160 This function must be supplied by the embedding application. */ 161 162 extern bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec); 163 164 /* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding 165 application a chance to change it to be considered "unhandled". 166 This function must be supplied by the embedding application. If it 167 returns true, then the exception is "unhandled". */ 168 169 extern bool handle_access_violation (const EXCEPTION_RECORD *rec); 170 171 172 /* Currently executing process */ 173 extern HANDLE current_process_handle; 174 extern DWORD current_process_id; 175 extern DWORD main_thread_id; 176 extern enum gdb_signal last_sig; 177 178 /* The current debug event from WaitForDebugEvent or from a pending 179 stop. */ 180 extern DEBUG_EVENT current_event; 181 182 /* The ID of the thread for which we anticipate a stop event. 183 Normally this is -1, meaning we'll accept an event in any 184 thread. */ 185 extern DWORD desired_stop_thread_id; 186 187 /* A single pending stop. See "pending_stops" for more 188 information. */ 189 struct pending_stop 190 { 191 /* The thread id. */ 192 DWORD thread_id; 193 194 /* The target waitstatus we computed. */ 195 target_waitstatus status; 196 197 /* The event. A few fields of this can be referenced after a stop, 198 and it seemed simplest to store the entire event. */ 199 DEBUG_EVENT event; 200 }; 201 202 /* A vector of pending stops. Sometimes, Windows will report a stop 203 on a thread that has been ostensibly suspended. We believe what 204 happens here is that two threads hit a breakpoint simultaneously, 205 and the Windows kernel queues the stop events. However, this can 206 result in the strange effect of trying to single step thread A -- 207 leaving all other threads suspended -- and then seeing a stop in 208 thread B. To handle this scenario, we queue all such "pending" 209 stops here, and then process them once the step has completed. See 210 PR gdb/22992. */ 211 extern std::vector<pending_stop> pending_stops; 212 213 /* Contents of $_siginfo */ 214 extern EXCEPTION_RECORD siginfo_er; 215 216 #ifdef __x86_64__ 217 /* The target is a WOW64 process */ 218 extern bool wow64_process; 219 /* Ignore first breakpoint exception of WOW64 process */ 220 extern bool ignore_first_breakpoint; 221 #endif 222 223 typedef enum 224 { 225 HANDLE_EXCEPTION_UNHANDLED = 0, 226 HANDLE_EXCEPTION_HANDLED, 227 HANDLE_EXCEPTION_IGNORED 228 } handle_exception_result; 229 230 extern handle_exception_result handle_exception 231 (struct target_waitstatus *ourstatus, bool debug_exceptions); 232 233 /* Call to indicate that a DLL was loaded. */ 234 235 extern void dll_loaded_event (); 236 237 /* Iterate over all DLLs currently mapped by our inferior, and 238 add them to our list of solibs. */ 239 240 extern void windows_add_all_dlls (); 241 242 /* Return true if there is a pending stop matching 243 desired_stop_thread_id. If DEBUG_EVENTS is true, logging will be 244 enabled. */ 245 246 extern bool matching_pending_stop (bool debug_events); 247 248 /* See if a pending stop matches DESIRED_STOP_THREAD_ID. If so, 249 remove it from the list of pending stops, set 'current_event', and 250 return it. Otherwise, return an empty optional. */ 251 252 extern gdb::optional<pending_stop> fetch_pending_stop (bool debug_events); 253 254 /* A simple wrapper for ContinueDebugEvent that continues the last 255 waited-for event. If DEBUG_EVENTS is true, logging will be 256 enabled. */ 257 258 extern BOOL continue_last_debug_event (DWORD continue_status, 259 bool debug_events); 260 261 /* A simple wrapper for WaitForDebugEvent that also sets the internal 262 'last_wait_event' on success. */ 263 264 extern BOOL wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout); 265 266 #define AdjustTokenPrivileges dyn_AdjustTokenPrivileges 267 #define DebugActiveProcessStop dyn_DebugActiveProcessStop 268 #define DebugBreakProcess dyn_DebugBreakProcess 269 #define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit 270 #define EnumProcessModules dyn_EnumProcessModules 271 #define EnumProcessModulesEx dyn_EnumProcessModulesEx 272 #define GetModuleInformation dyn_GetModuleInformation 273 #define GetModuleFileNameExA dyn_GetModuleFileNameExA 274 #define GetModuleFileNameExW dyn_GetModuleFileNameExW 275 #define LookupPrivilegeValueA dyn_LookupPrivilegeValueA 276 #define OpenProcessToken dyn_OpenProcessToken 277 #define GetConsoleFontSize dyn_GetConsoleFontSize 278 #define GetCurrentConsoleFont dyn_GetCurrentConsoleFont 279 #define Wow64SuspendThread dyn_Wow64SuspendThread 280 #define Wow64GetThreadContext dyn_Wow64GetThreadContext 281 #define Wow64SetThreadContext dyn_Wow64SetThreadContext 282 #define Wow64GetThreadSelectorEntry dyn_Wow64GetThreadSelectorEntry 283 #define GenerateConsoleCtrlEvent dyn_GenerateConsoleCtrlEvent 284 285 typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL, 286 PTOKEN_PRIVILEGES, 287 DWORD, PTOKEN_PRIVILEGES, 288 PDWORD); 289 extern AdjustTokenPrivileges_ftype *AdjustTokenPrivileges; 290 291 typedef BOOL WINAPI (DebugActiveProcessStop_ftype) (DWORD); 292 extern DebugActiveProcessStop_ftype *DebugActiveProcessStop; 293 294 typedef BOOL WINAPI (DebugBreakProcess_ftype) (HANDLE); 295 extern DebugBreakProcess_ftype *DebugBreakProcess; 296 297 typedef BOOL WINAPI (DebugSetProcessKillOnExit_ftype) (BOOL); 298 extern DebugSetProcessKillOnExit_ftype *DebugSetProcessKillOnExit; 299 300 typedef BOOL WINAPI (EnumProcessModules_ftype) (HANDLE, HMODULE *, DWORD, 301 LPDWORD); 302 extern EnumProcessModules_ftype *EnumProcessModules; 303 304 #ifdef __x86_64__ 305 typedef BOOL WINAPI (EnumProcessModulesEx_ftype) (HANDLE, HMODULE *, DWORD, 306 LPDWORD, DWORD); 307 extern EnumProcessModulesEx_ftype *EnumProcessModulesEx; 308 #endif 309 310 typedef BOOL WINAPI (GetModuleInformation_ftype) (HANDLE, HMODULE, 311 LPMODULEINFO, DWORD); 312 extern GetModuleInformation_ftype *GetModuleInformation; 313 314 typedef DWORD WINAPI (GetModuleFileNameExA_ftype) (HANDLE, HMODULE, LPSTR, 315 DWORD); 316 extern GetModuleFileNameExA_ftype *GetModuleFileNameExA; 317 318 typedef DWORD WINAPI (GetModuleFileNameExW_ftype) (HANDLE, HMODULE, 319 LPWSTR, DWORD); 320 extern GetModuleFileNameExW_ftype *GetModuleFileNameExW; 321 322 typedef BOOL WINAPI (LookupPrivilegeValueA_ftype) (LPCSTR, LPCSTR, PLUID); 323 extern LookupPrivilegeValueA_ftype *LookupPrivilegeValueA; 324 325 typedef BOOL WINAPI (OpenProcessToken_ftype) (HANDLE, DWORD, PHANDLE); 326 extern OpenProcessToken_ftype *OpenProcessToken; 327 328 typedef BOOL WINAPI (GetCurrentConsoleFont_ftype) (HANDLE, BOOL, 329 CONSOLE_FONT_INFO *); 330 extern GetCurrentConsoleFont_ftype *GetCurrentConsoleFont; 331 332 typedef COORD WINAPI (GetConsoleFontSize_ftype) (HANDLE, DWORD); 333 extern GetConsoleFontSize_ftype *GetConsoleFontSize; 334 335 #ifdef __x86_64__ 336 typedef DWORD WINAPI (Wow64SuspendThread_ftype) (HANDLE); 337 extern Wow64SuspendThread_ftype *Wow64SuspendThread; 338 339 typedef BOOL WINAPI (Wow64GetThreadContext_ftype) (HANDLE, PWOW64_CONTEXT); 340 extern Wow64GetThreadContext_ftype *Wow64GetThreadContext; 341 342 typedef BOOL WINAPI (Wow64SetThreadContext_ftype) (HANDLE, 343 const WOW64_CONTEXT *); 344 extern Wow64SetThreadContext_ftype *Wow64SetThreadContext; 345 346 typedef BOOL WINAPI (Wow64GetThreadSelectorEntry_ftype) (HANDLE, DWORD, 347 PLDT_ENTRY); 348 extern Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry; 349 #endif 350 351 typedef BOOL WINAPI (GenerateConsoleCtrlEvent_ftype) (DWORD, DWORD); 352 extern GenerateConsoleCtrlEvent_ftype *GenerateConsoleCtrlEvent; 353 354 /* Load any functions which may not be available in ancient versions 355 of Windows. */ 356 357 extern bool initialize_loadable (); 358 359 } 360 361 #endif 362