Implement "set cwd" command on GDB
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
index 76313db98914973135247bddc6314ef8464202bc..1ef38fb32b4bd8cb9d9907ba1c7d728658a9f446 100644 (file)
@@ -66,6 +66,7 @@
 #include "x86-nat.h"
 #include "complaints.h"
 #include "inf-child.h"
+#include "gdb_tilde_expand.h"
 
 #define AdjustTokenPrivileges          dyn_AdjustTokenPrivileges
 #define DebugActiveProcessStop         dyn_DebugActiveProcessStop
@@ -585,9 +586,9 @@ struct safe_symbol_file_add_args
 };
 
 /* Maintain a linked list of "so" information.  */
-struct lm_info
+struct lm_info_windows : public lm_info_base
 {
-  LPVOID load_addr;
+  LPVOID load_addr = 0;
 };
 
 static struct so_list solib_start, *solib_end;
@@ -645,8 +646,9 @@ windows_make_so (const char *name, LPVOID load_addr)
     }
 #endif
   so = XCNEW (struct so_list);
-  so->lm_info = XNEW (struct lm_info);
-  so->lm_info->load_addr = load_addr;
+  lm_info_windows *li = new lm_info_windows;
+  so->lm_info = li;
+  li->load_addr = load_addr;
   strcpy (so->so_original_name, name);
 #ifndef __CYGWIN__
   strcpy (so->so_name, buf);
@@ -772,8 +774,10 @@ handle_load_dll (void *dummy)
   solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
   solib_end = solib_end->next;
 
+  lm_info_windows *li = (lm_info_windows *) solib_end->lm_info;
+
   DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
-                host_address_to_string (solib_end->lm_info->load_addr)));
+                host_address_to_string (li->load_addr)));
 
   return 1;
 }
@@ -781,8 +785,9 @@ handle_load_dll (void *dummy)
 static void
 windows_free_so (struct so_list *so)
 {
-  if (so->lm_info)
-    xfree (so->lm_info);
+  lm_info_windows *li = (lm_info_windows *) so->lm_info;
+
+  delete li;
   xfree (so);
 }
 
@@ -801,18 +806,22 @@ handle_unload_dll (void *dummy)
   struct so_list *so;
 
   for (so = &solib_start; so->next != NULL; so = so->next)
-    if (so->next->lm_info->load_addr == lpBaseOfDll)
-      {
-       struct so_list *sodel = so->next;
+    {
+      lm_info_windows *li_next = (lm_info_windows *) so->next->lm_info;
 
-       so->next = sodel->next;
-       if (!so->next)
-         solib_end = so;
-       DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
+      if (li_next->load_addr == lpBaseOfDll)
+       {
+         struct so_list *sodel = so->next;
 
-       windows_free_so (sodel);
-       return 1;
-      }
+         so->next = sodel->next;
+         if (!so->next)
+           solib_end = so;
+         DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
+
+         windows_free_so (sodel);
+         return 1;
+       }
+    }
 
   /* 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
@@ -1511,7 +1520,7 @@ get_windows_debug_event (struct target_ops *ops,
                     "EXIT_PROCESS_DEBUG_EVENT"));
       if (!windows_initialization_done)
        {
-         target_terminal_ours ();
+         target_terminal::ours ();
          target_mourn_inferior (inferior_ptid);
          error (_("During startup program exited with code 0x%x."),
                 (unsigned int) current_event.u.ExitProcess.dwExitCode);
@@ -1618,7 +1627,7 @@ windows_wait (struct target_ops *ops,
 {
   int pid = -1;
 
-  target_terminal_ours ();
+  target_terminal::ours ();
 
   /* We loop when we get a non-standard exception rather than return
      with a SPURIOUS because resume can try and step or modify things,
@@ -1763,8 +1772,8 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
      current thread until we report an event out of windows_wait.  */
   inferior_ptid = pid_to_ptid (pid);
 
-  target_terminal_init ();
-  target_terminal_inferior ();
+  target_terminal::init ();
+  target_terminal::inferior ();
 
   windows_initialization_done = 0;
 
@@ -1904,7 +1913,7 @@ windows_attach (struct target_ops *ops, const char *args, int from_tty)
     }
 
   do_initial_windows_stuff (ops, pid, 1);
-  target_terminal_ours ();
+  target_terminal::ours ();
 }
 
 static void
