gdb: include gdbsupport/buildargv.h in ser-mingw.c
[binutils-gdb.git] / gdb / nto-procfs.c
index 51559e6c3ed7c3e378f91ade992be1b8ce547eec..da0feaedff9fab03228f492add19923d4a048b04 100644 (file)
@@ -1,7 +1,7 @@
 /* Machine independent support for QNX Neutrino /proc (process file system)
    for GDB.  Written by Colin Burgess at QNX Software Systems Limited.
 
-   Copyright (C) 2003-2018 Free Software Foundation, Inc.
+   Copyright (C) 2003-2022 Free Software Foundation, Inc.
 
    Contributed by QNX Software Systems Ltd.
 
@@ -42,8 +42,8 @@
 #include "regcache.h"
 #include "solib.h"
 #include "inf-child.h"
-#include "common/filestuff.h"
-#include "common/scoped_fd.h"
+#include "gdbsupport/filestuff.h"
+#include "gdbsupport/scoped_fd.h"
 
 #define NULL_PID               0
 #define _DEBUG_FLAG_TRACE      (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
@@ -69,7 +69,7 @@ struct nto_procfs_target : public inf_child_target
 
   void resume (ptid_t, int, enum gdb_signal) override;
 
-  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
 
   void fetch_registers (struct regcache *, int) override;
   void store_registers (struct regcache *, int) override;
@@ -109,19 +109,16 @@ struct nto_procfs_target : public inf_child_target
 
   void mourn_inferior () override;
 
-  void pass_signals (int, unsigned char *) override;
+  void pass_signals (gdb::array_view<const unsigned char>) override;
 
   bool thread_alive (ptid_t ptid) override;
 
   void update_thread_list () override;
 
-  const char *pid_to_str (ptid_t) override;
+  std::string pid_to_str (ptid_t) override;
 
   void interrupt () override;
 
-  bool have_continuable_watchpoint ()
-  { return true; }
-
   const char *extra_thread_info (struct thread_info *) override;
 
   char *pid_to_exec_file (int pid) override;
@@ -146,7 +143,7 @@ class nto_procfs_target_native final : public nto_procfs_target
 static const target_info nto_procfs_target_info = {
   "procfs",
   N_("QNX Neutrino local or remote process"),
-  N_("QNX Neutrino process.  target procfs <node>")
+  N_("QNX Neutrino process.  target procfs NODE")
 };
 
 struct nto_procfs_target_procfs final : public nto_procfs_target
@@ -217,8 +214,6 @@ nto_procfs_target::open (const char *arg, int from_tty)
   nto_procfs_node = ND_LOCAL_NODE;
   nodestr = (arg != NULL) ? xstrdup (arg) : NULL;
 
-  init_thread_list ();
-
   if (nodestr)
     {
       nto_procfs_node = netmgr_strtond (nodestr, &endstr);
@@ -296,7 +291,7 @@ procfs_set_thread (ptid_t ptid)
 {
   pid_t tid;
 
-  tid = ptid_get_tid (ptid);
+  tid = ptid.tid ();
   devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
 }
 
@@ -310,8 +305,8 @@ nto_procfs_target::thread_alive (ptid_t ptid)
   procfs_status status;
   int err;
 
-  tid = ptid_get_tid (ptid);
-  pid = ptid_get_pid (ptid);
+  tid = ptid.tid ();
+  pid = ptid.pid ();
 
   if (kill (pid, 0) == -1)
     return false;
@@ -398,7 +393,7 @@ nto_procfs_target::update_thread_list ()
 
   prune_threads ();
 
-  pid = ptid_get_pid (inferior_ptid);
+  pid = current_inferior ()->pid;
 
   status.tid = 1;
 
@@ -413,8 +408,8 @@ nto_procfs_target::update_thread_list ()
           returned different tid, meaning the requested tid no longer exists
           (e.g. thread exited).  */
        continue;
-      ptid = ptid_build (pid, 0, tid);
-      new_thread = find_thread_ptid (ptid);
+      ptid = ptid_t (pid, 0, tid);
+      new_thread = find_thread_ptid (this, ptid);
       if (!new_thread)
        new_thread = add_thread (ptid);
       update_thread_private_data (new_thread, tid, status.state, 0);
@@ -423,16 +418,9 @@ nto_procfs_target::update_thread_list ()
   return;
 }
 
