*** empty log message ***
[binutils-gdb.git] / gdb / windows-nat.c
index e84214d31bf98dc0c2e580e59db5fc08a0261cb3..66ebdd66194feaf0060669799d1aaa3ee4ea5dc9 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.
 
@@ -85,6 +85,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
 
@@ -475,7 +481,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;
@@ -518,7 +524,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,
@@ -554,7 +560,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;
@@ -613,7 +619,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];
@@ -696,7 +702,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
@@ -740,7 +746,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;
@@ -751,11 +757,11 @@ 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,
-                (DWORD) solib_end->lm_info->load_addr));
+                solib_end->lm_info->load_addr));
 
   return 1;
 }
@@ -771,7 +777,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)
@@ -1001,7 +1007,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)
@@ -1115,7 +1121,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;
     }
@@ -1316,14 +1322,16 @@ 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 = fake_create_process ();
-            if (retval)
-              saw_create++;
+             if (retval)
+               saw_create++;
            }
          break;
        }
@@ -1519,10 +1527,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;
@@ -1537,27 +1547,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 ();
 
-  stop_soon = STOP_QUIETLY;
+  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;
     }
 
-  stop_soon = NO_STOP_QUIETLY;
+  inf->stop_soon = NO_STOP_QUIETLY;
   stop_after_trap = 0;
   return;
 }
@@ -1567,8 +1587,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)
@@ -1579,13 +1599,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;
@@ -1620,13 +1641,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;
@@ -1670,7 +1692,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;
@@ -1705,9 +1727,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)
     {
@@ -1723,12 +1743,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;
 
@@ -1737,13 +1757,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)
     {
@@ -1754,8 +1774,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 *
@@ -1789,8 +1812,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
@@ -1805,8 +1831,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;
@@ -1859,8 +1885,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, " ");
@@ -1929,13 +1953,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();
@@ -1944,7 +1968,7 @@ win32_mourn_inferior (void)
       CHECK (CloseHandle (current_process_handle));
       open_process_used = 0;
     }
-  unpush_target (&win32_ops);
+  unpush_target (ops);
   generic_mourn_inferior ();
 }
 
@@ -1964,7 +1988,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",
@@ -2058,7 +2082,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);