/* Internal interfaces for the Windows code
   Copyright (C) 1995-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef NAT_WINDOWS_NAT_H
#define NAT_WINDOWS_NAT_H

#include <windows.h>
#include <psapi.h>
#include <vector>

#include "gdbsupport/gdb_optional.h"
#include "target/waitstatus.h"

#define STATUS_WX86_BREAKPOINT 0x4000001F
#define STATUS_WX86_SINGLE_STEP 0x4000001E

namespace windows_nat
{

/* Thread information structure used to track extra information about
   each thread.  */
struct windows_thread_info
{
  windows_thread_info (DWORD tid_, HANDLE h_, CORE_ADDR tlb)
    : tid (tid_),
      h (h_),
      thread_local_base (tlb)
  {
  }

  DISABLE_COPY_AND_ASSIGN (windows_thread_info);

  /* Ensure that this thread has been suspended.  */
  void suspend ();

  /* Resume the thread if it has been suspended.  */
  void resume ();

  /* Return the thread's name, or nullptr if not known.  The name is
     stored in this thread and is guaranteed to live until at least
     the next call.  */
  const char *thread_name ();

  /* The Win32 thread identifier.  */
  DWORD tid;

  /* The handle to the thread.  */
  HANDLE h;

  /* Thread Information Block address.  */
  CORE_ADDR thread_local_base;

  /* This keeps track of whether SuspendThread was called on this
     thread.  -1 means there was a failure or that the thread was
     explicitly not suspended, 1 means it was called, and 0 means it
     was not.  */
  int suspended = 0;

  /* The context of the thread, including any manipulations.  */
  union
  {
    CONTEXT context {};
#ifdef __x86_64__
    WOW64_CONTEXT wow64_context;
#endif
  };

  /* Whether debug registers changed since we last set CONTEXT back to
     the thread.  */
  bool debug_registers_changed = false;

  /* Nonzero if CONTEXT is invalidated and must be re-read from the
     inferior thread.  */
  bool reload_context = false;

  /* True if this thread is currently stopped at a software
     breakpoint.  This is used to offset the PC when needed.  */
  bool stopped_at_software_breakpoint = false;

  /* True if we've adjusted the PC after hitting a software
     breakpoint, false otherwise.  This lets us avoid multiple
     adjustments if the registers are read multiple times.  */
  bool pc_adjusted = false;

  /* The name of the thread.  */
  gdb::unique_xmalloc_ptr<char> name;
};


/* Possible values to pass to 'thread_rec'.  */
enum thread_disposition_type
{
  /* Do not invalidate the thread's context, and do not suspend the
     thread.  */
  DONT_INVALIDATE_CONTEXT,
  /* Invalidate the context, but do not suspend the thread.  */
  DONT_SUSPEND,
  /* Invalidate the context and suspend the thread.  */
  INVALIDATE_CONTEXT
};

/* A single pending stop.  See "pending_stops" for more
   information.  */
struct pending_stop
{
  /* The thread id.  */
  DWORD thread_id;

  /* The target waitstatus we computed.  */
  target_waitstatus status;

  /* The event.  A few fields of this can be referenced after a stop,
     and it seemed simplest to store the entire event.  */
  DEBUG_EVENT event;
};

enum handle_exception_result
{
  HANDLE_EXCEPTION_UNHANDLED = 0,
  HANDLE_EXCEPTION_HANDLED,
  HANDLE_EXCEPTION_IGNORED
};

/* A single Windows process.  An object of this type (or subclass) is
   created by the client.  Some methods must be provided by the client
   as well.  */

struct windows_process_info
{
  /* The process handle */
  HANDLE handle = 0;
  DWORD main_thread_id = 0;
  enum gdb_signal last_sig = GDB_SIGNAL_0;

  /* The current debug event from WaitForDebugEvent or from a pending
     stop.  */
  DEBUG_EVENT current_event {};

  /* The ID of the thread for which we anticipate a stop event.
     Normally this is -1, meaning we'll accept an event in any
     thread.  */
  DWORD desired_stop_thread_id = -1;