-static void
-do_closedir_cleanup (void *dir)
-{
-  closedir (dir);
-}
-
 static void
 procfs_pidlist (const char *args, int from_tty)
 {
-  DIR *dp = NULL;
   struct dirent *dirp = NULL;
   char buf[PATH_MAX];
   procfs_info *pidinfo = NULL;
@@ -441,13 +429,12 @@ procfs_pidlist (const char *args, int from_tty)
   pid_t num_threads = 0;
   pid_t pid;
   char name[512];
-  struct cleanup *cleanups;
   char procfs_dir[PATH_MAX];
 
   snprintf (procfs_dir, sizeof (procfs_dir), "%s%s",
            (nodestr != NULL) ? nodestr : "", "/proc");
 
-  dp = opendir (procfs_dir);
+  gdb_dir_up dp (opendir (procfs_dir));
   if (dp == NULL)
     {
       fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
@@ -455,22 +442,17 @@ procfs_pidlist (const char *args, int from_tty)
       return;
     }
 
-  cleanups = make_cleanup (do_closedir_cleanup, dp);
-
   /* Start scan at first pid.  */
-  rewinddir (dp);
+  rewinddir (dp.get ());
 
   do
     {
       /* Get the right pid and procfs path for the pid.  */
       do
        {
-         dirp = readdir (dp);
+         dirp = readdir (dp.get ());
          if (dirp == NULL)
-           {
-             do_cleanups (cleanups);
-             return;
-           }
+           return;
          snprintf (buf, sizeof (buf), "%s%s/%s/as",
                    (nodestr != NULL) ? nodestr : "",
                    "/proc", dirp->d_name);
@@ -521,9 +503,6 @@ procfs_pidlist (const char *args, int from_tty)
        }
     }
   while (dirp != NULL);
-
-  do_cleanups (cleanups);
-  return;
 }
 
 static void
@@ -626,7 +605,7 @@ procfs_meminfo (const char *args, int from_tty)
              if (strcmp (map.info.path, printme.name))
                continue;
 
-             /* Lower debug_vaddr is always text, if nessessary, swap.  */
+             /* Lower debug_vaddr is always text, if necessary, swap.  */
              if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
                {
                  memcpy (&(printme.data), &(printme.text),
@@ -677,10 +656,10 @@ nto_procfs_target::files_info ()
 {
   struct inferior *inf = current_inferior ();
 
-  printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
-                    inf->attach_flag ? "attached" : "child",
-                    target_pid_to_str (inferior_ptid),
-                    (nodestr != NULL) ? nodestr : "local node");
+  printf_filtered ("\tUsing the running image of %s %s via %s.\n",
+                  inf->attach_flag ? "attached" : "child",
+                  target_pid_to_str (inferior_ptid).c_str (),
+                  (nodestr != NULL) ? nodestr : "local node");
 }
 
 /* Target to_pid_to_exec_file implementation.  */
@@ -714,7 +693,6 @@ nto_procfs_target::pid_to_exec_file (const int pid)
 void
 nto_procfs_target::attach (const char *args, int from_tty)
 {
-  char *exec_file;
   int pid;
   struct inferior *inf;
 
@@ -723,34 +701,25 @@ nto_procfs_target::attach (const char *args, int from_tty)
   if (pid == getpid ())
     error (_("Attaching GDB to itself is not a good idea..."));
 
-  if (from_tty)
-    {
-      exec_file = (char *) get_exec_file (0);
-
-      if (exec_file)
-       printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
-                          target_pid_to_str (pid_to_ptid (pid)));
-      else
-       printf_unfiltered ("Attaching to %s\n",
-                          target_pid_to_str (pid_to_ptid (pid)));
+  target_announce_attach (from_tty, pid);
 
-      gdb_flush (gdb_stdout);
-    }
-  inferior_ptid = do_attach (pid_to_ptid (pid));
+  ptid_t ptid = do_attach (ptid_t (pid));
   inf = current_inferior ();
   inferior_appeared (inf, pid);
   inf->attach_flag = 1;
 
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  if (!inf->target_is_pushed (ops))
+    inf->push_target (ops);
 
-  procfs_update_thread_list (ops);
+  update_thread_list ();
+
+  switch_to_thread (find_thread_ptid (this, ptid));
 }
 
 void
 nto_procfs_target::post_attach (pid_t pid)
 {
-  if (exec_bfd)
+  if (current_program_space->exec_bfd ())
     solib_create_inferior_hook (0);
 }
 
