Update ROCm for multi-target support
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 0d8f9df966511e7ca8bdb9254c1a9ee2fe417311..a59e32c6d7ad315527e4d2cb14cf826c20ec740c 100644 (file)
@@ -1,6 +1,6 @@
 /* Machine independent support for Solaris /proc (process file system) for GDB.
 
-   Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    Written by Michael Snyder at Cygnus Solutions.
    Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
 #include "regcache.h"
 #include "inf-child.h"
 #include "nat/fork-inferior.h"
-#include "filestuff.h"
+#include "gdbarch.h"
 
 #define _STRUCTURED_PROC 1     /* Should be done by configure script.  */
 
 #include <sys/procfs.h>
 #include <sys/fault.h>
 #include <sys/syscall.h>
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
 #include <signal.h>
 #include <ctype.h>
 #include "gdb_bfd.h"
@@ -46,8 +46,8 @@
 #include "auxv.h"
 #include "procfs.h"
 #include "observable.h"
-#include "common/scoped_fd.h"
-#include "common/pathstuff.h"
+#include "gdbsupport/scoped_fd.h"
+#include "gdbsupport/pathstuff.h"
 
 /* This module provides the interface between GDB and the
    /proc file system, which is used on many versions of Unix
@@ -119,7 +119,7 @@ public:
                                        ULONGEST offset, ULONGEST len,
                                        ULONGEST *xfered_len) override;
 
-  void pass_signals (int, unsigned char *) override;
+  void pass_signals (gdb::array_view<const unsigned char>) override;
 
   void files_info () override;
 
@@ -127,7 +127,7 @@ public:
 
   bool thread_alive (ptid_t ptid) override;
 
-  const char *pid_to_str (ptid_t) override;
+  std::string pid_to_str (ptid_t) override;
 
   char *pid_to_exec_file (int pid) override;
 
@@ -160,6 +160,8 @@ public:
 
   int can_use_hw_breakpoint (enum bptype, int, int) override;
   bool stopped_data_address (CORE_ADDR *) override;
+
+  void procfs_init_inferior (int pid);
 };
 
 static procfs_target the_procfs_target;
@@ -385,7 +387,7 @@ open_procinfo_files (procinfo *pi, int which)
      several.  Here is some rationale:
 
      There are several file descriptors that may need to be open
-       for any given process or LWP.  The ones we're intereted in are:
+       for any given process or LWP.  The ones we're interested in are:
         - control       (ctl)    write-only    change the state
         - status        (status) read-only     query the state
         - address space (as)     read/write    access memory
@@ -838,7 +840,7 @@ proc_unset_run_on_last_close (procinfo *pi)
 }
 
 /* Reset inherit_on_fork flag.  If the process forks a child while we
-   are registered for events in the parent, then we will NOT recieve
+   are registered for events in the parent, then we will NOT receive
    events from the child.  Returns non-zero for success, zero for
    failure.  */
 
@@ -909,7 +911,12 @@ proc_wait_for_stop (procinfo *pi)
 
   procfs_ctl_t cmd = PCWSTOP;
 
+  set_sigint_trap ();
+
   win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+
+  clear_sigint_trap ();
+
   /* We been runnin' and we stopped -- need to update status.  */
   pi->status_valid = 0;
 
@@ -1310,6 +1317,7 @@ proc_set_current_signal (procinfo *pi, int signo)
     char sinfo[sizeof (siginfo_t)];
   } arg;
   siginfo_t mysinfo;
+  process_stratum_target *wait_target;
   ptid_t wait_ptid;
   struct target_waitstatus wait_status;
 
@@ -1322,8 +1330,9 @@ proc_set_current_signal (procinfo *pi, int signo)
     pi = find_procinfo_or_die (pi->pid, 0);
 
   /* The pointer is just a type alias.  */
