* remote-fileio.c (remote_fileio_func_rename): Use Cygwin 1.7
[binutils-gdb.git] / gdb / windows-nat.c
index ffd2222e7ef80639c4f2ac06b4c2d02d05e01de1..2a679e4b047c5ac239e2cf01ff56d3667529d7d8 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-vector operations for controlling windows child processes, for GDB.
 
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
    Contributed by Cygnus Solutions, A Red Hat Company.
 
 
 #include "windows-tdep.h"
 #include "windows-nat.h"
+#include "i386-nat.h"
+#include "complaints.h"
 
+#define AdjustTokenPrivileges          dyn_AdjustTokenPrivileges
 #define DebugActiveProcessStop         dyn_DebugActiveProcessStop
 #define DebugBreakProcess              dyn_DebugBreakProcess
 #define DebugSetProcessKillOnExit      dyn_DebugSetProcessKillOnExit
 #define EnumProcessModules             dyn_EnumProcessModules
+#ifndef __CYGWIN__
 #define GetModuleFileNameExA           dyn_GetModuleFileNameExA
+#else
+#define GetModuleFileNameExW           dyn_GetModuleFileNameExW
+#endif
 #define GetModuleInformation           dyn_GetModuleInformation
+#define LookupPrivilegeValueA          dyn_LookupPrivilegeValueA
+#define OpenProcessToken               dyn_OpenProcessToken
 
-/* Since Windows XP, detaching from a process is supported by Windows.
-   The following code tries loading the appropriate functions dynamically.
-   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 (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
+                                           DWORD, PTOKEN_PRIVILEGES, PDWORD);
 static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
 static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
 static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
 static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
                                          LPDWORD);
+#ifndef __CYGWIN__
 static DWORD WINAPI (*GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
                                            DWORD);
+#else
+static DWORD WINAPI (*GetModuleFileNameExW) (HANDLE, HMODULE, LPWSTR,
+                                           DWORD);
+#endif
 static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
                                            DWORD);
+static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
+static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
 
 static struct target_ops windows_ops;
 
@@ -120,6 +133,8 @@ enum
 static uintptr_t dr[8];
 static int debug_registers_changed;
 static int debug_registers_used;
+
+static int windows_initialization_done;
 #define DR6_CLEAR_VALUE 0xffff0ff0
 
 /* The string sent by cygwin when it processes a signal.
@@ -138,6 +153,10 @@ static void windows_stop (ptid_t);
 static int windows_thread_alive (struct target_ops *, ptid_t);
 static void windows_kill_inferior (struct target_ops *);
 
+static void cygwin_set_dr (int i, CORE_ADDR addr);
+static void cygwin_set_dr7 (unsigned long val);
+static unsigned long cygwin_get_dr6 (void);
+
 static enum target_signal last_sig = TARGET_SIGNAL_0;
 /* Set if a signal was received from the debugged process */
 
@@ -473,10 +492,10 @@ get_module_name (LPVOID base_address, char *dll_name_ret)
   HMODULE *DllHandle = dh_buf; /* Set to temporary storage for initial query */
   DWORD cbNeeded;
 #ifdef __CYGWIN__
-  char pathbuf[PATH_MAX + 1];  /* Temporary storage prior to converting to
-                                  posix form */
-#else
-  char *pathbuf = dll_name_ret;        /* Just copy directly to passed-in arg */
+  wchar_t pathbuf[PATH_MAX];   /* Temporary storage prior to converting to
+                                  posix form.  PATH_MAX is always enough
+                                  as long as SO_NAME_MAX_PATH_SIZE is defined
+                                  as 512. */
 #endif
 
   cbNeeded = 0;
