section-select: Fix exclude-file-3
[binutils-gdb.git] / gdbserver / win32-low.cc
index 8fde3e95b2d6bde8abe0301d6db026fb1560cd69..af132f60215d14e61a512719faedc36384694952 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "server.h"
 #include "regcache.h"
-#include "gdb/fileio.h"
+#include "gdbsupport/fileio.h"
 #include "mem-break.h"
 #include "win32-low.h"
 #include "gdbthread.h"
@@ -38,7 +38,8 @@
 
 using namespace windows_nat;
 
-static windows_process_info windows_process;
+/* See win32-low.h.  */
+gdbserver_windows_process windows_process;
 
 #ifndef USE_WIN32API
 #include <sys/cygwin.h>
@@ -60,31 +61,8 @@ static windows_process_info windows_process;
 #define _T(x) TEXT (x)
 #endif
 
-#ifndef COUNTOF
-#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
-#endif
-
 int using_threads = 1;
 
-/* Globals.  */
-static int attaching = 0;
-
-/* A status that hasn't been reported to the core yet, and so
-   win32_wait should return it next, instead of fetching the next
-   debug event off the win32 API.  */
-static struct target_waitstatus cached_status;
-
-/* Non zero if an interrupt request is to be satisfied by suspending
-   all threads.  */
-static int soft_interrupt_requested = 0;
-
-/* Non zero if the inferior is stopped in a simulated breakpoint done
-   by suspending all the threads.  */
-static int faked_breakpoint = 0;
-
-/* True if current_process_handle needs to be closed.  */
-static bool open_process_used = false;
-
 const struct target_desc *win32_tdesc;
 #ifdef __x86_64__
 const struct target_desc *wow64_win32_tdesc;
