2011-11-23 Thomas Klein <th.r.klein@web.de>
[deliverable/binutils-gdb.git] / gdb / nto-procfs.c
index 0b13d352ba0e1ba340557c0796b28e123298cb4f..38247755a1944938cde24da7fb029c6ad4b3a60d 100644 (file)
@@ -1,7 +1,8 @@
 /* Machine independent support for QNX Neutrino /proc (process file system)
 /* Machine independent support for QNX Neutrino /proc (process file system)
-   for GDB.  Written by Colin Burgess at QNX Software Systems Limited. 
+   for GDB.  Written by Colin Burgess at QNX Software Systems Limited.
 
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
 
    Contributed by QNX Software Systems Ltd.
 
 
    Contributed by QNX Software Systems Ltd.
 
@@ -9,7 +10,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,9 +19,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 
 
 #include "defs.h"
 
@@ -33,6 +32,7 @@
 #include "gdb_dirent.h"
 #include <sys/netmgr.h>
 
 #include "gdb_dirent.h"
 #include <sys/netmgr.h>
 
+#include "exceptions.h"
 #include "gdb_string.h"
 #include "gdbcore.h"
 #include "inferior.h"
 #include "gdb_string.h"
 #include "gdbcore.h"
 #include "inferior.h"
@@ -42,6 +42,7 @@
 #include "nto-tdep.h"
 #include "command.h"
 #include "regcache.h"
 #include "nto-tdep.h"
 #include "command.h"
 #include "regcache.h"
+#include "solib.h"
 
 #define NULL_PID               0
 #define _DEBUG_FLAG_TRACE      (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
 
 #define NULL_PID               0
 #define _DEBUG_FLAG_TRACE      (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
@@ -59,29 +60,21 @@ static void procfs_open (char *, int);
 
 static int procfs_can_run (void);
 
 
 static int procfs_can_run (void);
 
-static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
-
-static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
+static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
                               struct mem_attrib *attrib,
                               struct target_ops *);
 
                               struct mem_attrib *attrib,
                               struct target_ops *);
 
-static void procfs_fetch_registers (int);
-
-static void notice_signals (void);
-
 static void init_procfs_ops (void);
 
 static ptid_t do_attach (ptid_t ptid);
 
 static int procfs_can_use_hw_breakpoint (int, int, int);
 
 static void init_procfs_ops (void);
 
 static ptid_t do_attach (ptid_t ptid);
 
 static int procfs_can_use_hw_breakpoint (int, int, int);
 
-static int procfs_insert_hw_breakpoint (CORE_ADDR, char *);
-
-static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *);
+static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type,
+                                       struct expression *cond);
 
 
-static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
-
-static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
+static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type,
+                                       struct expression *cond);
 
 static int procfs_stopped_by_watchpoint (void);
 
 
 static int procfs_stopped_by_watchpoint (void);
 
@@ -106,7 +99,7 @@ nto_node (void)
 
   node = netmgr_strtond (nto_procfs_path, 0);
   if (node == -1)
 
   node = netmgr_strtond (nto_procfs_path, 0);
   if (node == -1)
-    error ("Lost the QNX node.  Debug session probably over.");
+    error (_("Lost the QNX node.  Debug session probably over."));
 
   return (node);
 }
 
   return (node);
 }
@@ -129,6 +122,7 @@ procfs_open (char *arg, int from_tty)
   char buffer[50];
   int fd, total_size;
   procfs_sysinfo *sysinfo;
   char buffer[50];
   int fd, total_size;
   procfs_sysinfo *sysinfo;
+  struct cleanup *cleanups;
 
   nto_is_nto_target = procfs_is_nto_target;
 
 
   nto_is_nto_target = procfs_is_nto_target;
 
@@ -171,16 +165,16 @@ procfs_open (char *arg, int from_tty)
     {
       printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
                       safe_strerror (errno));
     {
       printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
                       safe_strerror (errno));
-      error ("Invalid procfs arg");
+      error (_("Invalid procfs arg"));
     }
     }
+  cleanups = make_cleanup_close (fd);
 
   sysinfo = (void *) buffer;
   if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
     {
       printf_filtered ("Error getting size: %d (%s)\n", errno,
                       safe_strerror (errno));
 
   sysinfo = (void *) buffer;
   if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
     {
       printf_filtered ("Error getting size: %d (%s)\n", errno,
                       safe_strerror (errno));
-      close (fd);
-      error ("Devctl failed.");
+      error (_("Devctl failed."));
     }
   else
     {
     }
   else
     {
@@ -190,8 +184,7 @@ procfs_open (char *arg, int from_tty)
        {
          printf_filtered ("Memory error: %d (%s)\n", errno,
                           safe_strerror (errno));
        {
          printf_filtered ("Memory error: %d (%s)\n", errno,
                           safe_strerror (errno));
-         close (fd);
-         error ("alloca failed.");
+         error (_("alloca failed."));
        }
       else
        {
        }
       else
        {
@@ -199,21 +192,18 @@ procfs_open (char *arg, int from_tty)
            {
              printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
                               safe_strerror (errno));
            {
              printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
                               safe_strerror (errno));
-             close (fd);
-             error ("Devctl failed.");
+             error (_("Devctl failed."));
            }
          else
            {
              if (sysinfo->type !=
            }
          else
            {
              if (sysinfo->type !=
-                 nto_map_arch_to_cputype (TARGET_ARCHITECTURE->arch_name))
-               {
-                 close (fd);
-                 error ("Invalid target CPU.");
-               }
+                 nto_map_arch_to_cputype (gdbarch_bfd_arch_info
+                                          (target_gdbarch)->arch_name))
+               error (_("Invalid target CPU."));
            }
        }
     }
            }
        }
     }
-  close (fd);
+  do_cleanups (cleanups);
   printf_filtered ("Debugging using %s\n", nto_procfs_path);
 }
 
   printf_filtered ("Debugging using %s\n", nto_procfs_path);
 }
 
@@ -228,46 +218,149 @@ procfs_set_thread (ptid_t ptid)
 
 /*  Return nonzero if the thread TH is still alive.  */
 static int
 
 /*  Return nonzero if the thread TH is still alive.  */
 static int