@@ -1912,7 +1921,7 @@ windows_detach (struct target_ops *ops, const char *args, int from_tty)
 {
   int detached = 1;
 
-  ptid_t ptid = {-1};
+  ptid_t ptid = minus_one_ptid;
   windows_resume (ops, ptid, 0, GDB_SIGNAL_0);
 
   if (!DebugActiveProcessStop (current_event.dwProcessId))
@@ -1925,7 +1934,7 @@ windows_detach (struct target_ops *ops, const char *args, int from_tty)
 
   if (detached && from_tty)
     {
-      char *exec_file = get_exec_file (0);
+      const char *exec_file = get_exec_file (0);
       if (exec_file == 0)
        exec_file = "";
       printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file,
@@ -2412,13 +2421,15 @@ redirect_inferior_handles (const char *cmd_orig, char *cmd,
    ENV is the environment vector to pass.  Errors reported with error().  */
 
 static void
-windows_create_inferior (struct target_ops *ops, char *exec_file,
-                      char *allargs, char **in_env, int from_tty)
+windows_create_inferior (struct target_ops *ops, const char *exec_file,
+                        const std::string &origallargs, char **in_env,
+                        int from_tty)
 {
   STARTUPINFO si;
 #ifdef __CYGWIN__
   cygwin_buf_t real_path[__PMAX];
   cygwin_buf_t shell[__PMAX]; /* Path to shell */
+  cygwin_buf_t infcwd[__PMAX];
   const char *sh;
   cygwin_buf_t *toexec;
   cygwin_buf_t *cygallargs;
@@ -2431,7 +2442,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
 #else  /* !__CYGWIN__ */
   char real_path[__PMAX];
   char shell[__PMAX]; /* Path to shell */
-  char *toexec;
+  const char *toexec;
   char *args, *allargs_copy;
   size_t args_len, allargs_len;
   int fd_inp = -1, fd_out = -1, fd_err = -1;
@@ -2447,6 +2458,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
   size_t envsize;
   char **env;
 #endif /* !__CYGWIN__ */
+  const char *allargs = origallargs.c_str ();
   PROCESS_INFORMATION pi;
   BOOL ret;
   DWORD flags = 0;
@@ -2455,6 +2467,17 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
   if (!exec_file)
     error (_("No executable specified, use `target exec'."));
 
+  const char *inferior_cwd = get_inferior_cwd ();
+  std::string expanded_infcwd;
+  if (inferior_cwd != NULL)
+    {
+      expanded_infcwd = gdb_tilde_expand (inferior_cwd);
+      /* Mirror slashes on inferior's cwd.  */
+      std::replace (expanded_infcwd.begin (), expanded_infcwd.end (),
+                   '/', '\\');
+      inferior_cwd = expanded_infcwd.c_str ();
+    }
+
   memset (&si, 0, sizeof (si));
   si.cb = sizeof (si);
 
@@ -2504,6 +2527,11 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
       flags |= DEBUG_PROCESS;
     }
 
+  if (inferior_cwd != NULL
+      && cygwin_conv_path (CCP_POSIX_TO_WIN_W, inferior_cwd,
+                          infcwd, strlen (inferior_cwd)) < 0)
+    error (_("Error converting inferior cwd: %d"), errno);
+
 #ifdef __USEWIDE
   args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
                                  * sizeof (wchar_t));
@@ -2564,7 +2592,8 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
                       TRUE,    /* inherit handles */
                       flags,   /* start flags */
                       w32_env, /* environment */
-                      NULL,    /* current directory */
+                      inferior_cwd != NULL ? infcwd : NULL, /* current
+                                                               directory */
                       &si,
                       &pi);
   if (w32_env)
@@ -2687,7 +2716,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
                        TRUE,   /* inherit handles */
                        flags,  /* start flags */
                        w32env, /* environment */
-                       NULL,   /* current directory */
+                       inferior_cwd, /* current directory */
                        &si,
                        &pi);
   if (tty != INVALID_HANDLE_VALUE)
@@ -2807,7 +2836,7 @@ windows_close (struct target_ops *self)
 }
 
 /* Convert pid to printable format.  */
-static char *
+static const char *
 windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   static char buf[80];
@@ -2840,9 +2869,13 @@ windows_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)
-    windows_xfer_shared_library (so->so_name, (CORE_ADDR)
-                                (uintptr_t) so->lm_info->load_addr,
-                                target_gdbarch (), &obstack);
+    {
+      lm_info_windows *li = (lm_info_windows *) so->lm_info;
+
+      windows_xfer_shared_library (so->so_name, (CORE_ADDR)
+                                  (uintptr_t) li->load_addr,
+                                  target_gdbarch (), &obstack);
+    }
   obstack_grow_str0 (&obstack, "</library-list>\n");
 
   buf = (const char *) obstack_finish (&obstack);
@@ -2945,9 +2978,6 @@ windows_target (void)
   return t;
 }
 
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_windows_nat;
-
 void
 _initialize_windows_nat (void)
 {
@@ -3116,9 +3146,6 @@ windows_thread_alive (struct target_ops *ops, ptid_t ptid)
     ? FALSE : TRUE;
 }
 
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_check_for_gdb_ini;
-
 void
 _initialize_check_for_gdb_ini (void)
 {
@@ -3213,9 +3240,6 @@ bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
   return size;
 }
  
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_loadable;
-
 /* Load any functions which may not be available in ancient versions
    of Windows.  */
 
This page took 0.0285 seconds and 4 git commands to generate.