@@ -113,7 +91,7 @@ static void
 win32_get_thread_context (windows_thread_info *th)
 {
 #ifdef __x86_64__
-  if (wow64_process)
+  if (windows_process.wow64_process)
     memset (&th->wow64_context, 0, sizeof (WOW64_CONTEXT));
   else
 #endif
@@ -127,7 +105,7 @@ static void
 win32_set_thread_context (windows_thread_info *th)
 {
 #ifdef __x86_64__
-  if (wow64_process)
+  if (windows_process.wow64_process)
     Wow64SetThreadContext (th->h, &th->wow64_context);
   else
 #endif
@@ -150,7 +128,7 @@ win32_require_context (windows_thread_info *th)
 {
   DWORD context_flags;
 #ifdef __x86_64__
-  if (wow64_process)
+  if (windows_process.wow64_process)
     context_flags = th->wow64_context.ContextFlags;
   else
 #endif
@@ -165,7 +143,7 @@ win32_require_context (windows_thread_info *th)
 /* See nat/windows-nat.h.  */
 
 windows_thread_info *
-windows_nat::windows_process_info::thread_rec
+gdbserver_windows_process::thread_rec
      (ptid_t ptid, thread_disposition_type disposition)
 {
   thread_info *thread = find_thread_ptid (ptid);
@@ -192,7 +170,7 @@ child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb)
 #ifdef __x86_64__
   /* For WOW64 processes, this is actually the pointer to the 64bit TIB,
      and the 32bit TIB is exactly 2 pages after it.  */
-  if (wow64_process)
+  if (windows_process.wow64_process)
     base += 2 * 4096; /* page size = 4096 */
 #endif
   th = new windows_thread_info (tid, h, base);
@@ -325,10 +303,6 @@ child_init_thread_list (void)
   for_each_thread (delete_thread_info);
 }
 
-/* Zero during the child initialization phase, and nonzero otherwise.  */
-
-static int child_initialization_done = 0;
-
 static void
 do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
 {
@@ -336,12 +310,11 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
 
   windows_process.last_sig = GDB_SIGNAL_0;
   windows_process.handle = proch;
-  windows_process.id = pid;
   windows_process.main_thread_id = 0;
 
-  soft_interrupt_requested = 0;
-  faked_breakpoint = 0;
-  open_process_used = true;
+  windows_process.soft_interrupt_requested = 0;
+  windows_process.faked_breakpoint = 0;
+  windows_process.open_process_used = true;
 
   memset (&windows_process.current_event, 0,
          sizeof (windows_process.current_event));
@@ -354,30 +327,31 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
       error ("Check if WOW64 process failed (error %d): %s\n",
             (int) err, strwinerror (err));
     }
-  wow64_process = wow64;
+  windows_process.wow64_process = wow64;
 
-  if (wow64_process
+  if (windows_process.wow64_process
       && (Wow64GetThreadContext == nullptr
          || Wow64SetThreadContext == nullptr))
     error ("WOW64 debugging is not supported on this system.\n");
 
-  ignore_first_breakpoint = !attached && wow64_process;
+  windows_process.ignore_first_breakpoint
+    = !attached && windows_process.wow64_process;
 #endif
 
   proc = add_process (pid, attached);
 #ifdef __x86_64__
-  if (wow64_process)
+  if (windows_process.wow64_process)
     proc->tdesc = wow64_win32_tdesc;
   else
 #endif
     proc->tdesc = win32_tdesc;
   child_init_thread_list ();
-  child_initialization_done = 0;
+  windows_process.child_initialization_done = 0;
 
   if (the_low_target.initial_stuff != NULL)
     (*the_low_target.initial_stuff) ();
 
-  cached_status.set_ignore ();
+  windows_process.cached_status.set_ignore ();
 
   /* Flush all currently pending debug events (thread and dll list) up
      to the initial breakpoint.  */
@@ -390,7 +364,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
       /* Note win32_wait doesn't return thread events.  */
       if (status.kind () != TARGET_WAITKIND_LOADED)
        {
-         cached_status = status;
+         windows_process.cached_status = status;
          break;
        }
 
@@ -422,7 +396,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
      phase, and then process them all in one batch now.  */
   windows_process.add_all_dlls ();
 
-  child_initialization_done = 1;
+  windows_process.child_initialization_done = 1;
 }
 
 /* Resume all artificially suspended threads if we are continuing
@@ -440,7 +414,7 @@ continue_one_thread (thread_info *thread, int thread_id)
        {
          DWORD *context_flags;
 #ifdef __x86_64__
-         if (wow64_process)
+         if (windows_process.wow64_process)
            context_flags = &th->wow64_context.ContextFlags;
          else
 #endif
@@ -469,7 +443,7 @@ child_continue (DWORD continue_status, int thread_id)
     {
       continue_one_thread (thread, thread_id);
     });
-  faked_breakpoint = 0;
+  windows_process.faked_breakpoint = 0;
 
   return continue_last_debug_event (continue_status, debug_threads);
 }
@@ -505,61 +479,6 @@ child_store_inferior_registers (struct regcache *regcache, int r)
       (*the_low_target.store_inferior_register) (regcache, th, regno);
 }
 
-/* Map the Windows error number in ERROR to a locale-dependent error
-   message string and return a pointer to it.  Typically, the values
-   for ERROR come from GetLastError.
-
-   The string pointed to shall not be modified by the application,
-   but may be overwritten by a subsequent call to strwinerror
-
-   The strwinerror function does not change the current setting
-   of GetLastError.  */
-
-char *
-strwinerror (DWORD error)
-{
-  static char buf[1024];
-  TCHAR *msgbuf;
-  DWORD lasterr = GetLastError ();
-  DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
-                              | FORMAT_MESSAGE_ALLOCATE_BUFFER,
-                              NULL,
-                              error,
-                              0, /* Default language */
-                              (LPTSTR) &msgbuf,
-                              0,
-                              NULL);
-  if (chars != 0)
-    {
-      /* If there is an \r\n appended, zap it.  */
-      if (chars >= 2
-         && msgbuf[chars - 2] == '\r'
-         && msgbuf[chars - 1] == '\n')
-       {
-         chars -= 2;
-         msgbuf[chars] = 0;
-       }
-
-      if (chars > ((COUNTOF (buf)) - 1))
-       {
-         chars = COUNTOF (buf) - 1;
-         msgbuf [chars] = 0;
-       }
-
-#ifdef UNICODE
-      wcstombs (buf, msgbuf, chars + 1);
-#else
-      strncpy (buf, msgbuf, chars + 1);
-#endif
-      LocalFree (msgbuf);
-    }
-  else
-    sprintf (buf, "unknown win32 error (%u)", (unsigned) error);
-
-  SetLastError (lasterr);
-  return buf;
-}
-
 static BOOL
 create_process (const char *program, char *args,
                DWORD flags, PROCESS_INFORMATION *pi)
@@ -577,17 +496,15 @@ create_process (const char *program, char *args,
   strcpy (program_and_args, program);
   strcat (program_and_args, " ");
   strcat (program_and_args, args);
-  ret = CreateProcessA (program,           /* image name */
+  ret = create_process (program,           /* image name */
                        program_and_args,  /* command line */
-                       NULL,              /* security */
-                       NULL,              /* thread */
-                       TRUE,              /* inherit handles */
                        flags,             /* start flags */
                        NULL,              /* environment */
                        /* current directory */
                        (inferior_cwd.empty ()
                         ? NULL
                         : gdb_tilde_expand (inferior_cwd.c_str ()).c_str()),
+                       get_client_state ().disable_randomization,
                        &si,               /* start info */
                        pi);               /* proc info */
 
@@ -616,7 +533,7 @@ win32_process_target::create_inferior (const char *program,
   char *args = (char *) str_program_args.c_str ();
 
   /* win32_wait needs to know we're not attaching.  */
-  attaching = 0;
+  windows_process.attaching = 0;
 
   if (!program)
     error ("No executable specified, specify executable to debug.\n");
@@ -676,12 +593,12 @@ win32_process_target::create_inferior (const char *program,
 
   /* Wait till we are at 1st instruction in program, return new pid
      (assuming success).  */
-  cs.last_ptid = wait (ptid_t (windows_process.id), &cs.last_status, 0);
+  cs.last_ptid = wait (ptid_t (pi.dwProcessId), &cs.last_status, 0);
 
   /* Necessary for handle_v_kill.  */
-  signal_pid = windows_process.id;
+  signal_pid = pi.dwProcessId;
 
-  return windows_process.id;
+  return pi.dwProcessId;
 }
 
 /* Attach to a running process.
@@ -701,7 +618,7 @@ win32_process_target::attach (unsigned long pid)
          DebugSetProcessKillOnExit (FALSE);
 
          /* win32_wait needs to know we're attaching.  */
-         attaching = 1;
+         windows_process.attaching = 1;
          do_initial_child_stuff (h, pid, 1);
          return 0;
        }
@@ -717,7 +634,7 @@ win32_process_target::attach (unsigned long pid)
 /* See nat/windows-nat.h.  */
 
 int
-windows_nat::windows_process_info::handle_output_debug_string
+gdbserver_windows_process::handle_output_debug_string
      (struct target_waitstatus *ourstatus)
 {
 #define READ_BUFFER_LEN 1024
@@ -766,10 +683,10 @@ windows_nat::windows_process_info::handle_output_debug_string
 static void
 win32_clear_inferiors (void)
 {
-  if (open_process_used)
+  if (windows_process.open_process_used)
     {
       CloseHandle (windows_process.handle);
-      open_process_used = false;
+      windows_process.open_process_used = false;
     }
 
   for_each_thread (delete_thread_info);
@@ -814,7 +731,7 @@ win32_process_target::detach (process_info *process)
   resume.sig = 0;
   this->resume (&resume, 1);
 
-  if (!DebugActiveProcessStop (windows_process.id))
+  if (!DebugActiveProcessStop (process->pid))
     return -1;
 
   DebugSetProcessKillOnExit (FALSE);
@@ -913,7 +830,7 @@ win32_process_target::resume (thread_resume *resume_info, size_t n)
 
       DWORD *context_flags;
 #ifdef __x86_64__
-      if (wow64_process)
+      if (windows_process.wow64_process)
        context_flags = &th->wow64_context.ContextFlags;
       else
 #endif
@@ -947,8 +864,7 @@ win32_process_target::resume (thread_resume *resume_info, size_t n)
 /* See nat/windows-nat.h.  */
 
 void
-windows_nat::windows_process_info::handle_load_dll (const char *name,
-                                                   LPVOID base)
+gdbserver_windows_process::handle_load_dll (const char *name, LPVOID base)
 {
   CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) base;
 
@@ -1002,7 +918,7 @@ windows_nat::windows_process_info::handle_load_dll (const char *name,
 /* See nat/windows-nat.h.  */
 
 void
-windows_nat::windows_process_info::handle_unload_dll ()
+gdbserver_windows_process::handle_unload_dll ()
 {
   CORE_ADDR load_addr =
          (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll;
@@ -1027,7 +943,7 @@ fake_breakpoint_event (void)
 {
   OUTMSG2(("fake_breakpoint_event\n"));
 
-  faked_breakpoint = 1;
+  windows_process.faked_breakpoint = 1;
 
   memset (&windows_process.current_event, 0,
          sizeof (windows_process.current_event));
@@ -1042,7 +958,7 @@ fake_breakpoint_event (void)
 /* See nat/windows-nat.h.  */
 
 bool
-windows_nat::windows_process_info::handle_access_violation
+gdbserver_windows_process::handle_access_violation
      (const EXCEPTION_RECORD *rec)
 {
   return false;
@@ -1068,7 +984,7 @@ maybe_adjust_pc ()
           == EXCEPTION_BREAKPOINT)
          || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
              == STATUS_WX86_BREAKPOINT))
-      && child_initialization_done)
+      && windows_process.child_initialization_done)
     {
       th->stopped_at_software_breakpoint = true;
       CORE_ADDR pc = regcache_read_pc (regcache);
@@ -1094,14 +1010,14 @@ get_child_debug_event (DWORD *continue_status,
 
   DEBUG_EVENT *current_event = &windows_process.current_event;
 
-  if (soft_interrupt_requested)
+  if (windows_process.soft_interrupt_requested)
     {
-      soft_interrupt_requested = 0;
+      windows_process.soft_interrupt_requested = 0;
       fake_breakpoint_event ();
       goto gotevent;
     }
 
-  attaching = 0;
+  windows_process.attaching = 0;
   {
     gdb::optional<pending_stop> stop
       = windows_process.fetch_pending_stop (debug_threads);
@@ -1170,10 +1086,10 @@ get_child_debug_event (DWORD *continue_status,
                (unsigned) current_event->dwThreadId));
       CloseHandle (current_event->u.CreateProcessInfo.hFile);
 
-      if (open_process_used)
+      if (windows_process.open_process_used)
        {
          CloseHandle (windows_process.handle);
-         open_process_used = false;
+         windows_process.open_process_used = false;
        }
 
       windows_process.handle = current_event->u.CreateProcessInfo.hProcess;
@@ -1212,7 +1128,7 @@ get_child_debug_event (DWORD *continue_status,
                (unsigned) current_event->dwProcessId,
                (unsigned) current_event->dwThreadId));
       CloseHandle (current_event->u.LoadDll.hFile);
-      if (! child_initialization_done)
+      if (! windows_process.child_initialization_done)
        break;
       windows_process.dll_loaded_event ();
 
@@ -1224,7 +1140,7 @@ get_child_debug_event (DWORD *continue_status,
                "for pid=%u tid=%x\n",
                (unsigned) current_event->dwProcessId,
                (unsigned) current_event->dwThreadId));
-      if (! child_initialization_done)
+      if (! windows_process.child_initialization_done)
        break;
       windows_process.handle_unload_dll ();
       ourstatus->set_loaded ();
@@ -1286,14 +1202,14 @@ ptid_t
 win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
                            target_wait_flags options)
 {
-  if (cached_status.kind () != TARGET_WAITKIND_IGNORE)
+  if (windows_process.cached_status.kind () != TARGET_WAITKIND_IGNORE)
     {
       /* The core always does a wait after creating the inferior, and
         do_initial_child_stuff already ran the inferior to the
         initial breakpoint (or an exit, if creating the process
         fails).  Report it now.  */
-      *ourstatus = cached_status;
-      cached_status.set_ignore ();
+      *ourstatus = windows_process.cached_status;
+      windows_process.cached_status.set_ignore ();
       return debug_event_ptid (&windows_process.current_event);
     }
 
@@ -1373,7 +1289,7 @@ win32_process_target::write_memory (CORE_ADDR memaddr,
 void
 win32_process_target::request_interrupt ()
 {
-  if (GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, windows_process.id))
+  if (GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, signal_pid))
     return;
 
   /* GenerateConsoleCtrlEvent can fail if process id being debugged is
@@ -1385,7 +1301,7 @@ win32_process_target::request_interrupt ()
     return;
 
   /* Last resort, suspend all threads manually.  */
-  soft_interrupt_requested = 1;
+  windows_process.soft_interrupt_requested = 1;
 }
 
 bool
@@ -1419,19 +1335,22 @@ win32_process_target::qxfer_siginfo (const char *annex,
 
 #ifdef __x86_64__
   EXCEPTION_RECORD32 er32;
-  if (wow64_process)
+  if (windows_process.wow64_process)
     {
       buf = (char *) &er32;
       bufsize = sizeof (er32);
 
-      er32.ExceptionCode = siginfo_er.ExceptionCode;
-      er32.ExceptionFlags = siginfo_er.ExceptionFlags;
-      er32.ExceptionRecord = (uintptr_t) siginfo_er.ExceptionRecord;
-      er32.ExceptionAddress = (uintptr_t) siginfo_er.ExceptionAddress;
-      er32.NumberParameters = siginfo_er.NumberParameters;
+      er32.ExceptionCode = windows_process.siginfo_er.ExceptionCode;
+      er32.ExceptionFlags = windows_process.siginfo_er.ExceptionFlags;
+      er32.ExceptionRecord
+       = (uintptr_t) windows_process.siginfo_er.ExceptionRecord;
+      er32.ExceptionAddress
+       = (uintptr_t) windows_process.siginfo_er.ExceptionAddress;
+      er32.NumberParameters = windows_process.siginfo_er.NumberParameters;
       int i;
       for (i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++)
-       er32.ExceptionInformation[i] = siginfo_er.ExceptionInformation[i];
+       er32.ExceptionInformation[i]
+         = windows_process.siginfo_er.ExceptionInformation[i];
     }
 #endif
 
@@ -1502,6 +1421,21 @@ win32_process_target::write_pc (struct regcache *regcache, CORE_ADDR pc)
   return (*the_low_target.set_pc) (regcache, pc);
 }
 
+const char *
+win32_process_target::thread_name (ptid_t thread)
+{
+  windows_thread_info *th
+    = windows_process.thread_rec (current_thread_ptid (),
+                                 DONT_INVALIDATE_CONTEXT);
+  return th->thread_name ();
+}
+
+const char *
+win32_process_target::pid_to_exec_file (int pid)
+{
+  return windows_process.pid_to_exec_file (pid);
+}
+
 /* The win32 target ops object.  */
 
 static win32_process_target the_win32_target;