-procfs_thread_alive (ptid_t ptid)
+procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   pid_t tid;
 {
   pid_t tid;
+  pid_t pid;
+  procfs_status status;
+  int err;
 
   tid = ptid_get_tid (ptid);
 
   tid = ptid_get_tid (ptid);
-  if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK)
-    return 1;
-  return 0;
+  pid = ptid_get_pid (ptid);
+
+  if (kill (pid, 0) == -1)
+    return 0;
+
+  status.tid = tid;
+  if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS,
+                    &status, sizeof (status), 0)) != EOK)
+    return 0;
+
+  /* Thread is alive or dead but not yet joined,
+     or dead and there is an alive (or dead unjoined) thread with
+     higher tid.
+
+     If the tid is not the same as requested, requested tid is dead.  */
+  return (status.tid == tid) && (status.state != STATE_DEAD);
+}
+
+static void
+update_thread_private_data_name (struct thread_info *new_thread,
+                                const char *newname)
+{
+  int newnamelen;
+  struct private_thread_info *pti;
+
+  gdb_assert (newname != NULL);
+  gdb_assert (new_thread != NULL);
+  newnamelen = strlen (newname);
+  if (!new_thread->private)
+    {
+      new_thread->private = xmalloc (offsetof (struct private_thread_info,
+                                              name)
+                                    + newnamelen + 1);
+      memcpy (new_thread->private->name, newname, newnamelen + 1);
+    }
+  else if (strcmp (newname, new_thread->private->name) != 0)
+    {
+      /* Reallocate if neccessary.  */
+      int oldnamelen = strlen (new_thread->private->name);
+
+      if (oldnamelen < newnamelen)
+       new_thread->private = xrealloc (new_thread->private,
+                                       offsetof (struct private_thread_info,
+                                                 name)
+                                       + newnamelen + 1);
+      memcpy (new_thread->private->name, newname, newnamelen + 1);
+    }
+}
+
+static void 
+update_thread_private_data (struct thread_info *new_thread, 
+                           pthread_t tid, int state, int flags)
+{
+  struct private_thread_info *pti;
+  procfs_info pidinfo;
+  struct _thread_name *tn;
+  procfs_threadctl tctl;
+
+#if _NTO_VERSION > 630
+  gdb_assert (new_thread != NULL);
+
+  if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo,
+             sizeof(pidinfo), 0) != EOK)
+    return;
+
+  memset (&tctl, 0, sizeof (tctl));
+  tctl.cmd = _NTO_TCTL_NAME;
+  tn = (struct _thread_name *) (&tctl.data);
+
+  /* Fetch name for the given thread.  */
+  tctl.tid = tid;
+  tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn);
+  tn->new_name_len = -1; /* Getting, not setting.  */
+  if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK)
+    tn->name_buf[0] = '\0';
+
+  tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0';
+
+  update_thread_private_data_name (new_thread, tn->name_buf);
+
+  pti = (struct private_thread_info *) new_thread->private;
+  pti->tid = tid;
+  pti->state = state;
+  pti->flags = flags;
+#endif /* _NTO_VERSION */
 }
 
 void
 }
 
 void