  /* A vector of pending stops.  Sometimes, Windows will report a stop
     on a thread that has been ostensibly suspended.  We believe what
     happens here is that two threads hit a breakpoint simultaneously,
     and the Windows kernel queues the stop events.  However, this can
     result in the strange effect of trying to single step thread A --
     leaving all other threads suspended -- and then seeing a stop in
     thread B.  To handle this scenario, we queue all such "pending"
     stops here, and then process them once the step has completed.  See
     PR gdb/22992.  */
  std::vector<pending_stop> pending_stops;

  /* Contents of $_siginfo */
  EXCEPTION_RECORD siginfo_er {};

#ifdef __x86_64__
  /* The target is a WOW64 process */
  bool wow64_process = false;
  /* Ignore first breakpoint exception of WOW64 process */
  bool ignore_first_breakpoint = false;
#endif


  /* Find a thread record given a thread id.  THREAD_DISPOSITION
     controls whether the thread is suspended, and whether the context
     is invalidated.

     This function must be supplied by the embedding application.  */
  virtual windows_thread_info *thread_rec (ptid_t ptid,
					   thread_disposition_type disposition) = 0;

  /* Handle OUTPUT_DEBUG_STRING_EVENT from child process.  Updates
     OURSTATUS and returns the thread id if this represents a thread
     change (this is specific to Cygwin), otherwise 0.

     Cygwin prepends its messages with a "cygwin:".  Interpret this as
     a Cygwin signal.  Otherwise just print the string as a warning.

     This function must be supplied by the embedding application.  */
  virtual int handle_output_debug_string (struct target_waitstatus *ourstatus) = 0;

  /* Handle a DLL load event.

     This function assumes that the current event did not occur during
     inferior initialization.

     DLL_NAME is the name of the library.  BASE is the base load
     address.

     This function must be supplied by the embedding application.  */

  virtual void handle_load_dll (const char *dll_name, LPVOID base) = 0;

  /* Handle a DLL unload event.

     This function assumes that this event did not occur during inferior
     initialization.

     This function must be supplied by the embedding application.  */

  virtual void handle_unload_dll () = 0;

  /* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
     application a chance to change it to be considered "unhandled".
     This function must be supplied by the embedding application.  If it
     returns true, then the exception is "unhandled".  */

  virtual bool handle_access_violation (const EXCEPTION_RECORD *rec) = 0;

  handle_exception_result handle_exception
       (struct target_waitstatus *ourstatus, bool debug_exceptions);

  /* Call to indicate that a DLL was loaded.  */

  void dll_loaded_event ();

  /* Iterate over all DLLs currently mapped by our inferior, and
     add them to our list of solibs.  */

  void add_all_dlls ();

  /* Return true if there is a pending stop matching
     desired_stop_thread_id.  If DEBUG_EVENTS is true, logging will be
     enabled.  */

  bool matching_pending_stop (bool debug_events);

  /* See if a pending stop matches DESIRED_STOP_THREAD_ID.  If so,
     remove it from the list of pending stops, set 'current_event', and
     return it.  Otherwise, return an empty optional.  */

  gdb::optional<pending_stop> fetch_pending_stop (bool debug_events);

  const char *pid_to_exec_file (int);

private:

  /* Handle MS_VC_EXCEPTION when processing a stop.  MS_VC_EXCEPTION is
     somewhat undocumented but is used to tell the debugger the name of
     a thread.

     Return true if the exception was handled; return false otherwise.  */

  bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);

  /* Iterate over all DLLs currently mapped by our inferior, looking for
     a DLL which is loaded at LOAD_ADDR.  If found, add the DLL to our
     list of solibs; otherwise do nothing.  LOAD_ADDR NULL means add all
     DLLs to the list of solibs; this is used when the inferior finishes
     its initialization, and all the DLLs it statically depends on are
     presumed loaded.  */

  void add_dll (LPVOID load_addr);

  /* Try to determine the executable filename.

     EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.

     Upon success, the filename is stored inside EXE_NAME_RET, and
     this function returns nonzero.

     Otherwise, this function returns zero and the contents of
     EXE_NAME_RET is undefined.  */

  int get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len);
};