-  get_last_target_status (&wait_ptid, &wait_status);
-  if (wait_ptid == inferior_ptid
+  get_last_target_status (&wait_target, &wait_ptid, &wait_status);
+  if (wait_target == &the_procfs_target
+      && wait_ptid == inferior_ptid
       && wait_status.kind == TARGET_WAITKIND_STOPPED
       && wait_status.value.sig == gdb_signal_from_host (signo)
       && proc_get_status (pi)
@@ -1865,7 +1874,6 @@ procfs_debug_inferior (procinfo *pi)
 void
 procfs_target::attach (const char *args, int from_tty)
 {
-  char *exec_file;
   int   pid;
 
   pid = parse_pid_to_attach (args);
@@ -1875,14 +1883,14 @@ procfs_target::attach (const char *args, int from_tty)
 
   if (from_tty)
     {
-      exec_file = get_exec_file (0);
+      const char *exec_file = get_exec_file (0);
 
       if (exec_file)
        printf_filtered (_("Attaching to program `%s', %s\n"),
-                        exec_file, target_pid_to_str (ptid_t (pid)));
+                        exec_file, target_pid_to_str (ptid_t (pid)).c_str ());
       else
        printf_filtered (_("Attaching to %s\n"),
-                        target_pid_to_str (ptid_t (pid)));
+                        target_pid_to_str (ptid_t (pid)).c_str ());
 
       fflush (stdout);
     }
@@ -1905,8 +1913,7 @@ procfs_target::detach (inferior *inf, int from_tty)
        exec_file = "";
 
       printf_filtered (_("Detaching from program: %s, %s\n"), exec_file,
-                      target_pid_to_str (ptid_t (pid)));
-      gdb_flush (gdb_stdout);
+                      target_pid_to_str (ptid_t (pid)).c_str ());
     }
 
   do_detach ();
@@ -1984,7 +1991,7 @@ do_attach (ptid_t ptid)
 
   /* Add it to gdb's thread list.  */
   ptid = ptid_t (pi->pid, lwpid, 0);
-  add_thread (ptid);
+  add_thread (&the_procfs_target, ptid);
 
   return ptid;
 }
@@ -2059,7 +2066,7 @@ procfs_target::fetch_registers (struct regcache *regcache, int regnum)
 
   if (pi == NULL)
     error (_("procfs: fetch_registers failed to find procinfo for %s"),
-          target_pid_to_str (ptid));
+          target_pid_to_str (ptid).c_str ());
 
   gregs = proc_get_gregs (pi);
   if (gregs == NULL)
@@ -2108,7 +2115,7 @@ procfs_target::store_registers (struct regcache *regcache, int regnum)
 
   if (pi == NULL)
     error (_("procfs: store_registers: failed to find procinfo for %s"),
-          target_pid_to_str (ptid));
+          target_pid_to_str (ptid).c_str ());
 
   gregs = proc_get_gregs (pi);
   if (gregs == NULL)
@@ -2281,8 +2288,8 @@ wait_again:
                  {
                    if (print_thread_events)
                      printf_unfiltered (_("[%s exited]\n"),
-                                        target_pid_to_str (retval));
-                   delete_thread (find_thread_ptid (retval));
+                                        target_pid_to_str (retval).c_str ());
+                   delete_thread (find_thread_ptid (this, retval));
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
@@ -2304,7 +2311,7 @@ wait_again:
                    if (!proc_run_process (pi, 0, 0))
                      proc_error (pi, "target_wait, run_process", __LINE__);
 
-                   inf = find_inferior_pid (pi->pid);
+                   inf = find_inferior_pid (this, pi->pid);
                    if (inf->attach_flag)
                      {
                        /* Don't call wait: simulate waiting for exit,
@@ -2391,8 +2398,8 @@ wait_again:
 
                    temp_ptid = ptid_t (pi->pid, temp_tid, 0);
                    /* If not in GDB's thread list, add it.  */
-                   if (!in_thread_list (temp_ptid))
-                     add_thread (temp_ptid);
+                   if (!in_thread_list (this, temp_ptid))
+                     add_thread (this, temp_ptid);
 
                    /* Return to WFI, but tell it to immediately resume.  */
                    status->kind = TARGET_WAITKIND_SPURIOUS;
@@ -2402,8 +2409,8 @@ wait_again:
                  {
                    if (print_thread_events)
                      printf_unfiltered (_("[%s exited]\n"),
-                                        target_pid_to_str (retval));
-                   delete_thread (find_thread_ptid (retval));
+                                        target_pid_to_str (retval).c_str ());
+                   delete_thread (find_thread_ptid (this, retval));
                    status->kind = TARGET_WAITKIND_SPURIOUS;
                    return retval;
                  }