-procfs_find_new_threads (void)
+procfs_find_new_threads (struct target_ops *ops)
 {
   procfs_status status;
   pid_t pid;
   ptid_t ptid;
 {
   procfs_status status;
   pid_t pid;
   ptid_t ptid;
+  pthread_t tid;
+  struct thread_info *new_thread;
 
   if (ctl_fd == -1)
     return;
 
   pid = ptid_get_pid (inferior_ptid);
 
 
   if (ctl_fd == -1)
     return;
 
   pid = ptid_get_pid (inferior_ptid);
 
-  for (status.tid = 1;; ++status.tid)
+  status.tid = 1;
+
+  for (tid = 1;; ++tid)
     {
     {
-      if (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0)
-         != EOK && status.tid != 0)
+      if (status.tid == tid 
+         && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0)
+             != EOK))
        break;
        break;
-      ptid = ptid_build (pid, 0, status.tid);
-      if (!in_thread_list (ptid))
-       add_thread (ptid);
+      if (status.tid != tid)
+       /* The reason why this would not be equal is that devctl might have 
+          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);
+      if (!new_thread)
+       new_thread = add_thread (ptid);
+      update_thread_private_data (new_thread, tid, status.state, 0);
+      status.tid++;
     }
   return;
 }
 
     }
   return;
 }
 
+static void
+do_closedir_cleanup (void *dir)
+{
+  closedir (dir);
+}
+
 void
 procfs_pidlist (char *args, int from_tty)
 {
   DIR *dp = NULL;
   struct dirent *dirp = NULL;
 void
 procfs_pidlist (char *args, int from_tty)
 {
   DIR *dp = NULL;
   struct dirent *dirp = NULL;
-  int fd = -1;
   char buf[512];
   procfs_info *pidinfo = NULL;
   procfs_debuginfo *info = NULL;
   char buf[512];
   procfs_info *pidinfo = NULL;
   procfs_debuginfo *info = NULL;
@@ -275,6 +368,7 @@ procfs_pidlist (char *args, int from_tty)
   pid_t num_threads = 0;
   pid_t pid;
   char name[512];
   pid_t num_threads = 0;
   pid_t pid;
   char name[512];
+  struct cleanup *cleanups;
 
   dp = opendir (nto_procfs_path);
   if (dp == NULL)
 
   dp = opendir (nto_procfs_path);
   if (dp == NULL)
@@ -284,18 +378,23 @@ procfs_pidlist (char *args, int from_tty)
       return;
     }
 
       return;
     }
 
+  cleanups = make_cleanup (do_closedir_cleanup, dp);
+
   /* Start scan at first pid.  */
   rewinddir (dp);
 
   do
     {
   /* Start scan at first pid.  */
   rewinddir (dp);
 
   do
     {
+      int fd;
+      struct cleanup *inner_cleanup;
+
       /* Get the right pid and procfs path for the pid.  */
       do
        {
          dirp = readdir (dp);
          if (dirp == NULL)
            {
       /* Get the right pid and procfs path for the pid.  */
       do
        {
          dirp = readdir (dp);
          if (dirp == NULL)
            {
-             closedir (dp);
+             do_cleanups (cleanups);
              return;
            }
          snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
              return;
            }
          snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
@@ -303,15 +402,16 @@ procfs_pidlist (char *args, int from_tty)
        }
       while (pid == 0);
 
        }
       while (pid == 0);
 
-      /* Open the procfs path. */
+      /* Open the procfs path.  */
       fd = open (buf, O_RDONLY);
       if (fd == -1)
        {
          fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
                              buf, errno, safe_strerror (errno));
       fd = open (buf, O_RDONLY);
       if (fd == -1)
        {
          fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
                              buf, errno, safe_strerror (errno));
-         closedir (dp);
+         do_cleanups (cleanups);
          return;
        }
          return;
        }
+      inner_cleanup = make_cleanup_close (fd);
 
       pidinfo = (procfs_info *) buf;
       if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
 
       pidinfo = (procfs_info *) buf;
       if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
@@ -339,12 +439,12 @@ procfs_pidlist (char *args, int from_tty)
          if (status->tid != 0)
            printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
        }
          if (status->tid != 0)
            printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
        }
-      close (fd);
+
+      do_cleanups (inner_cleanup);
     }
   while (dirp != NULL);
 
     }
   while (dirp != NULL);
 
-  close (fd);
-  closedir (dp);
+  do_cleanups (cleanups);
   return;
 }
 
   return;
 }
 
@@ -477,14 +577,14 @@ procfs_meminfo (char *args, int from_tty)
                       printme.text.addr);
       printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
       printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
                       printme.text.addr);
       printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
       printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
-      printf_filtered ("\t\toffset=%016llx\n", printme.text.offset);
+      printf_filtered ("\t\toffset=%s\n", phex (printme.text.offset, 8));
       if (printme.data.size)
        {
          printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
                           printme.data.addr);
          printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
          printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
       if (printme.data.size)
        {
          printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
                           printme.data.addr);
          printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
          printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
-         printf_filtered ("\t\toffset=%016llx\n", printme.data.offset);
+         printf_filtered ("\t\toffset=%s\n", phex (printme.data.offset, 8));
        }
       printf_filtered ("\tdev=0x%x\n", printme.dev);
       printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
        }
       printf_filtered ("\tdev=0x%x\n", printme.dev);
       printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