/* A simple wrapper for ContinueDebugEvent that continues the last
   waited-for event.  If DEBUG_EVENTS is true, logging will be
   enabled.  */

extern BOOL continue_last_debug_event (DWORD continue_status,
				       bool debug_events);

/* A simple wrapper for WaitForDebugEvent that also sets the internal
   'last_wait_event' on success.  */

extern BOOL wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout);

/* Wrappers for CreateProcess.  These exist primarily so that the
   "disable randomization" feature can be implemented in a single
   place.  */

extern BOOL create_process (const char *image, char *command_line,
			    DWORD flags, void *environment,
			    const char *cur_dir,
			    bool no_randomization,
			    STARTUPINFOA *startup_info,
			    PROCESS_INFORMATION *process_info);
#ifdef __CYGWIN__
extern BOOL create_process (const wchar_t *image, wchar_t *command_line,
			    DWORD flags, void *environment,
			    const wchar_t *cur_dir,
			    bool no_randomization,
			    STARTUPINFOW *startup_info,
			    PROCESS_INFORMATION *process_info);
#endif /* __CYGWIN__ */

#define AdjustTokenPrivileges		dyn_AdjustTokenPrivileges
#define DebugActiveProcessStop		dyn_DebugActiveProcessStop
#define DebugBreakProcess		dyn_DebugBreakProcess
#define DebugSetProcessKillOnExit	dyn_DebugSetProcessKillOnExit
#undef EnumProcessModules
#define EnumProcessModules		dyn_EnumProcessModules
#undef EnumProcessModulesEx
#define EnumProcessModulesEx		dyn_EnumProcessModulesEx
#undef GetModuleInformation
#define GetModuleInformation		dyn_GetModuleInformation
#undef GetModuleFileNameExA
#define GetModuleFileNameExA		dyn_GetModuleFileNameExA
#undef GetModuleFileNameExW
#define GetModuleFileNameExW		dyn_GetModuleFileNameExW
#define LookupPrivilegeValueA		dyn_LookupPrivilegeValueA
#define OpenProcessToken		dyn_OpenProcessToken
#define GetConsoleFontSize		dyn_GetConsoleFontSize
#define GetCurrentConsoleFont		dyn_GetCurrentConsoleFont
#define Wow64SuspendThread		dyn_Wow64SuspendThread
#define Wow64GetThreadContext		dyn_Wow64GetThreadContext
#define Wow64SetThreadContext		dyn_Wow64SetThreadContext
#define Wow64GetThreadSelectorEntry	dyn_Wow64GetThreadSelectorEntry
#define GenerateConsoleCtrlEvent	dyn_GenerateConsoleCtrlEvent
#define InitializeProcThreadAttributeList dyn_InitializeProcThreadAttributeList
#define UpdateProcThreadAttribute dyn_UpdateProcThreadAttribute
#define DeleteProcThreadAttributeList dyn_DeleteProcThreadAttributeList

typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL,
						   PTOKEN_PRIVILEGES,
						   DWORD, PTOKEN_PRIVILEGES,
						   PDWORD);
extern AdjustTokenPrivileges_ftype *AdjustTokenPrivileges;

typedef BOOL WINAPI (DebugActiveProcessStop_ftype) (DWORD);
extern DebugActiveProcessStop_ftype *DebugActiveProcessStop;

typedef BOOL WINAPI (DebugBreakProcess_ftype) (HANDLE);
extern DebugBreakProcess_ftype *DebugBreakProcess;

typedef BOOL WINAPI (DebugSetProcessKillOnExit_ftype) (BOOL);
extern DebugSetProcessKillOnExit_ftype *DebugSetProcessKillOnExit;

typedef BOOL WINAPI (EnumProcessModules_ftype) (HANDLE, HMODULE *, DWORD,
						LPDWORD);