@@ -505,13 +524,20 @@ get_module_name (LPVOID base_address, char *dll_name_ret)
       if (!base_address || mi.lpBaseOfDll == base_address)
        {
          /* Try to find the name of the given module */
+#ifdef __CYGWIN__
+         /* Cygwin prefers that the path be in /x/y/z format */
+         len = GetModuleFileNameExW (current_process_handle,
+                                     DllHandle[i], pathbuf, PATH_MAX);
+         if (len == 0)
+           error (_("Error getting dll name: %lu."), GetLastError ());
+         if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret,
+                               PATH_MAX) < 0)
+           error (_("Error converting dll name to POSIX: %d."), errno);
+#else
          len = GetModuleFileNameExA (current_process_handle,
-                                     DllHandle[i], pathbuf, MAX_PATH);
+                                     DllHandle[i], dll_name_ret, MAX_PATH);
          if (len == 0)
            error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
-#ifdef __CYGWIN__
-         /* Cygwin prefers that the path be in /x/y/z format */
-         cygwin_conv_to_full_posix_path (pathbuf, dll_name_ret);
 #endif
          return 1;     /* success */
        }
@@ -549,7 +575,9 @@ static int
 safe_symbol_file_add_stub (void *argv)
 {
 #define p ((struct safe_symbol_file_add_args *) argv)
-  p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
+  const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0)
+                         | (p->mainline ? SYMFILE_MAINLINE : 0));
+  p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags);
   return !!p->ret;
 #undef p
 }
@@ -600,12 +628,12 @@ static struct so_list *
 windows_make_so (const char *name, LPVOID load_addr)
 {
   struct so_list *so;
+  char *p;
+#ifndef __CYGWIN__
   char buf[MAX_PATH + 1];
   char cwd[MAX_PATH + 1];
-  char *p;
   WIN32_FIND_DATA w32_fd;
   HANDLE h = FindFirstFile(name, &w32_fd);
-  MEMORY_BASIC_INFORMATION m;
 
   if (h == INVALID_HANDLE_VALUE)
     strcpy (buf, name);
@@ -623,12 +651,24 @@ windows_make_so (const char *name, LPVOID load_addr)
          SetCurrentDirectory (cwd);
        }
     }
-
   if (strcasecmp (buf, "ntdll.dll") == 0)
     {
       GetSystemDirectory (buf, sizeof (buf));
       strcat (buf, "\\ntdll.dll");
     }
+#else
+  wchar_t buf[PATH_MAX];
+
+  buf[0] = L'\0';
+  if (access (name, F_OK) != 0)
+    {
+      if (strcasecmp (name, "ntdll.dll") == 0)
+       {
+         GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
+         wcscat (buf, L"\\ntdll.dll");
+       }
+    }
+#endif
   so = XZALLOC (struct so_list);
   so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
   so->lm_info->load_addr = load_addr;
@@ -636,7 +676,20 @@ windows_make_so (const char *name, LPVOID load_addr)
 #ifndef __CYGWIN__
   strcpy (so->so_name, buf);
 #else
-  cygwin_conv_to_posix_path (buf, so->so_name);
+  if (buf[0])
+    cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
+                     SO_NAME_MAX_PATH_SIZE);
+  else
+    {
+      char *rname = canonicalize_file_name (name);
+      if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
+       {
+         strcpy (so->so_name, rname);
+         free (rname);
+       }
+      else
+       error (_("dll path too long"));
+    }
   /* Record cygwin1.dll .text start/end.  */
   p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
   if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
@@ -675,7 +728,11 @@ windows_make_so (const char *name, LPVOID load_addr)
 static char *
 get_image_name (HANDLE h, void *address, int unicode)
 {
+#ifdef __CYGWIN__
+  static char buf[PATH_MAX];
+#else
   static char buf[(2 * MAX_PATH) + 1];
+#endif
   DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
   char *address_ptr;
   int len = 0;
@@ -706,8 +763,12 @@ get_image_name (HANDLE h, void *address, int unicode)
       WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
       ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
                         &done);
-
-      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
+#ifdef __CYGWIN__
+      wcstombs (buf, unicode_address, PATH_MAX);
+#else
+      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
+                          0, 0);
+#endif
     }
 
   return buf;