@@ -762,7 +731,7 @@ do_attach (ptid_t ptid)
   char path[PATH_MAX];
 
   snprintf (path, PATH_MAX - 1, "%s%s/%d/as",
-           (nodestr != NULL) ? nodestr : "", "/proc", ptid_get_pid (ptid));
+           (nodestr != NULL) ? nodestr : "", "/proc", ptid.pid ());
   ctl_fd = open (path, O_RDWR);
   if (ctl_fd == -1)
     error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
@@ -780,9 +749,9 @@ do_attach (ptid_t ptid)
 
   if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
       && status.flags & _DEBUG_FLAG_STOPPED)
-    SignalKill (nto_node (), ptid_get_pid (ptid), 0, SIGCONT, 0, 0);
+    SignalKill (nto_node (), ptid.pid (), 0, SIGCONT, 0, 0);
   nto_init_solib_absolute_prefix ();
-  return ptid_build (ptid_get_pid (ptid), 0, status.tid);
+  return ptid_t (ptid.pid (), 0, status.tid);
 }
 
 /* Ask the user what to do when an interrupt is received.  */
@@ -817,19 +786,18 @@ nto_handle_sigint (int signo)
 
 sptid_t
 nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
-                        int options)
+                        target_wait_flags options)
 {
   sigset_t set;
   siginfo_t info;
   procfs_status status;
   static int exit_signo = 0;   /* To track signals that cause termination.  */
 
-  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+  ourstatus->set_spurious ();
 
-  if (ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid == null_ptid)
     {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = GDB_SIGNAL_0;
+      ourstatus->set_stopped (GDB_SIGNAL_0);
       exit_signo = 0;
       return null_ptid;
     }
@@ -850,38 +818,29 @@ nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
   nto_inferior_data (NULL)->stopped_pc = status.ip;
 
   if (status.flags & _DEBUG_FLAG_SSTEP)
-    {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
-    }
+    ourstatus->set_stopped (GDB_SIGNAL_TRAP);
   /* Was it a breakpoint?  */
   else if (status.flags & _DEBUG_FLAG_TRACE)
-    {
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = GDB_SIGNAL_TRAP;
-    }
+    ourstatus->set_stopped (GDB_SIGNAL_TRAP);
   else if (status.flags & _DEBUG_FLAG_ISTOP)
     {
       switch (status.why)
        {
        case _DEBUG_WHY_SIGNALLED:
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
-         ourstatus->value.sig =
-           gdb_signal_from_host (status.info.si_signo);
+         ourstatus->set_stopped (gdb_signal_from_host (status.info.si_signo));
          exit_signo = 0;
          break;
        case _DEBUG_WHY_FAULTED:
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
          if (status.info.si_signo == SIGTRAP)
            {
-             ourstatus->value.sig = 0;
+             ourstatus->set_stopped (0);
              exit_signo = 0;
            }
          else
            {
-             ourstatus->value.sig =
-               gdb_signal_from_host (status.info.si_signo);
-             exit_signo = ourstatus->value.sig;
+             ourstatus->set_stopped
+               (gdb_signal_from_host (status.info.si_signo));
+             exit_signo = ourstatus->sig ();
            }
          break;
 
@@ -889,18 +848,16 @@ nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
          {
            int waitval = 0;
 
-           waitpid (ptid_get_pid (inferior_ptid), &waitval, WNOHANG);
+           waitpid (inferior_ptid.pid (), &waitval, WNOHANG);
            if (exit_signo)
              {
                /* Abnormal death.  */
-               ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-               ourstatus->value.sig = exit_signo;
+               ourstatus->set_signalled (exit_signo);
              }
            else
              {
                /* Normal death.  */
-               ourstatus->kind = TARGET_WAITKIND_EXITED;
-               ourstatus->value.integer = WEXITSTATUS (waitval);
+               ourstatus->set_exited (WEXITSTATUS (waitval));
              }
            exit_signo = 0;
            break;
@@ -908,14 +865,13 @@ nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 
        case _DEBUG_WHY_REQUESTED:
          /* We are assuming a requested stop is due to a SIGINT.  */
-         ourstatus->kind = TARGET_WAITKIND_STOPPED;
-         ourstatus->value.sig = GDB_SIGNAL_INT;
+         ourstatus->set_stopped (GDB_SIGNAL_INT);
          exit_signo = 0;
          break;
        }
     }
 
-  return ptid_build (status.pid, 0, status.tid);
+  return ptid_t (status.pid, 0, status.tid);
 }
 
 /* Read the current values of the inferior's registers, both the
@@ -933,7 +889,7 @@ nto_procfs_target::fetch_registers (struct regcache *regcache, int regno)
   reg;
   int regsize;
 
-  procfs_set_thread (regcache_get_ptid (regcache));
+  procfs_set_thread (regcache->ptid ());
   if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
     nto_supply_gregset (regcache, (char *) &reg.greg);
   if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
@@ -994,7 +950,7 @@ nto_procfs_target::xfer_partial (enum target_object object,
            return TARGET_XFER_E_IO;
 
          err = devctl (ctl_fd, DCMD_PROC_INFO, &procinfo,
-                       sizeof procinfo, 0);
+                       sizeof procinfo, 0);
          if (err != EOK)
            return TARGET_XFER_E_IO;
 
@@ -1011,9 +967,9 @@ nto_procfs_target::xfer_partial (enum target_object object,
        }
        /* Fallthru */
     default:
-      return this->beneath->xfer_partial (object, annex,
-                                         readbuf, writebuf, offset, len,
-                                         xfered_len);
+      return this->beneath ()->xfer_partial (object, annex,
+                                            readbuf, writebuf, offset, len,
+                                            xfered_len);
     }
 }
 