@@ -497,12 +597,15 @@ procfs_meminfo (char *args, int from_tty)
 static void
 procfs_files_info (struct target_ops *ignore)
 {
 static void
 procfs_files_info (struct target_ops *ignore)
 {
+  struct inferior *inf = current_inferior ();
+
   printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
   printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
-                    attach_flag ? "attached" : "child",
+                    inf->attach_flag ? "attached" : "child",
                     target_pid_to_str (inferior_ptid), nto_procfs_path);
 }
 
                     target_pid_to_str (inferior_ptid), nto_procfs_path);
 }
 
-/* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
+/* Mark our target-struct as eligible for stray "run" and "attach"
+   commands.  */
 static int
 procfs_can_run (void)
 {
 static int
 procfs_can_run (void)
 {
@@ -511,18 +614,16 @@ procfs_can_run (void)
 
 /* Attach to process PID, then initialize for debugging it.  */
 static void
 
 /* Attach to process PID, then initialize for debugging it.  */
 static void
-procfs_attach (char *args, int from_tty)
+procfs_attach (struct target_ops *ops, char *args, int from_tty)
 {
   char *exec_file;
   int pid;
 {
   char *exec_file;
   int pid;
+  struct inferior *inf;
 
 
-  if (!args)
-    error_no_arg ("process-id to attach");
-
-  pid = atoi (args);
+  pid = parse_pid_to_attach (args);
 
   if (pid == getpid ())
 
   if (pid == getpid ())
-    error ("Attaching GDB to itself is not a good idea...");
+    error (_("Attaching GDB to itself is not a good idea..."));
 
   if (from_tty)
     {
 
   if (from_tty)
     {
@@ -538,16 +639,20 @@ procfs_attach (char *args, int from_tty)
       gdb_flush (gdb_stdout);
     }
   inferior_ptid = do_attach (pid_to_ptid (pid));
       gdb_flush (gdb_stdout);
     }
   inferior_ptid = do_attach (pid_to_ptid (pid));
-  push_target (&procfs_ops);
+  inf = current_inferior ();
+  inferior_appeared (inf, pid);
+  inf->attach_flag = 1;
+
+  push_target (ops);
+
+  procfs_find_new_threads (ops);
 }
 
 static void
 procfs_post_attach (pid_t pid)
 {
 }
 
 static void
 procfs_post_attach (pid_t pid)
 {
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
   if (exec_bfd)
   if (exec_bfd)
-    SOLIB_CREATE_INFERIOR_HOOK (pid);
-#endif
+    solib_create_inferior_hook (0);
 }
 
 static ptid_t
 }
 
 static ptid_t
@@ -560,10 +665,10 @@ do_attach (ptid_t ptid)
   snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
   ctl_fd = open (path, O_RDWR);
   if (ctl_fd == -1)
   snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
   ctl_fd = open (path, O_RDWR);
   if (ctl_fd == -1)
-    error ("Couldn't open proc file %s, error %d (%s)", path, errno,
+    error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
           safe_strerror (errno));
   if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
           safe_strerror (errno));
   if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
-    error ("Couldn't stop process");
+    error (_("Couldn't stop process"));
 
   /* Define a sigevent for process stopped notification.  */
   event.sigev_notify = SIGEV_SIGNAL_THREAD;
 
   /* Define a sigevent for process stopped notification.  */
   event.sigev_notify = SIGEV_SIGNAL_THREAD;
@@ -576,9 +681,8 @@ 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 (), PIDGET (ptid), 0, SIGCONT, 0, 0);
   if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
       && status.flags & _DEBUG_FLAG_STOPPED)
     SignalKill (nto_node (), PIDGET (ptid), 0, SIGCONT, 0, 0);
-  attach_flag = 1;
   nto_init_solib_absolute_prefix ();
   nto_init_solib_absolute_prefix ();
-  return ptid;
+  return ptid_build (PIDGET (ptid), 0, status.tid);
 }
 
 /* Ask the user what to do when an interrupt is received.  */
 }
 
 /* Ask the user what to do when an interrupt is received.  */
@@ -587,11 +691,11 @@ interrupt_query (void)
 {
   target_terminal_ours ();
 
 {
   target_terminal_ours ();
 
-  if (query ("Interrupted while waiting for the program.\n\
-Give up (and stop debugging it)? "))
+  if (query (_("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? ")))
     {
       target_mourn_inferior ();
     {
       target_mourn_inferior ();
-      throw_exception (RETURN_QUIT);
+      deprecated_throw_reason (RETURN_QUIT);
     }
 
   target_terminal_inferior ();
     }
 
   target_terminal_inferior ();
@@ -612,11 +716,12 @@ nto_interrupt (int signo)
   /* If this doesn't work, try more severe steps.  */
   signal (signo, nto_interrupt_twice);
 
   /* If this doesn't work, try more severe steps.  */
   signal (signo, nto_interrupt_twice);
 
-  target_stop ();
+  target_stop (inferior_ptid);
 }
 
 static ptid_t
 }
 
 static ptid_t