@@ -719,7 +780,11 @@ static int
 handle_load_dll (void *dummy)
 {
   LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
+#ifdef __CYGWIN__
+  char dll_buf[PATH_MAX];
+#else
   char dll_buf[MAX_PATH + 1];
+#endif
   char *dll_name = NULL;
 
   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
@@ -738,8 +803,8 @@ handle_load_dll (void *dummy)
   solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
   solib_end = solib_end->next;
 
-  DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %p.\n", solib_end->so_name,
-                solib_end->lm_info->load_addr));
+  DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
+                host_address_to_string (solib_end->lm_info->load_addr)));
 
   return 1;
 }
@@ -772,7 +837,15 @@ handle_unload_dll (void *dummy)
        return 1;
       }
 
-  error (_("Error: dll starting at %p not found."), lpBaseOfDll);
+  /* We did not find any DLL that was previously loaded at this address,
+     so register a complaint.  We do not report an error, because we have
+     observed that this may be happening under some circumstances.  For
+     instance, running 32bit applications on x64 Windows causes us to receive
+     4 mysterious UNLOAD_DLL_DEBUG_EVENTs during the startup phase (these
+     events are apparently caused by the WOW layer, the interface between
+     32bit and 64bit worlds).  */
+  complaint (&symfile_complaints, _("dll starting at %s not found."),
+            host_address_to_string (lpBaseOfDll));
 
   return 0;
 }
@@ -984,8 +1057,9 @@ info_w32_command (char *args, int from_tty)
 
 
 #define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
-  printf_unfiltered ("gdb: Target exception %s at %p\n", x, \
-                    current_event.u.Exception.ExceptionRecord.ExceptionAddress)
+  printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
+    host_address_to_string (\
+      current_event.u.Exception.ExceptionRecord.ExceptionAddress))
 
 static int
 handle_exception (struct target_waitstatus *ourstatus)
@@ -1096,9 +1170,10 @@ handle_exception (struct target_waitstatus *ourstatus)
       /* Treat unhandled first chance exceptions specially. */
       if (current_event.u.Exception.dwFirstChance)
        return -1;
-      printf_unfiltered ("gdb: unknown target exception 0x%08lx at %p\n",
-                   current_event.u.Exception.ExceptionRecord.ExceptionCode,
-                   current_event.u.Exception.ExceptionRecord.ExceptionAddress);
+      printf_unfiltered ("gdb: unknown target exception 0x%08lx at %s\n",
+       current_event.u.Exception.ExceptionRecord.ExceptionCode,
+       host_address_to_string (
+         current_event.u.Exception.ExceptionRecord.ExceptionAddress));
       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
       break;
     }
@@ -1116,7 +1191,7 @@ windows_continue (DWORD continue_status, int id)
   thread_info *th;
   BOOL res;
 
-  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
+  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%lx, %s);\n",
                  current_event.dwProcessId, current_event.dwThreadId,
                  continue_status == DBG_CONTINUE ?
                  "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
