bfd/
[deliverable/binutils-gdb.git] / gdb / win32-nat.c
index 52ff20a20aec985368122c4ba81b7838ccf29a52..9a1a28cfd56ecaf309ccfe1a0df8dd65de4db6cf 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-vector operations for controlling win32 child processes, for GDB.
 
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by Cygnus Solutions, A Red Hat Company.
 
@@ -48,7 +48,6 @@
 #include "objfiles.h"
 #include "gdb_obstack.h"
 #include "gdb_string.h"
-#include "gdb_stdint.h"
 #include "gdbthread.h"
 #include "gdbcmd.h"
 #include <sys/param.h>
@@ -61,7 +60,8 @@
 #include "i386-tdep.h"
 #include "i387-tdep.h"
 
-#include "i386-cygwin-tdep.h"
+#include "win32-tdep.h"
+#include "win32-nat.h"
 
 static struct target_ops win32_ops;
 
@@ -86,6 +86,12 @@ enum
 #endif
 #include <psapi.h>
 
+#ifndef CONTEXT_EXTENDED_REGISTERS
+/* This macro is only defined on ia32.  It only makes sense on this target,
+   so define it as zero if not already defined.  */
+#define CONTEXT_EXTENDED_REGISTERS 0
+#endif
+
 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
        | CONTEXT_EXTENDED_REGISTERS
 
@@ -106,7 +112,7 @@ static int debug_registers_used;
 #define DEBUG_MEM(x)   if (debug_memory)       printf_unfiltered x
 #define DEBUG_EXCEPT(x)        if (debug_exceptions)   printf_unfiltered x
 
-static void win32_stop (void);
+static void win32_stop (ptid_t);
 static int win32_win32_thread_alive (ptid_t);
 static void win32_kill_inferior (void);
 
@@ -156,11 +162,16 @@ static int debug_memory = 0;              /* show target memory accesses */
 static int debug_exceptions = 0;       /* show target exceptions */
 static int useshell = 0;               /* use shell for subprocesses */
 
-/* This vector maps GDB's idea of a register's number into an address
+/* This vector maps GDB's idea of a register's number into an offset
    in the win32 exception context vector.
 
    It also contains the bit mask needed to load the register in question.
 
+   The contents of this table can only be computed by the units
+   that provide CPU-specific support for Windows native debugging.
+   These units should set the table by calling
+   win32_set_context_register_offsets.
+
    One day we could read a reg, we could inspect the context we
    already have loaded, if it doesn't have the bit set that we need,
    we read that set of registers in using GetThreadContext.  If the
@@ -169,55 +180,7 @@ static int useshell = 0;           /* use shell for subprocesses */
    the other regs of the group, and then we copy the info in and set
    out bit. */
 
-#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
-static const int mappings[] =
-{
-  context_offset (Eax),
-  context_offset (Ecx),
-  context_offset (Edx),
-  context_offset (Ebx),
-  context_offset (Esp),
-  context_offset (Ebp),
-  context_offset (Esi),
-  context_offset (Edi),
-  context_offset (Eip),
-  context_offset (EFlags),
-  context_offset (SegCs),
-  context_offset (SegSs),
-  context_offset (SegDs),
-  context_offset (SegEs),
-  context_offset (SegFs),
-  context_offset (SegGs),
-  context_offset (FloatSave.RegisterArea[0 * 10]),
-  context_offset (FloatSave.RegisterArea[1 * 10]),
-  context_offset (FloatSave.RegisterArea[2 * 10]),
-  context_offset (FloatSave.RegisterArea[3 * 10]),
-  context_offset (FloatSave.RegisterArea[4 * 10]),
-  context_offset (FloatSave.RegisterArea[5 * 10]),
-  context_offset (FloatSave.RegisterArea[6 * 10]),
-  context_offset (FloatSave.RegisterArea[7 * 10]),
-  context_offset (FloatSave.ControlWord),
-  context_offset (FloatSave.StatusWord),
-  context_offset (FloatSave.TagWord),
-  context_offset (FloatSave.ErrorSelector),
-  context_offset (FloatSave.ErrorOffset),
-  context_offset (FloatSave.DataSelector),
-  context_offset (FloatSave.DataOffset),
-  context_offset (FloatSave.ErrorSelector)
-  /* XMM0-7 */ ,
-  context_offset (ExtendedRegisters[10*16]),
-  context_offset (ExtendedRegisters[11*16]),
-  context_offset (ExtendedRegisters[12*16]),
-  context_offset (ExtendedRegisters[13*16]),
-  context_offset (ExtendedRegisters[14*16]),
-  context_offset (ExtendedRegisters[15*16]),
-  context_offset (ExtendedRegisters[16*16]),
-  context_offset (ExtendedRegisters[17*16]),
-  /* MXCSR */
-  context_offset (ExtendedRegisters[24])
-};
-
-#undef context_offset
+static const int *mappings;
 
 /* This vector maps the target's idea of an exception (extracted
    from the DEBUG_EVENT structure) to GDB's idea. */