@@ -1024,19 +980,16 @@ nto_procfs_target::xfer_partial (enum target_object object,
 void
 nto_procfs_target::detach (inferior *inf, int from_tty)
 {
-  int pid;
-
   target_announce_detach ();
 
   if (siggnal)
-    SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, 0, 0, 0);
+    SignalKill (nto_node (), inf->pid, 0, 0, 0, 0);
 
   close (ctl_fd);
   ctl_fd = -1;
 
-  pid = ptid_get_pid (inferior_ptid);
-  inferior_ptid = null_ptid;
-  detach_inferior (pid);
+  switch_to_no_thread ();
+  detach_inferior (inf->pid);
   init_thread_list ();
   inf_child_maybe_unpush_target (ops);
 }
@@ -1095,10 +1048,10 @@ nto_procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
   procfs_status status;
   sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
 
-  if (ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid == null_ptid)
     return;
 
-  procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
+  procfs_set_thread (ptid == minus_one_ptid ? inferior_ptid :
                     ptid);
 
   run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
@@ -1129,7 +1082,7 @@ nto_procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
        {
          if (signal_to_pass != status.info.si_signo)
            {
-             SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0,
+             SignalKill (nto_node (), inferior_ptid.pid (), 0,
                          signal_to_pass, 0, 0);
              run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
            }
@@ -1151,12 +1104,12 @@ nto_procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 void
 nto_procfs_target::mourn_inferior ()
 {
-  if (!ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid != null_ptid)
     {
-      SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, SIGKILL, 0, 0);
+      SignalKill (nto_node (), inferior_ptid.pid (), 0, SIGKILL, 0, 0);
       close (ctl_fd);
     }
-  inferior_ptid = null_ptid;
+  switch_to_no_thread ();
   init_thread_list ();
   inf_child_mourn_inferior (ops);
 }
@@ -1167,7 +1120,7 @@ nto_procfs_target::mourn_inferior ()
    the string "a b c d", and as output it would fill in argv with
    the four arguments "a", "b", "c", "d".  The only additional
    functionality is simple quoting.  The gdb command:
-       run a "b c d" f
+       run a "b c d" f
    will fill in argv with the three args "a", "b c d", "e".  */
 static void
 breakup_args (char *scratch, char **argv)