@@ -2460,8 +2467,8 @@ wait_again:
 
                    /* If not in GDB's thread list, add it.  */
                    temp_ptid = ptid_t (pi->pid, temp_tid, 0);
-                   if (!in_thread_list (temp_ptid))
-                     add_thread (temp_ptid);
+                   if (!in_thread_list (this, temp_ptid))
+                     add_thread (this, temp_ptid);
 
                    status->kind = TARGET_WAITKIND_STOPPED;
                    status->value.sig = GDB_SIGNAL_0;
@@ -2472,40 +2479,12 @@ wait_again:
                wstat = (what << 8) | 0177;
                break;
              case PR_FAULTED:
-               switch (what) {
-               case FLTWATCH:
-                 wstat = (SIGTRAP << 8) | 0177;
-                 break;
-                 /* FIXME: use si_signo where possible.  */
-               case FLTPRIV:
-               case FLTILL:
-                 wstat = (SIGILL << 8) | 0177;
-                 break;
-               case FLTBPT:
-               case FLTTRACE:
-                 wstat = (SIGTRAP << 8) | 0177;
-                 break;
-               case FLTSTACK:
-               case FLTACCESS:
-               case FLTBOUNDS:
-                 wstat = (SIGSEGV << 8) | 0177;
-                 break;
-               case FLTIOVF:
-               case FLTIZDIV:
-               case FLTFPE:
-                 wstat = (SIGFPE << 8) | 0177;
-                 break;
-               case FLTPAGE:   /* Recoverable page fault */
-               default:        /* FIXME: use si_signo if possible for
-                                  fault.  */
-                 retval = ptid_t (-1);
-                 printf_filtered ("procfs:%d -- ", __LINE__);
-                 printf_filtered (_("child stopped for unknown reason:\n"));
-                 proc_prettyprint_why (why, what, 1);
-                 error (_("... giving up..."));
-                 break;
+               {
+                 int signo = pi->prstatus.pr_lwp.pr_info.si_signo;
+                 if (signo != 0)
+                   wstat = (signo << 8) | 0177;
                }
-               break;  /* case PR_FAULTED: */
+               break;
              default:  /* switch (why) unmatched */
                printf_filtered ("procfs:%d -- ", __LINE__);
                printf_filtered (_("child stopped for unknown reason:\n"));
@@ -2517,12 +2496,12 @@ wait_again:
                 threads database, add it.  */
              if (retval.pid () > 0
                  && retval != inferior_ptid
-                 && !in_thread_list (retval))
+                 && !in_thread_list (this, retval))
                {
                  /* We have a new thread.  We need to add it both to
                     GDB's list and to our own.  If we don't create a
                     procinfo, resume may be unhappy later.  */
-                 add_thread (retval);
+                 add_thread (this, retval);
                  if (find_procinfo (retval.pid (),
                                     retval.lwp ()) == NULL)
                    create_procinfo (retval.pid (),
@@ -2615,7 +2594,7 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
    File descriptors are also cached.  As they are a limited resource,
    we cannot hold onto them indefinitely.  However, as they are
    expensive to open, we don't want to throw them away
-   indescriminately either.  As a compromise, we will keep the file
+   indiscriminately either.  As a compromise, we will keep the file
    descriptors for the parent process, but discard any file
    descriptors we may have accumulated for the threads.
 
@@ -2772,7 +2751,7 @@ procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 /* Set up to trace signals in the child process.  */
 
 void
-procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
+procfs_target::pass_signals (gdb::array_view<const unsigned char> pass_signals)
 {
   sigset_t signals;
   procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
@@ -2783,7 +2762,7 @@ procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
   for (signo = 0; signo < NSIG; signo++)
     {
       int target_signo = gdb_signal_from_host (signo);
-      if (target_signo < numsigs && pass_signals[target_signo])
+      if (target_signo < pass_signals.size () && pass_signals[target_signo])
        prdelset (&signals, signo);
     }
 
@@ -2800,7 +2779,7 @@ procfs_target::files_info ()
 
   printf_filtered (_("\tUsing the running image of %s %s via /proc.\n"),
                   inf->attach_flag? "attached": "child",
-                  target_pid_to_str (inferior_ptid));
+                  target_pid_to_str (inferior_ptid).c_str ());
 }
 
 /* Make it die.  Wait for it to die.  Clean up after it.  Note: this
@@ -2875,8 +2854,8 @@ procfs_target::mourn_inferior ()
    whatever is necessary to make the child ready to be debugged, and
    then wait for the child to synchronize.  */
 
-static void
-procfs_init_inferior (struct target_ops *ops, int pid)
+void
+procfs_target::procfs_init_inferior (int pid)
 {
   procinfo *pi;
   int fail;
@@ -2884,8 +2863,8 @@ procfs_init_inferior (struct target_ops *ops, int pid)
 
   /* This routine called on the parent side (GDB side)
      after GDB forks the inferior.  */
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  if (!target_is_pushed (this))
+    push_target (this);
 
   pi = create_procinfo (pid, 0);
   if (pi == NULL)
@@ -2946,8 +2925,7 @@ procfs_init_inferior (struct target_ops *ops, int pid)
   /* We already have a main thread registered in the thread table at
      this point, but it didn't have any lwp info yet.  Notify the core
      about it.  This changes inferior_ptid as well.  */
-  thread_change_ptid (ptid_t (pid),
-                     ptid_t (pid, lwpid, 0));
+  thread_change_ptid (this, ptid_t (pid), ptid_t (pid, lwpid, 0));
 
   gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
 }
@@ -3114,9 +3092,9 @@ procfs_target::create_inferior (const char *exec_file,
   /* We have something that executes now.  We'll be running through
      the shell at this point (if startup-with-shell is true), but the
      pid shouldn't change.  */
-  add_thread_silent (ptid_t (pid));
+  add_thread_silent (this, ptid_t (pid));
 
-  procfs_init_inferior (this, pid);
+  procfs_init_inferior (pid);
 }
 
 /* An observer for the "inferior_created" event.  */
@@ -3133,8 +3111,9 @@ procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
 {
   ptid_t gdb_threadid = ptid_t (pi->pid, thread->tid, 0);
 
-  if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid))
-    add_thread (gdb_threadid);
+  thread_info *thr = find_thread_ptid (&the_procfs_target, gdb_threadid);
+  if (thr == NULL || thr->state == THREAD_EXITED)
+    add_thread (&the_procfs_target, gdb_threadid);
 
   return 0;
 }