-procfs_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+procfs_wait (struct target_ops *ops,
+            ptid_t ptid, struct target_waitstatus *ourstatus, int options)
 {
   sigset_t set;
   siginfo_t info;
 {
   sigset_t set;
   siginfo_t info;
@@ -711,14 +816,15 @@ procfs_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
        }
     }
 
        }
     }
 
-  return inferior_ptid;
+  return ptid_build (status.pid, 0, status.tid);
 }
 
 /* Read the current values of the inferior's registers, both the
    general register set and floating point registers (if supported)
    and update gdb's idea of their current values.  */
 static void
 }
 
 /* Read the current values of the inferior's registers, both the
    general register set and floating point registers (if supported)
    and update gdb's idea of their current values.  */
 static void
-procfs_fetch_registers (int regno)
+procfs_fetch_registers (struct target_ops *ops,
+                       struct regcache *regcache, int regno)
 {
   union
   {
 {
   union
   {
@@ -731,13 +837,13 @@ procfs_fetch_registers (int regno)
 
   procfs_set_thread (inferior_ptid);
   if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
 
   procfs_set_thread (inferior_ptid);
   if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
-    nto_supply_gregset ((char *) &reg.greg);
+    nto_supply_gregset (regcache, (char *) &reg.greg);
   if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
       == EOK)
   if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
       == EOK)
-    nto_supply_fpregset ((char *) &reg.fpreg);
+    nto_supply_fpregset (regcache, (char *) &reg.fpreg);
   if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
       == EOK)
   if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
       == EOK)
-    nto_supply_altregset ((char *) &reg.altreg);
+    nto_supply_altregset (regcache, (char *) &reg.altreg);
 }
 
 /* Copy LEN bytes to/from inferior's memory starting at MEMADDR
 }
 
 /* Copy LEN bytes to/from inferior's memory starting at MEMADDR
@@ -749,7 +855,7 @@ procfs_fetch_registers (int regno)
    doesn't allow memory operations to cross below us in the target stack
    anyway.  */
 static int
    doesn't allow memory operations to cross below us in the target stack
    anyway.  */
 static int
-procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
+procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
                    struct mem_attrib *attrib, struct target_ops *target)
 {
   int nbytes = 0;
                    struct mem_attrib *attrib, struct target_ops *target)
 {
   int nbytes = 0;
@@ -771,9 +877,10 @@ procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
    on signals, etc.  We'd better not have left any breakpoints
    in the program or it'll die when it hits one.  */
 static void
    on signals, etc.  We'd better not have left any breakpoints
    in the program or it'll die when it hits one.  */
 static void
-procfs_detach (char *args, int from_tty)
+procfs_detach (struct target_ops *ops, char *args, int from_tty)
 {
   int siggnal = 0;
 {
   int siggnal = 0;
+  int pid;
 
   if (from_tty)
     {
 
   if (from_tty)
     {
@@ -792,9 +899,11 @@ procfs_detach (char *args, int from_tty)
 
   close (ctl_fd);
   ctl_fd = -1;
 
   close (ctl_fd);
   ctl_fd = -1;
-  init_thread_list ();
+
+  pid = ptid_get_pid (inferior_ptid);
   inferior_ptid = null_ptid;
   inferior_ptid = null_ptid;
-  attach_flag = 0;
+  detach_inferior (pid);
+  init_thread_list ();
   unpush_target (&procfs_ops); /* Pop out of handling an inferior.  */
 }
 
   unpush_target (&procfs_ops); /* Pop out of handling an inferior.  */
 }
 
@@ -813,34 +922,42 @@ procfs_breakpoint (CORE_ADDR addr, int type, int size)
 }
 
 static int
 }
 
 static int
-procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_insert_breakpoint (struct gdbarch *gdbarch,
+                         struct bp_target_info *bp_tgt)
 {
 {
-  return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
+  return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
 }
 
 static int
 }
 
 static int
-procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_remove_breakpoint (struct gdbarch *gdbarch,
+                         struct bp_target_info *bp_tgt)
 {
 {
-  return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
+  return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
 }
 
 static int
 }
 
 static int
-procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_insert_hw_breakpoint (struct gdbarch *gdbarch,
+                            struct bp_target_info *bp_tgt)
 {
 {
-  return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
+  return procfs_breakpoint (bp_tgt->placed_address,
+                           _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
 }
 
 static int
 }
 
 static int
-procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_remove_hw_breakpoint (struct gdbarch *gdbarch,
+                            struct bp_target_info *bp_tgt)
 {
 {
-  return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
+  return procfs_breakpoint (bp_tgt->placed_address,
+                           _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
 }
 
 static void
 }
 
 static void
-procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+procfs_resume (struct target_ops *ops,
+              ptid_t ptid, int step, enum target_signal signo)
 {
   int signal_to_pass;
   procfs_status status;
 {
   int signal_to_pass;
   procfs_status status;
+  sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
 
   if (ptid_equal (inferior_ptid, null_ptid))
     return;
 
   if (ptid_equal (inferior_ptid, null_ptid))
     return;
@@ -852,22 +969,20 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
   if (step)
     run.flags |= _DEBUG_RUN_STEP;
 
   if (step)
     run.flags |= _DEBUG_RUN_STEP;
 
-  sigemptyset ((sigset_t *) &run.fault);
-  sigaddset ((sigset_t *) &run.fault, FLTBPT);
-  sigaddset ((sigset_t *) &run.fault, FLTTRACE);
-  sigaddset ((sigset_t *) &run.fault, FLTILL);
-  sigaddset ((sigset_t *) &run.fault, FLTPRIV);
-  sigaddset ((sigset_t *) &run.fault, FLTBOUNDS);
-  sigaddset ((sigset_t *) &run.fault, FLTIOVF);
-  sigaddset ((sigset_t *) &run.fault, FLTIZDIV);
-  sigaddset ((sigset_t *) &run.fault, FLTFPE);
+  sigemptyset (run_fault);
+  sigaddset (run_fault, FLTBPT);
+  sigaddset (run_fault, FLTTRACE);
+  sigaddset (run_fault, FLTILL);
+  sigaddset (run_fault, FLTPRIV);
+  sigaddset (run_fault, FLTBOUNDS);
+  sigaddset (run_fault, FLTIOVF);
+  sigaddset (run_fault, FLTIZDIV);
+  sigaddset (run_fault, FLTFPE);
   /* Peter V will be changing this at some point.  */
   /* Peter V will be changing this at some point.  */
-  sigaddset ((sigset_t *) &run.fault, FLTPAGE);
+  sigaddset (run_fault, FLTPAGE);
 
   run.flags |= _DEBUG_RUN_ARM;
 
 
   run.flags |= _DEBUG_RUN_ARM;
 
-  sigemptyset (&run.trace);
-  notice_signals ();
   signal_to_pass = target_signal_to_host (signo);
 
   if (signal_to_pass)
   signal_to_pass = target_signal_to_host (signo);
 
   if (signal_to_pass)
@@ -882,7 +997,7 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
                          signal_to_pass, 0, 0);
              run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
            }
                          signal_to_pass, 0, 0);
              run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
            }
-         else                  /* Let it kill the program without telling us.  */
+         else          /* Let it kill the program without telling us.  */
            sigdelset (&run.trace, signal_to_pass);
        }
     }
            sigdelset (&run.trace, signal_to_pass);
        }
     }