@@ -1236,9 +1311,10 @@ windows_resume (struct target_ops *ops,
       if (step)
        {
          /* Single step by setting t bit */
-         windows_fetch_inferior_registers (ops,
-                                           get_current_regcache (),
-                                           gdbarch_ps_regnum (current_gdbarch));
+         struct regcache *regcache = get_current_regcache ();
+         struct gdbarch *gdbarch = get_regcache_arch (regcache);
+         windows_fetch_inferior_registers (ops, regcache,
+                                           gdbarch_ps_regnum (gdbarch));
          th->context.EFlags |= FLAG_TRACE_BIT;
        }
 
@@ -1276,8 +1352,8 @@ ctrl_c_handler (DWORD event_type)
 {
   const int attach_flag = current_inferior ()->attach_flag;
 
-  /* Only handle Ctrl-C event.  Ignore others.  */
-  if (event_type != CTRL_C_EVENT)
+  /* Only handle Ctrl-C and Ctrl-Break events.  Ignore others.  */
+  if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
     return FALSE;
 
   /* If the inferior and the debugger share the same console, do nothing as
@@ -1348,7 +1424,7 @@ get_windows_debug_event (struct target_ops *ops,
       break;
 
     case EXIT_THREAD_DEBUG_EVENT:
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "EXIT_THREAD_DEBUG_EVENT"));
@@ -1361,7 +1437,7 @@ get_windows_debug_event (struct target_ops *ops,
       break;
 
     case CREATE_PROCESS_DEBUG_EVENT:
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "CREATE_PROCESS_DEBUG_EVENT"));
@@ -1382,19 +1458,27 @@ get_windows_debug_event (struct target_ops *ops,
       break;
 
     case EXIT_PROCESS_DEBUG_EVENT:
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "EXIT_PROCESS_DEBUG_EVENT"));
-      if (saw_create != 1)
-       break;
-      ourstatus->kind = TARGET_WAITKIND_EXITED;
-      ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
-      retval = main_thread_id;
+      if (!windows_initialization_done)
+       {
+         target_terminal_ours ();
+         target_mourn_inferior ();
+         error (_("During startup program exited with code 0x%x."),
+                (unsigned int) current_event.u.ExitProcess.dwExitCode);
+       }
+      else if (saw_create == 1)
+       {
+         ourstatus->kind = TARGET_WAITKIND_EXITED;
+         ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
+         retval = main_thread_id;
+       }
       break;
 
     case LOAD_DLL_DEBUG_EVENT:
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "LOAD_DLL_DEBUG_EVENT"));
@@ -1408,7 +1492,7 @@ get_windows_debug_event (struct target_ops *ops,
       break;
 
     case UNLOAD_DLL_DEBUG_EVENT:
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "UNLOAD_DLL_DEBUG_EVENT"));
@@ -1421,7 +1505,7 @@ get_windows_debug_event (struct target_ops *ops,
       break;
 
     case EXCEPTION_DEBUG_EVENT:
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "EXCEPTION_DEBUG_EVENT"));
@@ -1443,7 +1527,7 @@ get_windows_debug_event (struct target_ops *ops,
       break;
 
     case OUTPUT_DEBUG_STRING_EVENT:    /* message from the kernel */
-      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
                     (unsigned) current_event.dwProcessId,
                     (unsigned) current_event.dwThreadId,
                     "OUTPUT_DEBUG_STRING_EVENT"));
@@ -1484,7 +1568,7 @@ out:
 /* Wait for interesting events to occur in the target process.  */
 static ptid_t
 windows_wait (struct target_ops *ops,
-             ptid_t ptid, struct target_waitstatus *ourstatus)
+             ptid_t ptid, struct target_waitstatus *ourstatus, int options)
 {
   int pid = -1;
 
@@ -1572,7 +1656,8 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
   clear_proceed_status ();
   init_wait_for_inferior ();
 
-  inf = add_inferior (pid);
+  inf = current_inferior ();
+  inferior_appeared (inf, pid);
   inf->attach_flag = attaching;
 
   /* Make the new process the current inferior, so terminal handling
@@ -1584,6 +1669,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
   terminal_init_inferior_with_pgrp (pid);
   target_terminal_inferior ();
 
+  windows_initialization_done = 0;
   inf->stop_soon = STOP_QUIETLY;
   while (1)
     {
@@ -1596,6 +1682,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
        break;
     }
 
+  windows_initialization_done = 1;
   inf->stop_soon = NO_STOP_QUIETLY;
   stop_after_trap = 0;
   return;
@@ -1610,47 +1697,18 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
 static int
 set_process_privilege (const char *privilege, BOOL enable)
 {
-  static HMODULE advapi32 = NULL;
-  static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
-  static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
-  static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
-                                             DWORD, PTOKEN_PRIVILEGES, PDWORD);
-
   HANDLE token_hdl = NULL;
   LUID restore_priv;
   TOKEN_PRIVILEGES new_priv, orig_priv;
   int ret = -1;
   DWORD size;
 
-  if (GetVersion () >= 0x80000000)  /* No security availbale on 9x/Me */
-    return 0;
-
-  if (!advapi32)
-    {
-      if (!(advapi32 = LoadLibrary ("advapi32.dll")))
-       goto out;
-      if (!OpenProcessToken)
-       OpenProcessToken =
-         (void *) GetProcAddress (advapi32, "OpenProcessToken");
-      if (!LookupPrivilegeValue)
-       LookupPrivilegeValue =
-         (void *) GetProcAddress (advapi32, "LookupPrivilegeValueA");
-      if (!AdjustTokenPrivileges)
-       AdjustTokenPrivileges =
-         (void *) GetProcAddress (advapi32, "AdjustTokenPrivileges");
-      if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
-       {
-         advapi32 = NULL;
-         goto out;
-       }
-    }
-
   if (!OpenProcessToken (GetCurrentProcess (),
                         TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
                         &token_hdl))
     goto out;
 
-  if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
+  if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv))
     goto out;
 
   new_priv.PrivilegeCount = 1;