@@ -1233,12 +1186,11 @@ nto_procfs_target::create_inferior (const char *exec_file,
   const char *in = "", *out = "", *err = "";
   int fd, fds[3];
   sigset_t set;
-  const char *inferior_io_terminal = get_inferior_io_terminal ();
   struct inferior *inf;
 
   argv = xmalloc ((allargs.size () / (unsigned) 2 + 2) *
                  sizeof (*argv));
-  argv[0] = get_exec_file (1);
+  argv[0] = const_cast<char *> (get_exec_file (1));
   if (!argv[0])
     {
       if (exec_file)
@@ -1258,14 +1210,15 @@ nto_procfs_target::create_inferior (const char *exec_file,
 
   /* If the user specified I/O via gdb's --tty= arg, use it, but only
      if the i/o is not also being specified via redirection.  */
-  if (inferior_io_terminal)
+  const char *inferior_tty = current_inferior ()->tty ();
+  if (inferior_tty != nullptr)
     {
       if (!in[0])
-       in = inferior_io_terminal;
+       in = inferior_tty;
       if (!out[0])
-       out = inferior_io_terminal;
+       out = inferior_tty;
       if (!err[0])
-       err = inferior_io_terminal;
+       err = inferior_tty;
     }
 
   if (in[0])
@@ -1327,8 +1280,9 @@ nto_procfs_target::create_inferior (const char *exec_file,
   if (fds[2] != STDERR_FILENO)
     close (fds[2]);
 
-  inferior_ptid = do_attach (pid_to_ptid (pid));
-  procfs_update_thread_list (ops);
+  ptid_t ptid = do_attach (ptid_t (pid));
+  update_thread_list ();
+  switch_to_thread (find_thread_ptid (this, ptid));
 
   inf = current_inferior ();
   inferior_appeared (inf, pid);
@@ -1340,14 +1294,15 @@ nto_procfs_target::create_inferior (const char *exec_file,
     {
       /* FIXME: expected warning?  */
       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
-         errn, strerror(errn) ); */
+        errn, safe_strerror(errn) ); */
     }
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  if (!inf->target_is_pushed (ops))
+    inf->push_target (ops);
   target_terminal::init ();
 
-  if (exec_bfd != NULL
-      || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
+  if (current_program_space->exec_bfd () != NULL
+      || (current_program_space->symfile_object_file != NULL
+         && current_program_space->symfile_object_file->obfd != NULL))
     solib_create_inferior_hook (0);
 }
 
@@ -1409,9 +1364,9 @@ nto_procfs_target::store_registers (struct regcache *regcache, int regno)
   unsigned off;
   int len, regset, regsize, dev_set, err;
   char *data;
-  ptid_t ptid = regcache_get_ptid (regcache);
+  ptid_t ptid = regcache->ptid ();
 
-  if (ptid_equal (ptid, null_ptid))
+  if (ptid == null_ptid)
     return;
   procfs_set_thread (ptid);
 
@@ -1450,7 +1405,7 @@ nto_procfs_target::store_registers (struct regcache *regcache, int regno)
       if (len < 1)
        return;
 
-      regcache_raw_collect (regcache, regno, (char *) &reg + off);
+      regcache->raw_collect (regno, (char *) &reg + off);
 
       err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
       if (err != EOK)
@@ -1463,7 +1418,8 @@ nto_procfs_target::store_registers (struct regcache *regcache, int regno)
 /* Set list of signals to be handled in the target.  */
 
 void
-nto_procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
+nto_procfs_target::pass_signals
+  (gdb::array_view<const unsigned char> pass_signals)
 {
   int signo;
 
@@ -1472,22 +1428,19 @@ nto_procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
   for (signo = 1; signo < NSIG; signo++)
     {
       int target_signo = gdb_signal_from_host (signo);
-      if (target_signo < numsigs && pass_signals[target_signo])
-        sigdelset (&run.trace, signo);
+      if (target_signo < pass_signals.size () && pass_signals[target_signo])
+       sigdelset (&run.trace, signo);
     }
 }
 
-char *
+std::string
 nto_procfs_target::pid_to_str (ptid_t ptid)
 {
-  static char buf[1024];
-  int pid, tid, n;
+  int pid, tid;
   struct tidinfo *tip;
 
-  pid = ptid_get_pid (ptid);
-  tid = ptid_get_tid (ptid);
-
-  n = snprintf (buf, 1023, "process %d", pid);
+  pid = ptid.pid ();
+  tid = ptid.tid ();
 
 #if 0                          /* NYI */
   tip = procfs_thread_info (pid, tid);
@@ -1495,7 +1448,7 @@ nto_procfs_target::pid_to_str (ptid_t ptid)
     snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
 #endif
 
-  return buf;
+  return string_printf ("process %d", pid);
 }
 
 /* to_can_run implementation for "target procfs".  Note this really
@@ -1531,8 +1484,9 @@ init_procfs_targets (void)
 
 #define OSTYPE_NTO 1
 
+void _initialize_procfs ();
 void
-_initialize_procfs (void)
+_initialize_procfs ()
 {
   sigset_t set;