Home | History | Annotate | Line # | Download | only in nat
      1      1.1  christos /* Internal interfaces for the Windows code
      2  1.1.1.3  christos    Copyright (C) 1995-2024 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of GDB.
      5      1.1  christos 
      6      1.1  christos    This program is free software; you can redistribute it and/or modify
      7      1.1  christos    it under the terms of the GNU General Public License as published by
      8      1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9      1.1  christos    (at your option) any later version.
     10      1.1  christos 
     11      1.1  christos    This program is distributed in the hope that it will be useful,
     12      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  christos    GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18      1.1  christos 
     19  1.1.1.4  christos #ifndef GDB_NAT_WINDOWS_NAT_H
     20  1.1.1.4  christos #define GDB_NAT_WINDOWS_NAT_H
     21      1.1  christos 
     22      1.1  christos #include <windows.h>
     23  1.1.1.2  christos #include <psapi.h>
     24      1.1  christos #include <vector>
     25      1.1  christos 
     26  1.1.1.3  christos #include <optional>
     27      1.1  christos #include "target/waitstatus.h"
     28      1.1  christos 
     29      1.1  christos #define STATUS_WX86_BREAKPOINT 0x4000001F
     30      1.1  christos #define STATUS_WX86_SINGLE_STEP 0x4000001E
     31      1.1  christos 
     32  1.1.1.4  christos #ifndef CONTEXT_EXTENDED_REGISTERS
     33  1.1.1.4  christos /* This macro is only defined on ia32.  It only makes sense on this target,
     34  1.1.1.4  christos    so define it as zero if not already defined.  */
     35  1.1.1.4  christos #define CONTEXT_EXTENDED_REGISTERS 0
     36  1.1.1.4  christos #endif
     37  1.1.1.4  christos 
     38      1.1  christos namespace windows_nat
     39      1.1  christos {
     40      1.1  christos 
     41      1.1  christos /* Thread information structure used to track extra information about
     42      1.1  christos    each thread.  */
     43      1.1  christos struct windows_thread_info
     44      1.1  christos {
     45      1.1  christos   windows_thread_info (DWORD tid_, HANDLE h_, CORE_ADDR tlb)
     46      1.1  christos     : tid (tid_),
     47      1.1  christos       h (h_),
     48      1.1  christos       thread_local_base (tlb)
     49      1.1  christos   {
     50      1.1  christos   }
     51      1.1  christos 
     52      1.1  christos   DISABLE_COPY_AND_ASSIGN (windows_thread_info);
     53      1.1  christos 
     54      1.1  christos   /* Ensure that this thread has been suspended.  */
     55      1.1  christos   void suspend ();
     56      1.1  christos 
     57      1.1  christos   /* Resume the thread if it has been suspended.  */
     58      1.1  christos   void resume ();
     59      1.1  christos 
     60  1.1.1.2  christos   /* Return the thread's name, or nullptr if not known.  The name is
     61  1.1.1.2  christos      stored in this thread and is guaranteed to live until at least
     62  1.1.1.2  christos      the next call.  */
     63  1.1.1.2  christos   const char *thread_name ();
     64  1.1.1.2  christos 
     65      1.1  christos   /* The Win32 thread identifier.  */
     66      1.1  christos   DWORD tid;
     67      1.1  christos 
     68      1.1  christos   /* The handle to the thread.  */
     69      1.1  christos   HANDLE h;
     70      1.1  christos 
     71      1.1  christos   /* Thread Information Block address.  */
     72      1.1  christos   CORE_ADDR thread_local_base;
     73      1.1  christos 
     74      1.1  christos   /* This keeps track of whether SuspendThread was called on this
     75      1.1  christos      thread.  -1 means there was a failure or that the thread was
     76      1.1  christos      explicitly not suspended, 1 means it was called, and 0 means it
     77      1.1  christos      was not.  */
     78      1.1  christos   int suspended = 0;
     79      1.1  christos 
     80      1.1  christos   /* The context of the thread, including any manipulations.  */
     81      1.1  christos   union
     82      1.1  christos   {
     83      1.1  christos     CONTEXT context {};
     84      1.1  christos #ifdef __x86_64__
     85      1.1  christos     WOW64_CONTEXT wow64_context;
     86      1.1  christos #endif
     87      1.1  christos   };
     88      1.1  christos 
     89      1.1  christos   /* Whether debug registers changed since we last set CONTEXT back to
     90      1.1  christos      the thread.  */
     91      1.1  christos   bool debug_registers_changed = false;
     92      1.1  christos 
     93      1.1  christos   /* Nonzero if CONTEXT is invalidated and must be re-read from the
     94      1.1  christos      inferior thread.  */
     95      1.1  christos   bool reload_context = false;
     96      1.1  christos 
     97      1.1  christos   /* True if this thread is currently stopped at a software
     98      1.1  christos      breakpoint.  This is used to offset the PC when needed.  */
     99      1.1  christos   bool stopped_at_software_breakpoint = false;
    100      1.1  christos 
    101      1.1  christos   /* True if we've adjusted the PC after hitting a software
    102      1.1  christos      breakpoint, false otherwise.  This lets us avoid multiple
    103      1.1  christos      adjustments if the registers are read multiple times.  */
    104      1.1  christos   bool pc_adjusted = false;
    105      1.1  christos 
    106  1.1.1.2  christos   /* The name of the thread.  */
    107      1.1  christos   gdb::unique_xmalloc_ptr<char> name;
    108      1.1  christos };
    109      1.1  christos 
    110      1.1  christos 
    111      1.1  christos /* Possible values to pass to 'thread_rec'.  */
    112      1.1  christos enum thread_disposition_type
    113      1.1  christos {
    114      1.1  christos   /* Do not invalidate the thread's context, and do not suspend the
    115      1.1  christos      thread.  */
    116      1.1  christos   DONT_INVALIDATE_CONTEXT,
    117      1.1  christos   /* Invalidate the context, but do not suspend the thread.  */
    118      1.1  christos   DONT_SUSPEND,
    119      1.1  christos   /* Invalidate the context and suspend the thread.  */
    120      1.1  christos   INVALIDATE_CONTEXT
    121      1.1  christos };
    122      1.1  christos 
    123  1.1.1.2  christos /* A single pending stop.  See "pending_stops" for more
    124  1.1.1.2  christos    information.  */
    125  1.1.1.2  christos struct pending_stop
    126  1.1.1.2  christos {
    127  1.1.1.2  christos   /* The thread id.  */
    128  1.1.1.2  christos   DWORD thread_id;
    129      1.1  christos 
    130  1.1.1.2  christos   /* The target waitstatus we computed.  */
    131  1.1.1.2  christos   target_waitstatus status;
    132      1.1  christos 
    133  1.1.1.2  christos   /* The event.  A few fields of this can be referenced after a stop,
    134  1.1.1.2  christos      and it seemed simplest to store the entire event.  */
    135  1.1.1.2  christos   DEBUG_EVENT event;
    136  1.1.1.2  christos };
    137      1.1  christos 
    138  1.1.1.2  christos enum handle_exception_result
    139  1.1.1.2  christos {
    140  1.1.1.2  christos   HANDLE_EXCEPTION_UNHANDLED = 0,
    141  1.1.1.2  christos   HANDLE_EXCEPTION_HANDLED,
    142  1.1.1.2  christos   HANDLE_EXCEPTION_IGNORED
    143  1.1.1.2  christos };
    144      1.1  christos 
    145  1.1.1.2  christos /* A single Windows process.  An object of this type (or subclass) is
    146  1.1.1.2  christos    created by the client.  Some methods must be provided by the client
    147  1.1.1.2  christos    as well.  */
    148      1.1  christos 
    149  1.1.1.2  christos struct windows_process_info
    150  1.1.1.2  christos {
    151  1.1.1.2  christos   /* The process handle */
    152  1.1.1.2  christos   HANDLE handle = 0;
    153  1.1.1.2  christos   DWORD main_thread_id = 0;
    154  1.1.1.2  christos   enum gdb_signal last_sig = GDB_SIGNAL_0;
    155  1.1.1.2  christos 
    156  1.1.1.2  christos   /* The current debug event from WaitForDebugEvent or from a pending
    157  1.1.1.2  christos      stop.  */
    158  1.1.1.2  christos   DEBUG_EVENT current_event {};
    159      1.1  christos 
    160  1.1.1.2  christos   /* The ID of the thread for which we anticipate a stop event.
    161  1.1.1.2  christos      Normally this is -1, meaning we'll accept an event in any
    162  1.1.1.2  christos      thread.  */
    163  1.1.1.2  christos   DWORD desired_stop_thread_id = -1;
    164      1.1  christos 
    165  1.1.1.2  christos   /* A vector of pending stops.  Sometimes, Windows will report a stop
    166  1.1.1.2  christos      on a thread that has been ostensibly suspended.  We believe what
    167  1.1.1.2  christos      happens here is that two threads hit a breakpoint simultaneously,
    168  1.1.1.2  christos      and the Windows kernel queues the stop events.  However, this can
    169  1.1.1.2  christos      result in the strange effect of trying to single step thread A --
    170  1.1.1.2  christos      leaving all other threads suspended -- and then seeing a stop in
    171  1.1.1.2  christos      thread B.  To handle this scenario, we queue all such "pending"
    172  1.1.1.2  christos      stops here, and then process them once the step has completed.  See
    173  1.1.1.2  christos      PR gdb/22992.  */
    174  1.1.1.2  christos   std::vector<pending_stop> pending_stops;
    175      1.1  christos 
    176  1.1.1.2  christos   /* Contents of $_siginfo */
    177  1.1.1.2  christos   EXCEPTION_RECORD siginfo_er {};
    178      1.1  christos 
    179  1.1.1.2  christos #ifdef __x86_64__
    180  1.1.1.2  christos   /* The target is a WOW64 process */
    181  1.1.1.2  christos   bool wow64_process = false;
    182  1.1.1.2  christos   /* Ignore first breakpoint exception of WOW64 process */
    183  1.1.1.2  christos   bool ignore_first_breakpoint = false;
    184  1.1.1.2  christos #endif
    185      1.1  christos 
    186      1.1  christos 
    187  1.1.1.2  christos   /* Find a thread record given a thread id.  THREAD_DISPOSITION
    188  1.1.1.2  christos      controls whether the thread is suspended, and whether the context
    189  1.1.1.2  christos      is invalidated.
    190      1.1  christos 
    191  1.1.1.2  christos      This function must be supplied by the embedding application.  */
    192  1.1.1.2  christos   virtual windows_thread_info *thread_rec (ptid_t ptid,
    193  1.1.1.2  christos 					   thread_disposition_type disposition) = 0;
    194      1.1  christos 
    195  1.1.1.2  christos   /* Handle OUTPUT_DEBUG_STRING_EVENT from child process.  Updates
    196  1.1.1.2  christos      OURSTATUS and returns the thread id if this represents a thread
    197  1.1.1.2  christos      change (this is specific to Cygwin), otherwise 0.
    198      1.1  christos 
    199  1.1.1.2  christos      Cygwin prepends its messages with a "cygwin:".  Interpret this as
    200  1.1.1.2  christos      a Cygwin signal.  Otherwise just print the string as a warning.
    201      1.1  christos 
    202  1.1.1.2  christos      This function must be supplied by the embedding application.  */
    203  1.1.1.2  christos   virtual int handle_output_debug_string (struct target_waitstatus *ourstatus) = 0;
    204      1.1  christos 
    205  1.1.1.2  christos   /* Handle a DLL load event.
    206      1.1  christos 
    207  1.1.1.2  christos      This function assumes that the current event did not occur during
    208  1.1.1.2  christos      inferior initialization.
    209      1.1  christos 
    210  1.1.1.2  christos      DLL_NAME is the name of the library.  BASE is the base load
    211  1.1.1.2  christos      address.
    212      1.1  christos 
    213  1.1.1.2  christos      This function must be supplied by the embedding application.  */
    214      1.1  christos 
    215  1.1.1.2  christos   virtual void handle_load_dll (const char *dll_name, LPVOID base) = 0;
    216      1.1  christos 
    217  1.1.1.2  christos   /* Handle a DLL unload event.
    218      1.1  christos 
    219  1.1.1.2  christos      This function assumes that this event did not occur during inferior
    220  1.1.1.2  christos      initialization.
    221      1.1  christos 
    222  1.1.1.2  christos      This function must be supplied by the embedding application.  */
    223      1.1  christos 
    224  1.1.1.2  christos   virtual void handle_unload_dll () = 0;
    225      1.1  christos 
    226  1.1.1.2  christos   /* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
    227  1.1.1.2  christos      application a chance to change it to be considered "unhandled".
    228  1.1.1.2  christos      This function must be supplied by the embedding application.  If it
    229  1.1.1.2  christos      returns true, then the exception is "unhandled".  */
    230      1.1  christos 
    231  1.1.1.2  christos   virtual bool handle_access_violation (const EXCEPTION_RECORD *rec) = 0;
    232      1.1  christos 
    233  1.1.1.2  christos   handle_exception_result handle_exception
    234  1.1.1.2  christos        (struct target_waitstatus *ourstatus, bool debug_exceptions);
    235      1.1  christos 
    236  1.1.1.2  christos   /* Call to indicate that a DLL was loaded.  */
    237      1.1  christos 
    238  1.1.1.2  christos   void dll_loaded_event ();
    239      1.1  christos 
    240  1.1.1.2  christos   /* Iterate over all DLLs currently mapped by our inferior, and
    241  1.1.1.2  christos      add them to our list of solibs.  */
    242      1.1  christos 
    243  1.1.1.2  christos   void add_all_dlls ();
    244      1.1  christos 
    245  1.1.1.2  christos   /* Return true if there is a pending stop matching
    246  1.1.1.2  christos      desired_stop_thread_id.  If DEBUG_EVENTS is true, logging will be
    247  1.1.1.2  christos      enabled.  */
    248      1.1  christos 
    249  1.1.1.2  christos   bool matching_pending_stop (bool debug_events);
    250  1.1.1.2  christos 
    251  1.1.1.2  christos   /* See if a pending stop matches DESIRED_STOP_THREAD_ID.  If so,
    252  1.1.1.2  christos      remove it from the list of pending stops, set 'current_event', and
    253  1.1.1.2  christos      return it.  Otherwise, return an empty optional.  */
    254  1.1.1.2  christos 
    255  1.1.1.3  christos   std::optional<pending_stop> fetch_pending_stop (bool debug_events);
    256  1.1.1.2  christos 
    257  1.1.1.2  christos   const char *pid_to_exec_file (int);
    258  1.1.1.2  christos 
    259  1.1.1.4  christos   template<typename Function>
    260  1.1.1.4  christos   auto with_context (windows_thread_info *th, Function function)
    261  1.1.1.4  christos   {
    262  1.1.1.4  christos #ifdef __x86_64__
    263  1.1.1.4  christos     if (wow64_process)
    264  1.1.1.4  christos       return function (th != nullptr ? &th->wow64_context : nullptr);
    265  1.1.1.4  christos     else
    266  1.1.1.4  christos #endif
    267  1.1.1.4  christos       return function (th != nullptr ? &th->context : nullptr);
    268  1.1.1.4  christos   }
    269  1.1.1.4  christos 
    270  1.1.1.4  christos   DWORD *context_flags_ptr (windows_thread_info *th)
    271  1.1.1.4  christos   {
    272  1.1.1.4  christos     return with_context (th, [] (auto *context)
    273  1.1.1.4  christos       {
    274  1.1.1.4  christos 	return &context->ContextFlags;
    275  1.1.1.4  christos       });
    276  1.1.1.4  christos   }
    277  1.1.1.4  christos 
    278  1.1.1.2  christos private:
    279      1.1  christos 
    280  1.1.1.2  christos   /* Handle MS_VC_EXCEPTION when processing a stop.  MS_VC_EXCEPTION is
    281  1.1.1.2  christos      somewhat undocumented but is used to tell the debugger the name of
    282  1.1.1.2  christos      a thread.
    283      1.1  christos 
    284  1.1.1.2  christos      Return true if the exception was handled; return false otherwise.  */
    285      1.1  christos 
    286  1.1.1.2  christos   bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
    287  1.1.1.2  christos 
    288  1.1.1.2  christos   /* Iterate over all DLLs currently mapped by our inferior, looking for
    289  1.1.1.2  christos      a DLL which is loaded at LOAD_ADDR.  If found, add the DLL to our
    290  1.1.1.2  christos      list of solibs; otherwise do nothing.  LOAD_ADDR NULL means add all
    291  1.1.1.2  christos      DLLs to the list of solibs; this is used when the inferior finishes
    292  1.1.1.2  christos      its initialization, and all the DLLs it statically depends on are
    293  1.1.1.2  christos      presumed loaded.  */
    294  1.1.1.2  christos 
    295  1.1.1.2  christos   void add_dll (LPVOID load_addr);
    296  1.1.1.2  christos 
    297  1.1.1.2  christos   /* Try to determine the executable filename.
    298  1.1.1.2  christos 
    299  1.1.1.2  christos      EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
    300  1.1.1.2  christos 
    301  1.1.1.2  christos      Upon success, the filename is stored inside EXE_NAME_RET, and
    302  1.1.1.2  christos      this function returns nonzero.
    303  1.1.1.2  christos 
    304  1.1.1.2  christos      Otherwise, this function returns zero and the contents of
    305  1.1.1.2  christos      EXE_NAME_RET is undefined.  */
    306  1.1.1.2  christos 
    307  1.1.1.2  christos   int get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len);
    308  1.1.1.2  christos };
    309      1.1  christos 
    310      1.1  christos /* A simple wrapper for ContinueDebugEvent that continues the last
    311      1.1  christos    waited-for event.  If DEBUG_EVENTS is true, logging will be
    312      1.1  christos    enabled.  */
    313      1.1  christos 
    314      1.1  christos extern BOOL continue_last_debug_event (DWORD continue_status,
    315      1.1  christos 				       bool debug_events);
    316      1.1  christos 
    317      1.1  christos /* A simple wrapper for WaitForDebugEvent that also sets the internal
    318      1.1  christos    'last_wait_event' on success.  */
    319      1.1  christos 
    320      1.1  christos extern BOOL wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout);
    321      1.1  christos 
    322  1.1.1.2  christos /* Wrappers for CreateProcess.  These exist primarily so that the
    323  1.1.1.2  christos    "disable randomization" feature can be implemented in a single
    324  1.1.1.2  christos    place.  */
    325  1.1.1.2  christos 
    326  1.1.1.2  christos extern BOOL create_process (const char *image, char *command_line,
    327  1.1.1.2  christos 			    DWORD flags, void *environment,
    328  1.1.1.2  christos 			    const char *cur_dir,
    329  1.1.1.2  christos 			    bool no_randomization,
    330  1.1.1.2  christos 			    STARTUPINFOA *startup_info,
    331  1.1.1.2  christos 			    PROCESS_INFORMATION *process_info);
    332  1.1.1.2  christos #ifdef __CYGWIN__
    333  1.1.1.2  christos extern BOOL create_process (const wchar_t *image, wchar_t *command_line,
    334  1.1.1.2  christos 			    DWORD flags, void *environment,
    335  1.1.1.2  christos 			    const wchar_t *cur_dir,
    336  1.1.1.2  christos 			    bool no_randomization,
    337  1.1.1.2  christos 			    STARTUPINFOW *startup_info,
    338  1.1.1.2  christos 			    PROCESS_INFORMATION *process_info);
    339  1.1.1.2  christos #endif /* __CYGWIN__ */
    340  1.1.1.2  christos 
    341  1.1.1.2  christos #define AdjustTokenPrivileges		dyn_AdjustTokenPrivileges
    342  1.1.1.2  christos #define DebugActiveProcessStop		dyn_DebugActiveProcessStop
    343  1.1.1.2  christos #define DebugBreakProcess		dyn_DebugBreakProcess
    344  1.1.1.2  christos #define DebugSetProcessKillOnExit	dyn_DebugSetProcessKillOnExit
    345  1.1.1.2  christos #undef EnumProcessModules
    346  1.1.1.2  christos #define EnumProcessModules		dyn_EnumProcessModules
    347  1.1.1.2  christos #undef EnumProcessModulesEx
    348  1.1.1.2  christos #define EnumProcessModulesEx		dyn_EnumProcessModulesEx
    349  1.1.1.2  christos #undef GetModuleInformation
    350  1.1.1.2  christos #define GetModuleInformation		dyn_GetModuleInformation
    351  1.1.1.2  christos #undef GetModuleFileNameExA
    352  1.1.1.2  christos #define GetModuleFileNameExA		dyn_GetModuleFileNameExA
    353  1.1.1.2  christos #undef GetModuleFileNameExW
    354  1.1.1.2  christos #define GetModuleFileNameExW		dyn_GetModuleFileNameExW
    355  1.1.1.2  christos #define LookupPrivilegeValueA		dyn_LookupPrivilegeValueA
    356  1.1.1.2  christos #define OpenProcessToken		dyn_OpenProcessToken
    357  1.1.1.2  christos #define GetConsoleFontSize		dyn_GetConsoleFontSize
    358  1.1.1.2  christos #define GetCurrentConsoleFont		dyn_GetCurrentConsoleFont
    359  1.1.1.2  christos #define Wow64SuspendThread		dyn_Wow64SuspendThread
    360  1.1.1.2  christos #define Wow64GetThreadContext		dyn_Wow64GetThreadContext
    361  1.1.1.2  christos #define Wow64SetThreadContext		dyn_Wow64SetThreadContext
    362  1.1.1.2  christos #define Wow64GetThreadSelectorEntry	dyn_Wow64GetThreadSelectorEntry
    363  1.1.1.2  christos #define GenerateConsoleCtrlEvent	dyn_GenerateConsoleCtrlEvent
    364  1.1.1.2  christos #define InitializeProcThreadAttributeList dyn_InitializeProcThreadAttributeList
    365  1.1.1.2  christos #define UpdateProcThreadAttribute dyn_UpdateProcThreadAttribute
    366  1.1.1.2  christos #define DeleteProcThreadAttributeList dyn_DeleteProcThreadAttributeList
    367  1.1.1.2  christos 
    368  1.1.1.2  christos typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL,
    369  1.1.1.2  christos 						   PTOKEN_PRIVILEGES,
    370  1.1.1.2  christos 						   DWORD, PTOKEN_PRIVILEGES,
    371  1.1.1.2  christos 						   PDWORD);
    372  1.1.1.2  christos extern AdjustTokenPrivileges_ftype *AdjustTokenPrivileges;
    373  1.1.1.2  christos 
    374  1.1.1.2  christos typedef BOOL WINAPI (DebugActiveProcessStop_ftype) (DWORD);
    375  1.1.1.2  christos extern DebugActiveProcessStop_ftype *DebugActiveProcessStop;
    376  1.1.1.2  christos 
    377  1.1.1.2  christos typedef BOOL WINAPI (DebugBreakProcess_ftype) (HANDLE);
    378  1.1.1.2  christos extern DebugBreakProcess_ftype *DebugBreakProcess;
    379  1.1.1.2  christos 
    380  1.1.1.2  christos typedef BOOL WINAPI (DebugSetProcessKillOnExit_ftype) (BOOL);
    381  1.1.1.2  christos extern DebugSetProcessKillOnExit_ftype *DebugSetProcessKillOnExit;
    382  1.1.1.2  christos 
    383  1.1.1.2  christos typedef BOOL WINAPI (EnumProcessModules_ftype) (HANDLE, HMODULE *, DWORD,
    384  1.1.1.2  christos 						LPDWORD);
    385  1.1.1.2  christos extern EnumProcessModules_ftype *EnumProcessModules;
    386  1.1.1.2  christos 
    387  1.1.1.2  christos #ifdef __x86_64__
    388  1.1.1.2  christos typedef BOOL WINAPI (EnumProcessModulesEx_ftype) (HANDLE, HMODULE *, DWORD,
    389  1.1.1.2  christos 						  LPDWORD, DWORD);
    390  1.1.1.2  christos extern EnumProcessModulesEx_ftype *EnumProcessModulesEx;
    391  1.1.1.2  christos #endif
    392  1.1.1.2  christos 
    393  1.1.1.2  christos typedef BOOL WINAPI (GetModuleInformation_ftype) (HANDLE, HMODULE,
    394  1.1.1.2  christos 						  LPMODULEINFO, DWORD);
    395  1.1.1.2  christos extern GetModuleInformation_ftype *GetModuleInformation;
    396  1.1.1.2  christos 
    397  1.1.1.2  christos typedef DWORD WINAPI (GetModuleFileNameExA_ftype) (HANDLE, HMODULE, LPSTR,
    398  1.1.1.2  christos 						  DWORD);
    399  1.1.1.2  christos extern GetModuleFileNameExA_ftype *GetModuleFileNameExA;
    400  1.1.1.2  christos 
    401  1.1.1.2  christos typedef DWORD WINAPI (GetModuleFileNameExW_ftype) (HANDLE, HMODULE,
    402  1.1.1.2  christos 						   LPWSTR, DWORD);
    403  1.1.1.2  christos extern GetModuleFileNameExW_ftype *GetModuleFileNameExW;
    404  1.1.1.2  christos 
    405  1.1.1.2  christos typedef BOOL WINAPI (LookupPrivilegeValueA_ftype) (LPCSTR, LPCSTR, PLUID);
    406  1.1.1.2  christos extern LookupPrivilegeValueA_ftype *LookupPrivilegeValueA;
    407  1.1.1.2  christos 
    408  1.1.1.2  christos typedef BOOL WINAPI (OpenProcessToken_ftype) (HANDLE, DWORD, PHANDLE);
    409  1.1.1.2  christos extern OpenProcessToken_ftype *OpenProcessToken;
    410  1.1.1.2  christos 
    411  1.1.1.2  christos typedef BOOL WINAPI (GetCurrentConsoleFont_ftype) (HANDLE, BOOL,
    412  1.1.1.2  christos 						   CONSOLE_FONT_INFO *);
    413  1.1.1.2  christos extern GetCurrentConsoleFont_ftype *GetCurrentConsoleFont;
    414  1.1.1.2  christos 
    415  1.1.1.2  christos typedef COORD WINAPI (GetConsoleFontSize_ftype) (HANDLE, DWORD);
    416  1.1.1.2  christos extern GetConsoleFontSize_ftype *GetConsoleFontSize;
    417  1.1.1.2  christos 
    418  1.1.1.2  christos #ifdef __x86_64__
    419  1.1.1.2  christos typedef DWORD WINAPI (Wow64SuspendThread_ftype) (HANDLE);
    420  1.1.1.2  christos extern Wow64SuspendThread_ftype *Wow64SuspendThread;
    421  1.1.1.2  christos 
    422  1.1.1.2  christos typedef BOOL WINAPI (Wow64GetThreadContext_ftype) (HANDLE, PWOW64_CONTEXT);
    423  1.1.1.2  christos extern Wow64GetThreadContext_ftype *Wow64GetThreadContext;
    424  1.1.1.2  christos 
    425  1.1.1.2  christos typedef BOOL WINAPI (Wow64SetThreadContext_ftype) (HANDLE,
    426  1.1.1.2  christos 						   const WOW64_CONTEXT *);
    427  1.1.1.2  christos extern Wow64SetThreadContext_ftype *Wow64SetThreadContext;
    428  1.1.1.2  christos 
    429  1.1.1.2  christos typedef BOOL WINAPI (Wow64GetThreadSelectorEntry_ftype) (HANDLE, DWORD,
    430  1.1.1.2  christos 							 PLDT_ENTRY);
    431  1.1.1.2  christos extern Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry;
    432  1.1.1.2  christos #endif
    433  1.1.1.2  christos 
    434  1.1.1.2  christos typedef BOOL WINAPI (GenerateConsoleCtrlEvent_ftype) (DWORD, DWORD);
    435  1.1.1.2  christos extern GenerateConsoleCtrlEvent_ftype *GenerateConsoleCtrlEvent;
    436  1.1.1.2  christos 
    437  1.1.1.2  christos /* We use a local typedef for this type to avoid depending on
    438  1.1.1.2  christos    Windows 8.  */
    439  1.1.1.2  christos typedef void *gdb_lpproc_thread_attribute_list;
    440  1.1.1.2  christos 
    441  1.1.1.2  christos typedef BOOL WINAPI (InitializeProcThreadAttributeList_ftype)
    442  1.1.1.2  christos      (gdb_lpproc_thread_attribute_list lpAttributeList,
    443  1.1.1.2  christos       DWORD dwAttributeCount, DWORD dwFlags, PSIZE_T lpSize);
    444  1.1.1.2  christos extern InitializeProcThreadAttributeList_ftype *InitializeProcThreadAttributeList;
    445  1.1.1.2  christos 
    446  1.1.1.2  christos typedef BOOL WINAPI (UpdateProcThreadAttribute_ftype)
    447  1.1.1.2  christos      (gdb_lpproc_thread_attribute_list lpAttributeList,
    448  1.1.1.2  christos       DWORD dwFlags, DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize,
    449  1.1.1.2  christos       PVOID lpPreviousValue, PSIZE_T lpReturnSize);
    450  1.1.1.2  christos extern UpdateProcThreadAttribute_ftype *UpdateProcThreadAttribute;
    451  1.1.1.2  christos 
    452  1.1.1.2  christos typedef void WINAPI (DeleteProcThreadAttributeList_ftype)
    453  1.1.1.2  christos      (gdb_lpproc_thread_attribute_list lpAttributeList);
    454  1.1.1.2  christos extern DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
    455  1.1.1.2  christos 
    456  1.1.1.2  christos /* Return true if it's possible to disable randomization on this
    457  1.1.1.2  christos    host.  */
    458  1.1.1.2  christos 
    459  1.1.1.2  christos extern bool disable_randomization_available ();
    460  1.1.1.2  christos 
    461  1.1.1.4  christos /* Helper classes to get the correct ContextFlags values based on the
    462  1.1.1.4  christos    used type (CONTEXT or WOW64_CONTEXT).  */
    463  1.1.1.4  christos 
    464  1.1.1.4  christos template<typename Context>
    465  1.1.1.4  christos struct WindowsContext;
    466  1.1.1.4  christos 
    467  1.1.1.4  christos template<>
    468  1.1.1.4  christos struct WindowsContext<CONTEXT *>
    469  1.1.1.4  christos {
    470  1.1.1.4  christos   static constexpr DWORD control  = CONTEXT_CONTROL;
    471  1.1.1.4  christos   static constexpr DWORD floating = CONTEXT_FLOATING_POINT;
    472  1.1.1.4  christos   static constexpr DWORD debug    = CONTEXT_DEBUG_REGISTERS;
    473  1.1.1.4  christos   static constexpr DWORD extended = CONTEXT_EXTENDED_REGISTERS;
    474  1.1.1.4  christos   static constexpr DWORD full	  = CONTEXT_FULL;
    475  1.1.1.4  christos   static constexpr DWORD all	  = (CONTEXT_FULL
    476  1.1.1.4  christos 				     | CONTEXT_FLOATING_POINT
    477  1.1.1.4  christos 				     | CONTEXT_SEGMENTS
    478  1.1.1.4  christos 				     | CONTEXT_DEBUG_REGISTERS
    479  1.1.1.4  christos 				     | CONTEXT_EXTENDED_REGISTERS);
    480  1.1.1.4  christos };
    481  1.1.1.4  christos 
    482  1.1.1.4  christos #ifdef __x86_64__
    483  1.1.1.4  christos template<>
    484  1.1.1.4  christos struct WindowsContext<WOW64_CONTEXT *>
    485  1.1.1.4  christos {
    486  1.1.1.4  christos   static constexpr DWORD control  = WOW64_CONTEXT_CONTROL;
    487  1.1.1.4  christos   static constexpr DWORD floating = WOW64_CONTEXT_FLOATING_POINT;
    488  1.1.1.4  christos   static constexpr DWORD debug	  = WOW64_CONTEXT_DEBUG_REGISTERS;
    489  1.1.1.4  christos   static constexpr DWORD extended = WOW64_CONTEXT_EXTENDED_REGISTERS;
    490  1.1.1.4  christos   static constexpr DWORD full	  = WOW64_CONTEXT_FULL;
    491  1.1.1.4  christos   static constexpr DWORD all	  = WOW64_CONTEXT_ALL;
    492  1.1.1.4  christos };
    493  1.1.1.4  christos #endif
    494  1.1.1.4  christos 
    495  1.1.1.4  christos /* Overloaded helper functions to call the correct function based on the used
    496  1.1.1.4  christos    type (CONTEXT or WOW64_CONTEXT).  */
    497  1.1.1.4  christos 
    498  1.1.1.4  christos static inline BOOL
    499  1.1.1.4  christos get_thread_context (HANDLE h, CONTEXT *context)
    500  1.1.1.4  christos {
    501  1.1.1.4  christos   return GetThreadContext (h, context);
    502  1.1.1.4  christos }
    503  1.1.1.4  christos 
    504  1.1.1.4  christos static inline BOOL
    505  1.1.1.4  christos set_thread_context (HANDLE h, CONTEXT *context)
    506  1.1.1.4  christos {
    507  1.1.1.4  christos   return SetThreadContext (h, context);
    508  1.1.1.4  christos }
    509  1.1.1.4  christos 
    510  1.1.1.4  christos static inline BOOL
    511  1.1.1.4  christos get_thread_selector_entry (CONTEXT *, HANDLE thread, DWORD sel,
    512  1.1.1.4  christos 			   LDT_ENTRY *info)
    513  1.1.1.4  christos {
    514  1.1.1.4  christos   return GetThreadSelectorEntry (thread, sel, info);
    515  1.1.1.4  christos }
    516  1.1.1.4  christos 
    517  1.1.1.4  christos static inline BOOL
    518  1.1.1.4  christos enum_process_modules (CONTEXT *, HANDLE process,
    519  1.1.1.4  christos 		      HMODULE *modules, DWORD size, LPDWORD needed)
    520  1.1.1.4  christos {
    521  1.1.1.4  christos   return EnumProcessModules (process, modules, size, needed);
    522  1.1.1.4  christos }
    523  1.1.1.4  christos 
    524  1.1.1.4  christos #ifdef __x86_64__
    525  1.1.1.4  christos static inline BOOL
    526  1.1.1.4  christos get_thread_context (HANDLE h, WOW64_CONTEXT *context)
    527  1.1.1.4  christos {
    528  1.1.1.4  christos   return Wow64GetThreadContext (h, context);
    529  1.1.1.4  christos }
    530  1.1.1.4  christos 
    531  1.1.1.4  christos static inline BOOL
    532  1.1.1.4  christos set_thread_context (HANDLE h, WOW64_CONTEXT *context)
    533  1.1.1.4  christos {
    534  1.1.1.4  christos   return Wow64SetThreadContext (h, context);
    535  1.1.1.4  christos }
    536  1.1.1.4  christos 
    537  1.1.1.4  christos static inline BOOL
    538  1.1.1.4  christos get_thread_selector_entry (WOW64_CONTEXT *, HANDLE thread, DWORD sel,
    539  1.1.1.4  christos 			   LDT_ENTRY *info)
    540  1.1.1.4  christos {
    541  1.1.1.4  christos   return Wow64GetThreadSelectorEntry (thread, sel, info);
    542  1.1.1.4  christos }
    543  1.1.1.4  christos 
    544  1.1.1.4  christos static inline BOOL
    545  1.1.1.4  christos enum_process_modules (WOW64_CONTEXT *, HANDLE process,
    546  1.1.1.4  christos 		      HMODULE *modules, DWORD size, LPDWORD needed)
    547  1.1.1.4  christos {
    548  1.1.1.4  christos   return EnumProcessModulesEx (process, modules, size, needed,
    549  1.1.1.4  christos 			       LIST_MODULES_32BIT);
    550  1.1.1.4  christos }
    551  1.1.1.4  christos #endif
    552  1.1.1.4  christos 
    553  1.1.1.2  christos /* Load any functions which may not be available in ancient versions
    554  1.1.1.2  christos    of Windows.  */
    555  1.1.1.2  christos 
    556  1.1.1.2  christos extern bool initialize_loadable ();
    557  1.1.1.2  christos 
    558      1.1  christos }
    559      1.1  christos 
    560  1.1.1.4  christos #endif /* GDB_NAT_WINDOWS_NAT_H */
    561