@@ -239,6 +202,15 @@ static const struct xlate_exception
   {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
   {-1, -1}};
 
+/* Set the MAPPINGS static global to OFFSETS.
+   See the description of MAPPINGS for more details.  */
+
+void
+win32_set_context_register_offsets (const int *offsets)
+{
+  mappings = offsets;
+}
+
 static void
 check (BOOL ok, const char *file, int line)
 {
@@ -281,11 +253,16 @@ thread_rec (DWORD id, int get_context)
   return NULL;
 }
 
-/* Add a thread to the thread list */
+/* Add a thread to the thread list */
 static thread_info *
-win32_add_thread (DWORD id, HANDLE h)
+win32_add_thread (ptid_t ptid, HANDLE h)
 {
   thread_info *th;
+  DWORD id;
+
+  gdb_assert (ptid_get_tid (ptid) != 0);
+
+  id = ptid_get_tid (ptid);
 
   if ((th = thread_rec (id, FALSE)))
     return th;
@@ -295,8 +272,8 @@ win32_add_thread (DWORD id, HANDLE h)
   th->h = h;
   th->next = thread_head.next;
   thread_head.next = th;
-  add_thread (pid_to_ptid (id));
-  /* Set the debug registers for the new thread in they are used.  */
+  add_thread (ptid);
+  /* Set the debug registers for the new thread if they are used.  */
   if (debug_registers_used)
     {
       /* Only change the value of the debug registers.  */
@@ -334,13 +311,18 @@ win32_init_thread_list (void)
 
 /* Delete a thread from the list of threads */
 static void
-win32_delete_thread (DWORD id)
+win32_delete_thread (ptid_t ptid)
 {
   thread_info *th;
+  DWORD id;
+
+  gdb_assert (ptid_get_tid (ptid) != 0);
+
+  id = ptid_get_tid (ptid);
 
   if (info_verbose)
-    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
-  delete_thread (pid_to_ptid (id));
+    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
+  delete_thread (ptid);
 
   for (th = &thread_head;
        th->next != NULL && th->next->id != id;
@@ -421,7 +403,7 @@ do_win32_fetch_inferior_registers (struct regcache *regcache, int r)
 static void
 win32_fetch_inferior_registers (struct regcache *regcache, int r)
 {
-  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
+  current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
   /* Check if current_thread exists.  Windows sometimes uses a non-existent
      thread id in its events */
   if (current_thread)
@@ -447,7 +429,7 @@ do_win32_store_inferior_registers (const struct regcache *regcache, int r)
 static void
 win32_store_inferior_registers (struct regcache *regcache, int r)
 {
-  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
+  current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
   /* Check if current_thread exists.  Windows sometimes uses a non-existent
      thread id in its events */
   if (current_thread)
@@ -466,7 +448,7 @@ static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
    is zero return the first loaded module (which is always the name of the
    executable).  */
 static int
-get_module_name (DWORD base_address, char *dll_name_ret)
+get_module_name (LPVOID base_address, char *dll_name_ret)
 {
   DWORD len;
   MODULEINFO mi;
@@ -509,7 +491,7 @@ get_module_name (DWORD base_address, char *dll_name_ret)
                                       &mi, sizeof (mi)))
        error (_("Can't get module info"));
 
-      if (!base_address || (DWORD) (mi.lpBaseOfDll) == base_address)
+      if (!base_address || mi.lpBaseOfDll == base_address)
        {
          /* Try to find the name of the given module */
          len = psapi_GetModuleFileNameExA (current_process_handle,
@@ -545,7 +527,7 @@ struct safe_symbol_file_add_args
 /* Maintain a linked list of "so" information. */
 struct lm_info
 {
-  DWORD load_addr;
+  LPVOID load_addr;
 };
 
 static struct so_list solib_start, *solib_end;
@@ -556,8 +538,6 @@ static int
 safe_symbol_file_add_stub (void *argv)
 {
 #define p ((struct safe_symbol_file_add_args *) argv)
-  struct so_list *so = &solib_start;
-
   p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
   return !!p->ret;
 #undef p
@@ -606,7 +586,7 @@ safe_symbol_file_add (char *name, int from_tty,
 }
 
 static struct so_list *
-win32_make_so (const char *name, DWORD load_addr)
+win32_make_so (const char *name, LPVOID load_addr)
 {
   struct so_list *so;
   char buf[MAX_PATH + 1];
@@ -689,7 +669,7 @@ get_image_name (HANDLE h, void *address, int unicode)
   char *address_ptr;
   int len = 0;
   char b[2];
-  DWORD done;
+  SIZE_T done;
 
   /* Attempt to read the name of the dll that was detected.
      This is documented to work only when actively debugging
@@ -733,7 +713,7 @@ handle_load_dll (void *dummy)
 
   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
 
-  if (!get_module_name ((DWORD) event->lpBaseOfDll, dll_buf))
+  if (!get_module_name (event->lpBaseOfDll, dll_buf))
     dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
 
   dll_name = dll_buf;
@@ -744,9 +724,12 @@ handle_load_dll (void *dummy)
   if (!dll_name)
     return 1;
 
-  solib_end->next = win32_make_so (dll_name, (DWORD) event->lpBaseOfDll);
+  solib_end->next = win32_make_so (dll_name, event->lpBaseOfDll);
   solib_end = solib_end->next;
 
+  DEBUG_EVENTS (("gdb: Loading dll \"%s\" at 0x%lx.\n", solib_end->so_name,
+                solib_end->lm_info->load_addr));
+
   return 1;
 }
 
@@ -761,7 +744,7 @@ win32_free_so (struct so_list *so)
 static int
 handle_unload_dll (void *dummy)
 {
-  DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll;
+  LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
   struct so_list *so;
 
   for (so = &solib_start; so->next != NULL; so = so->next)
@@ -771,6 +754,8 @@ handle_unload_dll (void *dummy)
        so->next = sodel->next;
        if (!so->next)
          solib_end = so;
+       DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
+
        win32_free_so (sodel);
        solib_add (NULL, 0, NULL, auto_solib_add);
        return 1;
@@ -989,7 +974,7 @@ info_w32_command (char *args, int from_tty)
 
 #define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
   printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
-  (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
+          current_event.u.Exception.ExceptionRecord.ExceptionAddress)
 
 static int
 handle_exception (struct target_waitstatus *ourstatus)
@@ -1103,7 +1088,7 @@ handle_exception (struct target_waitstatus *ourstatus)
        return -1;
       printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
                    current_event.u.Exception.ExceptionRecord.ExceptionCode,
-       (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
+               current_event.u.Exception.ExceptionRecord.ExceptionAddress);
       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
       break;
     }
@@ -1174,7 +1159,8 @@ fake_create_process (void)
       /*  We can not debug anything in that case.  */
     }
   main_thread_id = current_event.dwThreadId;
-  current_thread = win32_add_thread (main_thread_id,
+  current_thread = win32_add_thread (ptid_build (current_event.dwProcessId, 0,
+                                                current_event.dwThreadId),
                                     current_event.u.CreateThread.hThread);
   return main_thread_id;
 }
@@ -1185,7 +1171,13 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig)
   thread_info *th;
   DWORD continue_status = DBG_CONTINUE;
 
-  int pid = PIDGET (ptid);
+  /* A specific PTID means `step only this thread id'.  */
+  int resume_all = ptid_equal (ptid, minus_one_ptid);
+
+  /* If we're continuing all threads, it's the current inferior that
+     should be handled specially.  */
+  if (resume_all)
+    ptid = inferior_ptid;
 
   if (sig != TARGET_SIGNAL_0)
     {
@@ -1223,11 +1215,11 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig)
 
   last_sig = TARGET_SIGNAL_0;
 
-  DEBUG_EXEC (("gdb: win32_resume (pid=%d, step=%d, sig=%d);\n",
-              pid, step, sig));
+  DEBUG_EXEC (("gdb: win32_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
+              ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
 
   /* Get context for currently selected thread */
-  th = thread_rec (PIDGET (inferior_ptid), FALSE);
+  th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
   if (th)
     {
       if (step)
@@ -1257,7 +1249,10 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig)
   /* Allow continuing with the same signal that interrupted us.
      Otherwise complain. */
 
-  win32_continue (continue_status, pid);
+  if (resume_all)
+    win32_continue (continue_status, -1);
+  else
+    win32_continue (continue_status, ptid_get_tid (ptid));
 }
 
 /* Get the next event from the child.  Return 1 if the event requires
@@ -1271,7 +1266,6 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
   thread_info *th;
   static thread_info dummy_thread_info;
   int retval = 0;
-  ptid_t ptid = {-1};
 
   last_sig = TARGET_SIGNAL_0;
 
@@ -1295,21 +1289,24 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
                     "CREATE_THREAD_DEBUG_EVENT"));
       if (saw_create != 1)
        {
-         if (!saw_create && attach_flag)
+         struct inferior *inf;
+         inf = find_inferior_pid (current_event.dwProcessId);
+         if (!saw_create && inf->attach_flag)
            {
              /* Kludge around a Windows bug where first event is a create
                 thread event.  Caused when attached process does not have
                 a main thread. */
-             retval = ourstatus->value.related_pid = fake_create_process ();
-            if (retval)
-              saw_create++;
+             retval = fake_create_process ();
+             if (retval)
+               saw_create++;
            }
          break;
        }
       /* Record the existence of this thread */
-      th = win32_add_thread (current_event.dwThreadId,
-                            current_event.u.CreateThread.hThread);
       retval = current_event.dwThreadId;
+      th = win32_add_thread (ptid_build (current_event.dwProcessId, 0,
+                                        current_event.dwThreadId),
+                            current_event.u.CreateThread.hThread);
       break;
 
     case EXIT_THREAD_DEBUG_EVENT:
@@ -1319,7 +1316,8 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
                     "EXIT_THREAD_DEBUG_EVENT"));
       if (current_event.dwThreadId != main_thread_id)
        {
-         win32_delete_thread (current_event.dwThreadId);
+         win32_delete_thread (ptid_build (current_event.dwProcessId, 0,
+                                          current_event.dwThreadId));
          th = &dummy_thread_info;
        }
       break;
@@ -1335,12 +1333,14 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
 
       current_process_handle = current_event.u.CreateProcessInfo.hProcess;
       if (main_thread_id)
-       win32_delete_thread (main_thread_id);
+       win32_delete_thread (ptid_build (current_event.dwProcessId, 0,
+                                        main_thread_id));
       main_thread_id = current_event.dwThreadId;
       /* Add the main thread */
-      th = win32_add_thread (main_thread_id,
+      th = win32_add_thread (ptid_build (current_event.dwProcessId, 0,
+                                        current_event.dwThreadId),
                             current_event.u.CreateProcessInfo.hThread);
-      retval = ourstatus->value.related_pid = current_event.dwThreadId;
+      retval = current_event.dwThreadId;
       break;
 
     case EXIT_PROCESS_DEBUG_EVENT:
@@ -1428,13 +1428,14 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
   if (!retval || saw_create != 1)
     {
       if (continue_status == -1)
-       win32_resume (ptid, 0, 1);
+       win32_resume (minus_one_ptid, 0, 1);
       else
        CHECK (win32_continue (continue_status, -1));
     }
   else
     {
-      inferior_ptid = pid_to_ptid (retval);
+      inferior_ptid = ptid_build (current_event.dwProcessId, 0,
+                                 retval);
       current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
     }
 
@@ -1442,11 +1443,11 @@ out:
   return retval;
 }
 
-/* Wait for interesting events to occur in the target process. */
+/* Wait for interesting events to occur in the target process.  */
 static ptid_t
 win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 {
-  int pid = PIDGET (ptid);
+  int pid = -1;
 
   target_terminal_ours ();
 
@@ -1478,7 +1479,7 @@ win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
       SetConsoleCtrlHandler (NULL, FALSE);
 
       if (retval)
-       return pid_to_ptid (retval);
+       return ptid_build (current_event.dwProcessId, 0, retval);
       else
        {
          int detach = 0;
@@ -1493,10 +1494,12 @@ win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 }
 
 static void
-do_initial_win32_stuff (DWORD pid)
+do_initial_win32_stuff (struct target_ops *ops, DWORD pid, int attaching)
 {
   extern int stop_after_trap;
   int i;
+  struct inferior *inf;
+  struct thread_info *tp;
 
   last_sig = TARGET_SIGNAL_0;
   event_count = 0;
@@ -1511,24 +1514,37 @@ do_initial_win32_stuff (DWORD pid)
 #endif
   current_event.dwProcessId = pid;
   memset (&current_event, 0, sizeof (current_event));
-  push_target (&win32_ops);
+  push_target (ops);
   disable_breakpoints_in_shlibs ();
   win32_clear_solib ();
   clear_proceed_status ();
   init_wait_for_inferior ();
 
+  inf = add_inferior (pid);
+  inf->attach_flag = attaching;
+
+  /* Make the new process the current inferior, so terminal handling
+     can rely on it.  When attaching, we don't know about any thread
+     id here, but that's OK --- nothing should be referencing the
+     current thread until we report an event out of win32_wait.  */
+  inferior_ptid = pid_to_ptid (pid);
+
   terminal_init_inferior_with_pgrp (pid);
   target_terminal_inferior ();
 
+  inf->stop_soon = STOP_QUIETLY;
   while (1)
     {
       stop_after_trap = 1;
       wait_for_inferior (0);
-      if (stop_signal != TARGET_SIGNAL_TRAP)
-       resume (0, stop_signal);
+      tp = inferior_thread ();
+      if (tp->stop_signal != TARGET_SIGNAL_TRAP)
+       resume (0, tp->stop_signal);
       else
        break;
     }
+
+  inf->stop_soon = NO_STOP_QUIETLY;
   stop_after_trap = 0;
   return;
 }
@@ -1538,8 +1554,8 @@ do_initial_win32_stuff (DWORD pid)
    If loading these functions succeeds use them to actually detach from
    the inferior process, otherwise behave as usual, pretending that
    detach has worked. */
-static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
-static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
+static BOOL WINAPI (*kernel32_DebugSetProcessKillOnExit)(BOOL);
+static BOOL WINAPI (*kernel32_DebugActiveProcessStop)(DWORD);
 
 static int
 has_detach_ability (void)
@@ -1550,13 +1566,14 @@ has_detach_ability (void)
     kernel32 = LoadLibrary ("kernel32.dll");
   if (kernel32)
     {
-      if (!DebugSetProcessKillOnExit)
-       DebugSetProcessKillOnExit = GetProcAddress (kernel32,
-                                                "DebugSetProcessKillOnExit");
-      if (!DebugActiveProcessStop)
-       DebugActiveProcessStop = GetProcAddress (kernel32,
-                                                "DebugActiveProcessStop");
-      if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
+      if (!kernel32_DebugSetProcessKillOnExit)
+       kernel32_DebugSetProcessKillOnExit =
+         (void *) GetProcAddress (kernel32, "DebugSetProcessKillOnExit");
+      if (!kernel32_DebugActiveProcessStop)
+       kernel32_DebugActiveProcessStop =
+         (void *) GetProcAddress (kernel32, "DebugActiveProcessStop");
+      if (kernel32_DebugSetProcessKillOnExit
+         && kernel32_DebugActiveProcessStop)
        return 1;
     }
   return 0;
@@ -1591,13 +1608,14 @@ set_process_privilege (const char *privilege, BOOL enable)
       if (!(advapi32 = LoadLibrary ("advapi32.dll")))
        goto out;
       if (!OpenProcessToken)
-       OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
+       OpenProcessToken =
+          (void *) GetProcAddress (advapi32, "OpenProcessToken");
       if (!LookupPrivilegeValue)
-       LookupPrivilegeValue = GetProcAddress (advapi32,
-                                              "LookupPrivilegeValueA");
+       LookupPrivilegeValue =
+          (void *) GetProcAddress (advapi32, "LookupPrivilegeValueA");
       if (!AdjustTokenPrivileges)
-       AdjustTokenPrivileges = GetProcAddress (advapi32,
-                                               "AdjustTokenPrivileges");
+       AdjustTokenPrivileges =
+          (void *) GetProcAddress (advapi32, "AdjustTokenPrivileges");
       if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
        {
          advapi32 = NULL;
@@ -1641,7 +1659,7 @@ out:
 
 /* Attach to process PID, then initialize for debugging it.  */
 static void
-win32_attach (char *args, int from_tty)
+win32_attach (struct target_ops *ops, char *args, int from_tty)
 {
   BOOL ok;
   DWORD pid;
@@ -1676,9 +1694,7 @@ win32_attach (char *args, int from_tty)
     error (_("Can't attach to process."));
 
   if (has_detach_ability ())
-    DebugSetProcessKillOnExit (FALSE);
-
-  attach_flag = 1;
+    kernel32_DebugSetProcessKillOnExit (FALSE);
 
   if (from_tty)
     {
@@ -1694,12 +1710,12 @@ win32_attach (char *args, int from_tty)
       gdb_flush (gdb_stdout);
     }
 
-  do_initial_win32_stuff (pid);
+  do_initial_win32_stuff (ops, pid, 1);
   target_terminal_ours ();
 }
 
 static void
-win32_detach (char *args, int from_tty)
+win32_detach (struct target_ops *ops, char *args, int from_tty)
 {
   int detached = 1;
 
@@ -1708,13 +1724,13 @@ win32_detach (char *args, int from_tty)
       ptid_t ptid = {-1};
       win32_resume (ptid, 0, TARGET_SIGNAL_0);
 
-      if (!DebugActiveProcessStop (current_event.dwProcessId))
+      if (!kernel32_DebugActiveProcessStop (current_event.dwProcessId))
        {
          error (_("Can't detach process %lu (error %lu)"),
                 current_event.dwProcessId, GetLastError ());
          detached = 0;
        }
-      DebugSetProcessKillOnExit (FALSE);
+      kernel32_DebugSetProcessKillOnExit (FALSE);
     }
   if (detached && from_tty)
     {
@@ -1725,8 +1741,11 @@ win32_detach (char *args, int from_tty)
                         current_event.dwProcessId);
       gdb_flush (gdb_stdout);
     }
+
   inferior_ptid = null_ptid;
-  unpush_target (&win32_ops);
+  detach_inferior (current_event.dwProcessId);
+
+  unpush_target (ops);
 }
 
 static char *
@@ -1738,7 +1757,7 @@ win32_pid_to_exec_file (int pid)
   /* Try to find exe name as symlink target of /proc/<pid>/exe */
   int nchars;
   char procexe[sizeof ("/proc/4294967295/exe")];
-  sprintf (procexe, "/proc/%lu/exe", current_event.dwProcessId);
+  sprintf (procexe, "/proc/%u/exe", pid);
   nchars = readlink (procexe, path, sizeof(path));
   if (nchars > 0 && nchars < sizeof (path))
     {
@@ -1760,8 +1779,11 @@ win32_pid_to_exec_file (int pid)
 static void
 win32_files_info (struct target_ops *ignore)
 {
+  struct inferior *inf = current_inferior ();
+
   printf_unfiltered ("\tUsing the running image of %s %s.\n",
-      attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
+                    inf->attach_flag ? "attached" : "child",
+                    target_pid_to_str (inferior_ptid));
 }
 
 static void
@@ -1776,8 +1798,8 @@ win32_open (char *arg, int from_tty)
    ENV is the environment vector to pass.  Errors reported with error().  */
 
 static void
-win32_create_inferior (char *exec_file, char *allargs, char **in_env,
-                      int from_tty)
+win32_create_inferior (struct target_ops *ops, char *exec_file,
+                      char *allargs, char **in_env, int from_tty)
 {
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
@@ -1830,8 +1852,6 @@ win32_create_inferior (char *exec_file, char *allargs, char **in_env,
   if (new_console)
     flags |= CREATE_NEW_CONSOLE;
 
-  attach_flag = 0;
-
   args = alloca (strlen (toexec) + strlen (allargs) + 2);
   strcpy (args, toexec);
   strcat (args, " ");
@@ -1900,13 +1920,13 @@ win32_create_inferior (char *exec_file, char *allargs, char **in_env,
   else
     saw_create = 0;
 
-  do_initial_win32_stuff (pi.dwProcessId);
+  do_initial_win32_stuff (ops, pi.dwProcessId, 0);
 
   /* win32_continue (DBG_CONTINUE, -1); */
 }
 
 static void
-win32_mourn_inferior (void)
+win32_mourn_inferior (struct target_ops *ops)
 {
   (void) win32_continue (DBG_CONTINUE, -1);
   i386_cleanup_dregs();
@@ -1915,7 +1935,7 @@ win32_mourn_inferior (void)
       CHECK (CloseHandle (current_process_handle));
       open_process_used = 0;
     }
-  unpush_target (&win32_ops);
+  unpush_target (ops);
   generic_mourn_inferior ();
 }
 
@@ -1923,7 +1943,7 @@ win32_mourn_inferior (void)
    ^C on the controlling terminal. */
 
 static void
-win32_stop (void)
+win32_stop (ptid_t ptid)
 {
   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
@@ -1935,7 +1955,7 @@ win32_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
                   int write, struct mem_attrib *mem,
                   struct target_ops *target)
 {
-  DWORD done = 0;
+  SIZE_T done = 0;
   if (write)
     {
       DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
@@ -2001,13 +2021,15 @@ static char *
 win32_pid_to_str (ptid_t ptid)
 {
   static char buf[80];
-  int pid = PIDGET (ptid);
 
-  if ((DWORD) pid == current_event.dwProcessId)
-    sprintf (buf, "process %d", pid);
-  else
-    sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
-  return buf;
+  if (ptid_get_tid (ptid) != 0)
+    {
+      snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
+               ptid_get_pid (ptid), ptid_get_tid (ptid));
+      return buf;
+    }
+
+  return normal_pid_to_str (ptid);
 }
 
 static LONGEST
@@ -2027,7 +2049,8 @@ win32_xfer_shared_libraries (struct target_ops *ops,
   obstack_init (&obstack);
   obstack_grow_str (&obstack, "<library-list>\n");
   for (so = solib_start.next; so; so = so->next)
-    win32_xfer_shared_library (so->so_name, so->lm_info->load_addr, &obstack);
+    win32_xfer_shared_library (so->so_name, (CORE_ADDR) so->lm_info->load_addr,
+                               &obstack);
   obstack_grow_str0 (&obstack, "</library-list>\n");
 
   buf = obstack_finish (&obstack);
@@ -2080,6 +2103,7 @@ init_win32_ops (void)
   win32_ops.to_open = win32_open;
   win32_ops.to_close = win32_close;
   win32_ops.to_attach = win32_attach;
+  win32_ops.to_attach_no_wait = 1;
   win32_ops.to_detach = win32_detach;
   win32_ops.to_resume = win32_resume;
   win32_ops.to_wait = win32_wait;
@@ -2110,8 +2134,8 @@ init_win32_ops (void)
   win32_ops.to_has_stack = 1;
   win32_ops.to_has_registers = 1;
   win32_ops.to_has_execution = 1;
-  win32_ops.to_magic = OPS_MAGIC;
   win32_ops.to_pid_to_exec_file = win32_pid_to_exec_file;
+  win32_ops.to_magic = OPS_MAGIC;
 }
 
 static void
@@ -2239,15 +2263,18 @@ cygwin_get_dr6 (void)
   return dr[6];
 }
 
-/* Determine if the thread referenced by "pid" is alive
+/* Determine if the thread referenced by "ptid" is alive
    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
-   it means that the pid has died.  Otherwise it is assumed to be alive. */
+   it means that the thread has died.  Otherwise it is assumed to be alive. */
 static int
 win32_win32_thread_alive (ptid_t ptid)
 {
-  int pid = PIDGET (ptid);
+  int tid;
+
+  gdb_assert (ptid_get_tid (ptid) != 0);
+  tid = ptid_get_tid (ptid);
 
-  return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
+  return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
     FALSE : TRUE;
 }
 
This page took 0.035535 seconds and 4 git commands to generate.