@@ -1686,8 +1744,7 @@ windows_attach (struct target_ops *ops, char *args, int from_tty)
   BOOL ok;
   DWORD pid;
 
-  if (!args)
-    error_no_arg (_("process-id to attach"));
+  pid = parse_pid_to_attach (args);
 
   if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
     {
@@ -1695,8 +1752,6 @@ windows_attach (struct target_ops *ops, char *args, int from_tty)
       printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
     }
 
-  pid = strtoul (args, 0, 0);          /* Windows pid */
-
   windows_init_thread_list ();
   ok = DebugActiveProcess (pid);
   saw_create = 0;
@@ -1770,9 +1825,9 @@ windows_detach (struct target_ops *ops, char *args, int from_tty)
 static char *
 windows_pid_to_exec_file (int pid)
 {
-  static char path[MAX_PATH + 1];
-
 #ifdef __CYGWIN__
+  static char path[PATH_MAX];
+
   /* Try to find exe name as symlink target of /proc/<pid>/exe */
   int nchars;
   char procexe[sizeof ("/proc/4294967295/exe")];
@@ -1783,6 +1838,8 @@ windows_pid_to_exec_file (int pid)
       path[nchars] = '\0';     /* Got it */
       return path;
     }
+#else
+  static char path[MAX_PATH + 1];
 #endif
 
   /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
@@ -1820,21 +1877,28 @@ static void
 windows_create_inferior (struct target_ops *ops, char *exec_file,
                       char *allargs, char **in_env, int from_tty)
 {
-  STARTUPINFO si;
-  PROCESS_INFORMATION pi;
-  BOOL ret;
-  DWORD flags;
-  char *args;
-  char real_path[MAXPATHLEN];
-  char *toexec;
-  char shell[MAX_PATH + 1]; /* Path to shell */
-  const char *sh;
 #ifdef __CYGWIN__
+  STARTUPINFOW si;
+  wchar_t real_path[PATH_MAX];
+  wchar_t shell[PATH_MAX]; /* Path to shell */
+  const char *sh;
+  wchar_t *toexec;
+  wchar_t *cygallargs;
+  wchar_t *args;
+  size_t len;
   int tty;
   int ostdin, ostdout, ostderr;
 #else
+  STARTUPINFOA si;
+  char real_path[PATH_MAX];
+  char shell[MAX_PATH + 1]; /* Path to shell */
+  char *toexec;
+  char *args;
   HANDLE tty;
 #endif
+  PROCESS_INFORMATION pi;
+  BOOL ret;
+  DWORD flags = 0;
   const char *inferior_io_terminal = get_inferior_io_terminal ();
 
   if (!exec_file)
@@ -1843,44 +1907,45 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
   memset (&si, 0, sizeof (si));
   si.cb = sizeof (si);
 
+  if (new_group)
+    flags |= CREATE_NEW_PROCESS_GROUP;
+
+  if (new_console)
+    flags |= CREATE_NEW_CONSOLE;
+
 #ifdef __CYGWIN__
   if (!useshell)
     {
-      flags = DEBUG_ONLY_THIS_PROCESS;
-      cygwin_conv_to_win32_path (exec_file, real_path);
+      flags |= DEBUG_ONLY_THIS_PROCESS;
+      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
+                           PATH_MAX * sizeof (wchar_t)) < 0)
+       error (_("Error starting executable: %d"), errno);
       toexec = real_path;