@@ -892,13 +1007,13 @@ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
   errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
   if (errno != EOK)
     {
   errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
   if (errno != EOK)
     {
-      perror ("run error!\n");
+      perror (_("run error!\n"));
       return;
     }
 }
 
 static void
       return;
     }
 }
 
 static void
-procfs_mourn_inferior (void)
+procfs_mourn_inferior (struct target_ops *ops)
 {
   if (!ptid_equal (inferior_ptid, null_ptid))
     {
 {
   if (!ptid_equal (inferior_ptid, null_ptid))
     {
@@ -909,7 +1024,6 @@ procfs_mourn_inferior (void)
   init_thread_list ();
   unpush_target (&procfs_ops);
   generic_mourn_inferior ();
   init_thread_list ();
   unpush_target (&procfs_ops);
   generic_mourn_inferior ();
-  attach_flag = 0;
 }
 
 /* This function breaks up an argument string into an argument
 }
 
 /* This function breaks up an argument string into an argument
@@ -973,16 +1087,18 @@ breakup_args (char *scratch, char **argv)
 }
 
 static void
 }
 
 static void
-procfs_create_inferior (char *exec_file, char *allargs, char **env,
-                       int from_tty)
+procfs_create_inferior (struct target_ops *ops, char *exec_file,
+                       char *allargs, char **env, int from_tty)
 {
   struct inheritance inherit;
   pid_t pid;
   int flags, errn;
   char **argv, *args;
 {
   struct inheritance inherit;
   pid_t pid;
   int flags, errn;
   char **argv, *args;
-  char *in = "", *out = "", *err = "";
+  const char *in = "", *out = "", *err = "";
   int fd, fds[3];
   sigset_t set;
   int fd, fds[3];
   sigset_t set;
+  const char *inferior_io_terminal = get_inferior_io_terminal ();
+  struct inferior *inf;
 
   argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
                  sizeof (*argv));
 
   argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
                  sizeof (*argv));
@@ -1065,7 +1181,7 @@ procfs_create_inferior (char *exec_file, char *allargs, char **env,
   sigprocmask (SIG_BLOCK, &set, NULL);
 
   if (pid == -1)
   sigprocmask (SIG_BLOCK, &set, NULL);
 
   if (pid == -1)
-    error ("Error spawning %s: %d (%s)", argv[0], errno,
+    error (_("Error spawning %s: %d (%s)"), argv[0], errno,
           safe_strerror (errno));
 
   if (fds[0] != STDIN_FILENO)
           safe_strerror (errno));
 
   if (fds[0] != STDIN_FILENO)
@@ -1076,8 +1192,12 @@ procfs_create_inferior (char *exec_file, char *allargs, char **env,
     close (fds[2]);
 
   inferior_ptid = do_attach (pid_to_ptid (pid));
     close (fds[2]);
 
   inferior_ptid = do_attach (pid_to_ptid (pid));
+  procfs_find_new_threads (ops);
+
+  inf = current_inferior ();
+  inferior_appeared (inf, pid);
+  inf->attach_flag = 0;
 
 
-  attach_flag = 0;
   flags = _DEBUG_FLAG_KLC;     /* Kill-on-Last-Close flag.  */
   errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
   if (errn != EOK)
   flags = _DEBUG_FLAG_KLC;     /* Kill-on-Last-Close flag.  */
   errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
   if (errn != EOK)
@@ -1086,26 +1206,22 @@ procfs_create_inferior (char *exec_file, char *allargs, char **env,
       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
          errn, strerror(errn) ); */
     }
       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
          errn, strerror(errn) ); */
     }