@@ -3184,20 +3163,15 @@ procfs_target::thread_alive (ptid_t ptid)
   return true;
 }
 
-/* Convert PTID to a string.  Returns the string in a static
-   buffer.  */
+/* Convert PTID to a string.  */
 
-const char *
+std::string
 procfs_target::pid_to_str (ptid_t ptid)
 {
-  static char buf[80];
-
   if (ptid.lwp () == 0)
-    xsnprintf (buf, sizeof (buf), "process %d", ptid.pid ());
+    return string_printf ("process %d", ptid.pid ());
   else
-    xsnprintf (buf, sizeof (buf), "LWP %ld", ptid.lwp ());
-
-  return buf;
+    return string_printf ("LWP %ld", ptid.lwp ());
 }
 
 /* Accepts an integer PID; Returns a string representing a file that
@@ -3768,7 +3742,7 @@ procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
                            char *note_data, int *note_size,
                            enum gdb_signal stop_signal)
 {
-  struct regcache *regcache = get_thread_regcache (ptid);
+  struct regcache *regcache = get_thread_regcache (&the_procfs_target, ptid);
   gdb_gregset_t gregs;
   gdb_fpregset_t fpregs;
   unsigned long merged_pid;
This page took 0.029896 seconds and 4 git commands to generate.