+      len = mbstowcs (NULL, allargs, 0) + 1;
+      if (len == (size_t) -1)
+       error (_("Error starting executable: %d"), errno);
+      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
+      mbstowcs (cygallargs, allargs, len);
     }
   else
     {
-      char *newallargs;
       sh = getenv ("SHELL");
       if (!sh)
        sh = "/bin/sh";
-      cygwin_conv_to_win32_path (sh, shell);
-      newallargs = alloca (sizeof (" -c 'exec  '") + strlen (exec_file)
-                          + strlen (allargs) + 2);
-      sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
-      allargs = newallargs;
+      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, PATH_MAX) < 0)
+       error (_("Error starting executable via shell: %d"), errno);
+      len = sizeof (L" -c 'exec  '") + mbstowcs (NULL, exec_file, 0)
+           + mbstowcs (NULL, allargs, 0) + 2;
+      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
+      swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
       toexec = shell;
-      flags = DEBUG_PROCESS;
+      flags |= DEBUG_PROCESS;
     }
-#else
-  toexec = exec_file;
-  flags = DEBUG_ONLY_THIS_PROCESS;
-#endif
-
-  if (new_group)
-    flags |= CREATE_NEW_PROCESS_GROUP;
-
-  if (new_console)
-    flags |= CREATE_NEW_CONSOLE;
-
-  args = alloca (strlen (toexec) + strlen (allargs) + 2);
-  strcpy (args, toexec);
-  strcat (args, " ");
-  strcat (args, allargs);
-
-#ifdef __CYGWIN__
+  args = (wchar_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
+                            * sizeof (wchar_t));
+  wcscpy (args, toexec);
+  wcscat (args, L" ");
+  wcscat (args, cygallargs);
   /* Prepare the environment vars for CreateProcess.  */
   cygwin_internal (CW_SYNC_WINENV);
 
@@ -1904,7 +1969,37 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
          dup2 (tty, 2);
        }
     }
+
+  windows_init_thread_list ();
+  ret = CreateProcessW (0,
+                       args,   /* command line */
+                       NULL,   /* Security */
+                       NULL,   /* thread */
+                       TRUE,   /* inherit handles */
+                       flags,  /* start flags */
+                       NULL,   /* environment */
+                       NULL,   /* current directory */
+                       &si,
+                       &pi);
+  if (tty >= 0)
+    {
+      close (tty);
+      dup2 (ostdin, 0);
+      dup2 (ostdout, 1);
+      dup2 (ostderr, 2);
+      close (ostdin);
+      close (ostdout);
+      close (ostderr);
+    }
 #else
+  args = alloca (strlen (toexec) + strlen (allargs) + 2);
+  strcpy (args, toexec);
+  strcat (args, " ");
+  strcat (args, allargs);
+
+  toexec = exec_file;
+  flags |= DEBUG_ONLY_THIS_PROCESS;
+
   if (!inferior_io_terminal)
     tty = INVALID_HANDLE_VALUE;
   else
@@ -1926,32 +2021,18 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
          si.dwFlags |= STARTF_USESTDHANDLES;
        }
     }
-#endif
 
   windows_init_thread_list ();