-  push_target (&procfs_ops);
+  push_target (ops);
   target_terminal_init ();
 
   target_terminal_init ();
 
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
   if (exec_bfd != NULL
       || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
   if (exec_bfd != NULL
       || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
-    SOLIB_CREATE_INFERIOR_HOOK (pid);
-#endif
-  stop_soon = 0;
-  proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
+    solib_create_inferior_hook (0);
 }
 
 static void
 }
 
 static void
-procfs_stop (void)
+procfs_stop (ptid_t ptid)
 {
   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
 }
 
 static void
 {
   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
 }
 
 static void
-procfs_kill_inferior (void)
+procfs_kill_inferior (struct target_ops *ops)
 {
   target_mourn_inferior ();
 }
 {
   target_mourn_inferior ();
 }
@@ -1113,7 +1229,7 @@ procfs_kill_inferior (void)
 /* Store register REGNO, or all registers if REGNO == -1, from the contents
    of REGISTERS.  */
 static void
 /* Store register REGNO, or all registers if REGNO == -1, from the contents
    of REGISTERS.  */
 static void
-procfs_prepare_to_store (void)
+procfs_prepare_to_store (struct regcache *regcache)
 {
 }
 
 {
 }
 
@@ -1144,14 +1260,15 @@ get_regset (int regset, char *buf, int bufsize, int *regsize)
     default:
       return -1;
     }
     default:
       return -1;
     }
-  if (devctl (ctl_fd, dev_get, &buf, bufsize, regsize) != EOK)
+  if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK)
     return -1;
 
   return dev_set;
 }
 
 void
     return -1;
 
   return dev_set;
 }
 
 void
-procfs_store_registers (int regno)
+procfs_store_registers (struct target_ops *ops,
+                       struct regcache *regcache, int regno)
 {
   union
   {
 {
   union
   {
@@ -1177,7 +1294,7 @@ procfs_store_registers (int regno)
          if (dev_set == -1)
            continue;
 
          if (dev_set == -1)
            continue;
 
-         if (nto_regset_fill (regset, (char *) &reg) == -1)
+         if (nto_regset_fill (regcache, regset, (char *) &reg) == -1)
            continue;
 
          err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
            continue;
 
          err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
@@ -1197,12 +1314,13 @@ procfs_store_registers (int regno)
       if (dev_set == -1)
        return;
 
       if (dev_set == -1)
        return;
 
-      len = nto_register_area (regno, regset, &off);
+      len = nto_register_area (get_regcache_arch (regcache),
+                              regno, regset, &off);
 
       if (len < 1)
        return;
 
 
       if (len < 1)
        return;
 
-      regcache_raw_collect (current_regcache, regno, (char *) &reg + off);
+      regcache_raw_collect (regcache, regno, (char *) &reg + off);
 
       err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
       if (err != EOK)
 
       err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
       if (err != EOK)
@@ -1212,34 +1330,23 @@ procfs_store_registers (int regno)
     }
 }
 
     }
 }
 
+/* Set list of signals to be handled in the target.  */
+
 static void
 static void
-notice_signals (void)
+procfs_pass_signals (int numsigs, unsigned char *pass_signals)
 {
   int signo;
 
 {
   int signo;
 
+  sigfillset (&run.trace);
+
   for (signo = 1; signo < NSIG; signo++)
     {
   for (signo = 1; signo < NSIG; signo++)
     {
-      if (signal_stop_state (target_signal_from_host (signo)) == 0
-         && signal_print_state (target_signal_from_host (signo)) == 0
-         && signal_pass_state (target_signal_from_host (signo)) == 1)
-       sigdelset (&run.trace, signo);
-      else
-       sigaddset (&run.trace, signo);
+      int target_signo = target_signal_from_host (signo);
+      if (target_signo < numsigs && pass_signals[target_signo])
+        sigdelset (&run.trace, signo);
     }
 }
 
     }
 }
 