extern EnumProcessModules_ftype *EnumProcessModules;

#ifdef __x86_64__
typedef BOOL WINAPI (EnumProcessModulesEx_ftype) (HANDLE, HMODULE *, DWORD,
						  LPDWORD, DWORD);
extern EnumProcessModulesEx_ftype *EnumProcessModulesEx;
#endif

typedef BOOL WINAPI (GetModuleInformation_ftype) (HANDLE, HMODULE,
						  LPMODULEINFO, DWORD);
extern GetModuleInformation_ftype *GetModuleInformation;

typedef DWORD WINAPI (GetModuleFileNameExA_ftype) (HANDLE, HMODULE, LPSTR,
						  DWORD);
extern GetModuleFileNameExA_ftype *GetModuleFileNameExA;

typedef DWORD WINAPI (GetModuleFileNameExW_ftype) (HANDLE, HMODULE,
						   LPWSTR, DWORD);
extern GetModuleFileNameExW_ftype *GetModuleFileNameExW;

typedef BOOL WINAPI (LookupPrivilegeValueA_ftype) (LPCSTR, LPCSTR, PLUID);
extern LookupPrivilegeValueA_ftype *LookupPrivilegeValueA;

typedef BOOL WINAPI (OpenProcessToken_ftype) (HANDLE, DWORD, PHANDLE);
extern OpenProcessToken_ftype *OpenProcessToken;

typedef BOOL WINAPI (GetCurrentConsoleFont_ftype) (HANDLE, BOOL,
						   CONSOLE_FONT_INFO *);
extern GetCurrentConsoleFont_ftype *GetCurrentConsoleFont;

typedef COORD WINAPI (GetConsoleFontSize_ftype) (HANDLE, DWORD);
extern GetConsoleFontSize_ftype *GetConsoleFontSize;

#ifdef __x86_64__
typedef DWORD WINAPI (Wow64SuspendThread_ftype) (HANDLE);
extern Wow64SuspendThread_ftype *Wow64SuspendThread;

typedef BOOL WINAPI (Wow64GetThreadContext_ftype) (HANDLE, PWOW64_CONTEXT);
extern Wow64GetThreadContext_ftype *Wow64GetThreadContext;

typedef BOOL WINAPI (Wow64SetThreadContext_ftype) (HANDLE,
						   const WOW64_CONTEXT *);
extern Wow64SetThreadContext_ftype *Wow64SetThreadContext;

typedef BOOL WINAPI (Wow64GetThreadSelectorEntry_ftype) (HANDLE, DWORD,
							 PLDT_ENTRY);
extern Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry;
#endif

typedef BOOL WINAPI (GenerateConsoleCtrlEvent_ftype) (DWORD, DWORD);
extern GenerateConsoleCtrlEvent_ftype *GenerateConsoleCtrlEvent;

/* We use a local typedef for this type to avoid depending on
   Windows 8.  */
typedef void *gdb_lpproc_thread_attribute_list;

typedef BOOL WINAPI (InitializeProcThreadAttributeList_ftype)
     (gdb_lpproc_thread_attribute_list lpAttributeList,
      DWORD dwAttributeCount, DWORD dwFlags, PSIZE_T lpSize);
extern InitializeProcThreadAttributeList_ftype *InitializeProcThreadAttributeList;

typedef BOOL WINAPI (UpdateProcThreadAttribute_ftype)
     (gdb_lpproc_thread_attribute_list lpAttributeList,
      DWORD dwFlags, DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize,
      PVOID lpPreviousValue, PSIZE_T lpReturnSize);
extern UpdateProcThreadAttribute_ftype *UpdateProcThreadAttribute;

typedef void WINAPI (DeleteProcThreadAttributeList_ftype)
     (gdb_lpproc_thread_attribute_list lpAttributeList);
extern DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;

/* Return true if it's possible to disable randomization on this
   host.  */

extern bool disable_randomization_available ();

/* Load any functions which may not be available in ancient versions
   of Windows.  */

extern bool initialize_loadable ();

}

#endif