-  ret = CreateProcess (0,
-                      args,    /* command line */
-                      NULL,    /* Security */
-                      NULL,    /* thread */
-                      TRUE,    /* inherit handles */
-                      flags,   /* start flags */
-                      NULL,    /* environment */
-                      NULL,    /* current directory */
-                      &si,
-                      &pi);
-
-#ifdef __CYGWIN__
-  if (tty >= 0)
-    {
-      close (tty);
-      dup2 (ostdin, 0);
-      dup2 (ostdout, 1);
-      dup2 (ostderr, 2);
-      close (ostdin);
-      close (ostdout);
-      close (ostderr);
-    }
-#else
+  ret = CreateProcessA (0,
+                       args,   /* command line */
+                       NULL,   /* Security */
+                       NULL,   /* thread */
+                       TRUE,   /* inherit handles */
+                       flags,  /* start flags */
+                       NULL,   /* environment */
+                       NULL,   /* current directory */
+                       &si,
+                       &pi);
   if (tty != INVALID_HANDLE_VALUE)
     CloseHandle (tty);
 #endif
@@ -2098,7 +2179,7 @@ windows_xfer_shared_libraries (struct target_ops *ops,
   obstack_grow_str (&obstack, "<library-list>\n");
   for (so = solib_start.next; so; so = so->next)
     windows_xfer_shared_library (so->so_name, (CORE_ADDR) (uintptr_t) so->lm_info->load_addr,
-                                &obstack);
+                                target_gdbarch, &obstack);
   obstack_grow_str0 (&obstack, "</library-list>\n");
 
   buf = obstack_finish (&obstack);
@@ -2142,6 +2223,12 @@ windows_xfer_partial (struct target_ops *ops, enum target_object object,
     }
 }
 
+static ptid_t
+windows_get_ada_task_ptid (long lwp, long thread)
+{
+  return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
+}
+
 static void
 init_windows_ops (void)
 {
@@ -2177,14 +2264,25 @@ init_windows_ops (void)
   windows_ops.to_pid_to_str = windows_pid_to_str;
   windows_ops.to_stop = windows_stop;
   windows_ops.to_stratum = process_stratum;
-  windows_ops.to_has_all_memory = 1;
-  windows_ops.to_has_memory = 1;
-  windows_ops.to_has_stack = 1;
-  windows_ops.to_has_registers = 1;
-  windows_ops.to_has_execution = 1;
+  windows_ops.to_has_all_memory = default_child_has_all_memory;
+  windows_ops.to_has_memory = default_child_has_memory;
+  windows_ops.to_has_stack = default_child_has_stack;
+  windows_ops.to_has_registers = default_child_has_registers;
+  windows_ops.to_has_execution = default_child_has_execution;
   windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
+  windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
+
   i386_use_watchpoints (&windows_ops);
 
+  i386_dr_low.set_control = cygwin_set_dr7;
+  i386_dr_low.set_addr = cygwin_set_dr;
+  i386_dr_low.reset_addr = NULL;
+  i386_dr_low.get_status = cygwin_get_dr6;
+
+  /* i386_dr_low.debug_register_length field is set by
+     calling i386_set_debug_register_length function
+     in processor windows specific native file.  */
+
   windows_ops.to_magic = OPS_MAGIC;
 }
 
@@ -2201,12 +2299,20 @@ _initialize_windows_nat (void)
 
   init_windows_ops ();
 
+#ifdef __CYGWIN__
+  cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
+#endif
+
   c = add_com ("dll-symbols", class_files, dll_symbol_command,
               _("Load dll library symbols from FILE."));
   set_cmd_completer (c, filename_completer);
 
   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
 
+  add_com_alias ("add-shared-symbol-files", "dll-symbols", class_alias, 1);
+
+  add_com_alias ("assf", "dll-symbols", class_alias, 1);
+
 #ifdef __CYGWIN__
   add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
 Set use of shell to start subprocess."), _("\
@@ -2282,7 +2388,7 @@ Show whether to display kernel exceptions in child process."), NULL,
 /* Pass the address ADDR to the inferior in the I'th debug register.
    Here we just store the address in dr array, the registers will be
    actually set up when windows_continue is called.  */