-/* When the user changes the state of gdb's signal handling via the
-   "handle" command, this function gets called to see if any change
-   in the /proc interface is required.  It is also called internally
-   by other /proc interface functions to initialize the state of
-   the traced signal set.  */
-static void
-procfs_notice_signals (ptid_t ptid)
-{
-  sigemptyset (&run.trace);
-  notice_signals ();
-}
-
 static struct tidinfo *
 procfs_thread_info (pid_t pid, short tid)
 {
 static struct tidinfo *
 procfs_thread_info (pid_t pid, short tid)
 {
@@ -1248,7 +1355,7 @@ procfs_thread_info (pid_t pid, short tid)
 }
 
 char *
 }
 
 char *
-procfs_pid_to_str (ptid_t ptid)
+procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   static char buf[1024];
   int pid, tid, n;
 {
   static char buf[1024];
   int pid, tid, n;
@@ -1304,19 +1411,20 @@ init_procfs_ops (void)
   procfs_ops.to_create_inferior = procfs_create_inferior;
   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
   procfs_ops.to_can_run = procfs_can_run;
   procfs_ops.to_create_inferior = procfs_create_inferior;
   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
   procfs_ops.to_can_run = procfs_can_run;
-  procfs_ops.to_notice_signals = procfs_notice_signals;
+  procfs_ops.to_pass_signals = procfs_pass_signals;
   procfs_ops.to_thread_alive = procfs_thread_alive;
   procfs_ops.to_find_new_threads = procfs_find_new_threads;
   procfs_ops.to_pid_to_str = procfs_pid_to_str;
   procfs_ops.to_stop = procfs_stop;
   procfs_ops.to_stratum = process_stratum;
   procfs_ops.to_thread_alive = procfs_thread_alive;
   procfs_ops.to_find_new_threads = procfs_find_new_threads;
   procfs_ops.to_pid_to_str = procfs_pid_to_str;
   procfs_ops.to_stop = procfs_stop;
   procfs_ops.to_stratum = process_stratum;
-  procfs_ops.to_has_all_memory = 1;
-  procfs_ops.to_has_memory = 1;
-  procfs_ops.to_has_stack = 1;
-  procfs_ops.to_has_registers = 1;
-  procfs_ops.to_has_execution = 1;
+  procfs_ops.to_has_all_memory = default_child_has_all_memory;
+  procfs_ops.to_has_memory = default_child_has_memory;
+  procfs_ops.to_has_stack = default_child_has_stack;
+  procfs_ops.to_has_registers = default_child_has_registers;
+  procfs_ops.to_has_execution = default_child_has_execution;
   procfs_ops.to_magic = OPS_MAGIC;
   procfs_ops.to_have_continuable_watchpoint = 1;
   procfs_ops.to_magic = OPS_MAGIC;
   procfs_ops.to_have_continuable_watchpoint = 1;
+  procfs_ops.to_extra_thread_info = nto_extra_thread_info;
 }
 
 #define OSTYPE_NTO 1
 }
 
 #define OSTYPE_NTO 1
@@ -1335,15 +1443,15 @@ _initialize_procfs (void)
   sigaddset (&set, SIGUSR1);
   sigprocmask (SIG_BLOCK, &set, NULL);
 
   sigaddset (&set, SIGUSR1);
   sigprocmask (SIG_BLOCK, &set, NULL);
 
-  /* Set up trace and fault sets, as gdb expects them.  */
-  sigemptyset (&run.trace);
+  /* Initially, make sure all signals are reported.  */
+  sigfillset (&run.trace);
 
   /* Stuff some information.  */
   nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
   nto_cpuinfo_valid = 1;
 
 
   /* Stuff some information.  */
   nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
   nto_cpuinfo_valid = 1;
 
-  add_info ("pidlist", procfs_pidlist, "pidlist");
-  add_info ("meminfo", procfs_meminfo, "memory information");
+  add_info ("pidlist", procfs_pidlist, _("pidlist"));
+  add_info ("meminfo", procfs_meminfo, _("memory information"));
 
   nto_is_nto_target = procfs_is_nto_target;
 }
 
   nto_is_nto_target = procfs_is_nto_target;
 }
@@ -1373,7 +1481,7 @@ procfs_hw_watchpoint (int addr, int len, int type)
   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
   if (errno != EOK)
     {
   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
   if (errno != EOK)
     {
-      perror ("Failed to set hardware watchpoint");
+      perror (_("Failed to set hardware watchpoint"));
       return -1;
     }
   return 0;
       return -1;
     }
   return 0;
@@ -1386,13 +1494,15 @@ procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
 }
 
 static int
 }
 
 static int
-procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
+procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type,
+                            struct expression *cond)
 {
   return procfs_hw_watchpoint (addr, -1, type);
 }
 
 static int
 {
   return procfs_hw_watchpoint (addr, -1, type);
 }
 
 static int
-procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
+procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type,
+                            struct expression *cond)
 {
   return procfs_hw_watchpoint (addr, len, type);
 }
 {
   return procfs_hw_watchpoint (addr, len, type);
 }
This page took 0.03823 seconds and 4 git commands to generate.