-void
+static void
 cygwin_set_dr (int i, CORE_ADDR addr)
 {
   if (i < 0 || i > 3)
@@ -2296,10 +2402,10 @@ cygwin_set_dr (int i, CORE_ADDR addr)
 /* Pass the value VAL to the inferior in the DR7 debug control
    register.  Here we just store the address in D_REGS, the watchpoint
    will be actually set up in windows_wait.  */
-void
-cygwin_set_dr7 (unsigned val)
+static void
+cygwin_set_dr7 (unsigned long val)
 {
-  dr[7] = val;
+  dr[7] = (CORE_ADDR) val;
   debug_registers_changed = 1;
   debug_registers_used = 1;
 }
@@ -2307,10 +2413,10 @@ cygwin_set_dr7 (unsigned val)
 /* Get the value of the DR6 debug status register from the inferior.
    Here we just return the value stored in dr[6]
    by the last call to thread_rec for current_event.dwThreadId id.  */
-unsigned
+static unsigned long
 cygwin_get_dr6 (void)
 {
-  return dr[6];
+  return (unsigned long) dr[6];
 }
 
 /* Determine if the thread referenced by "ptid" is alive
@@ -2379,17 +2485,31 @@ bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
 {
   return FALSE;
 }
+#ifndef __CYGWIN__
 static DWORD WINAPI
 bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
 {
   return 0;
 }
+#else
+static DWORD WINAPI
+bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
+{
+  return 0;
+}
+#endif
 static BOOL WINAPI
 bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
 {
   return FALSE;
 }
 
+static BOOL WINAPI
+bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
+{
+  return FALSE;
+}
+
 /* Load any functions which may not be available in ancient versions
    of Windows. */
 void
@@ -2427,19 +2547,49 @@ _initialize_loadable (void)
        GetProcAddress (hm, "EnumProcessModules");
       dyn_GetModuleInformation = (void *)
        GetProcAddress (hm, "GetModuleInformation");
+#ifndef __CYGWIN__
       dyn_GetModuleFileNameExA = (void *)
        GetProcAddress (hm, "GetModuleFileNameExA");
+#else
+      dyn_GetModuleFileNameExW = (void *)
+       GetProcAddress (hm, "GetModuleFileNameExW");
+#endif
     }
 
-  if (!dyn_EnumProcessModules || !dyn_GetModuleInformation || !dyn_GetModuleFileNameExA)
+  if (!dyn_EnumProcessModules || !dyn_GetModuleInformation
+#ifndef __CYGWIN__
+      || !dyn_GetModuleFileNameExA
+#else
+      || !dyn_GetModuleFileNameExW
+#endif
+     )
     {
       /* Set variables to dummy versions of these processes if the function
         wasn't found in psapi.dll. */
       dyn_EnumProcessModules = bad_EnumProcessModules;
       dyn_GetModuleInformation = bad_GetModuleInformation;
+#ifndef __CYGWIN__
       dyn_GetModuleFileNameExA = bad_GetModuleFileNameExA;
+#else
+      dyn_GetModuleFileNameExW = bad_GetModuleFileNameExW;
+#endif
       /* This will probably fail on Windows 9x/Me.  Let the user know that we're
         missing some functionality. */
-      warning(_("cannot automatically find executable file or library to read symbols.  Use \"file\" or \"dll\" command to load executable/libraries directly."));
+      warning(_("cannot automatically find executable file or library to read symbols.\nUse \"file\" or \"dll\" command to load executable/libraries directly."));
+    }
+
+  hm = LoadLibrary ("advapi32.dll");
+  if (hm)
+    {
+      dyn_OpenProcessToken = (void *)
+       GetProcAddress (hm, "OpenProcessToken");
+      dyn_LookupPrivilegeValueA = (void *)
+       GetProcAddress (hm, "LookupPrivilegeValueA");
+      dyn_AdjustTokenPrivileges = (void *)
+       GetProcAddress (hm, "AdjustTokenPrivileges");
+      /* Only need to set one of these since if OpenProcessToken fails nothing
+        else is needed. */
+      if (!dyn_OpenProcessToken || !dyn_LookupPrivilegeValueA || !dyn_AdjustTokenPrivileges)
+       dyn_OpenProcessToken = bad_OpenProcessToken;
     }
 }