GDB (API)
/home/stan/gdb/src/gdb/nto-procfs.c
Go to the documentation of this file.
00001 /* Machine independent support for QNX Neutrino /proc (process file system)
00002    for GDB.  Written by Colin Burgess at QNX Software Systems Limited.
00003 
00004    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00005 
00006    Contributed by QNX Software Systems Ltd.
00007 
00008    This file is part of GDB.
00009 
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 3 of the License, or
00013    (at your option) any later version.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License
00021    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00022 
00023 #include "defs.h"
00024 
00025 #include <fcntl.h>
00026 #include <spawn.h>
00027 #include <sys/debug.h>
00028 #include <sys/procfs.h>
00029 #include <sys/neutrino.h>
00030 #include <sys/syspage.h>
00031 #include "gdb_dirent.h"
00032 #include <sys/netmgr.h>
00033 
00034 #include "exceptions.h"
00035 #include "gdb_string.h"
00036 #include "gdbcore.h"
00037 #include "inferior.h"
00038 #include "target.h"
00039 #include "objfiles.h"
00040 #include "gdbthread.h"
00041 #include "nto-tdep.h"
00042 #include "command.h"
00043 #include "regcache.h"
00044 #include "solib.h"
00045 
00046 #define NULL_PID                0
00047 #define _DEBUG_FLAG_TRACE       (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
00048                 _DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY)
00049 
00050 static struct target_ops procfs_ops;
00051 
00052 int ctl_fd;
00053 
00054 static void (*ofunc) ();
00055 
00056 static procfs_run run;
00057 
00058 static void procfs_open (char *, int);
00059 
00060 static int procfs_can_run (void);
00061 
00062 static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
00063                                struct mem_attrib *attrib,
00064                                struct target_ops *);
00065 
00066 static void init_procfs_ops (void);
00067 
00068 static ptid_t do_attach (ptid_t ptid);
00069 
00070 static int procfs_can_use_hw_breakpoint (int, int, int);
00071 
00072 static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type,
00073                                         struct expression *cond);
00074 
00075 static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type,
00076                                         struct expression *cond);
00077 
00078 static int procfs_stopped_by_watchpoint (void);
00079 
00080 /* These two globals are only ever set in procfs_open(), but are
00081    referenced elsewhere.  'nto_procfs_node' is a flag used to say
00082    whether we are local, or we should get the current node descriptor
00083    for the remote QNX node.  */
00084 static char nto_procfs_path[PATH_MAX] = { "/proc" };
00085 static unsigned nto_procfs_node = ND_LOCAL_NODE;
00086 
00087 /* Return the current QNX Node, or error out.  This is a simple
00088    wrapper for the netmgr_strtond() function.  The reason this
00089    is required is because QNX node descriptors are transient so
00090    we have to re-acquire them every time.  */
00091 static unsigned
00092 nto_node (void)
00093 {
00094   unsigned node;
00095 
00096   if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0)
00097     return ND_LOCAL_NODE;
00098 
00099   node = netmgr_strtond (nto_procfs_path, 0);
00100   if (node == -1)
00101     error (_("Lost the QNX node.  Debug session probably over."));
00102 
00103   return (node);
00104 }
00105 
00106 static enum gdb_osabi
00107 procfs_is_nto_target (bfd *abfd)
00108 {
00109   return GDB_OSABI_QNXNTO;
00110 }
00111 
00112 /* This is called when we call 'target procfs <arg>' from the (gdb) prompt.
00113    For QNX6 (nto), the only valid arg will be a QNX node string, 
00114    eg: "/net/some_node".  If arg is not a valid QNX node, we will
00115    default to local.  */
00116 static void
00117 procfs_open (char *arg, int from_tty)
00118 {
00119   char *nodestr;
00120   char *endstr;
00121   char buffer[50];
00122   int fd, total_size;
00123   procfs_sysinfo *sysinfo;
00124   struct cleanup *cleanups;
00125 
00126   nto_is_nto_target = procfs_is_nto_target;
00127 
00128   /* Set the default node used for spawning to this one,
00129      and only override it if there is a valid arg.  */
00130 
00131   nto_procfs_node = ND_LOCAL_NODE;
00132   nodestr = arg ? xstrdup (arg) : arg;
00133 
00134   init_thread_list ();
00135 
00136   if (nodestr)
00137     {
00138       nto_procfs_node = netmgr_strtond (nodestr, &endstr);
00139       if (nto_procfs_node == -1)
00140         {
00141           if (errno == ENOTSUP)
00142             printf_filtered ("QNX Net Manager not found.\n");
00143           printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
00144                            errno, safe_strerror (errno));
00145           xfree (nodestr);
00146           nodestr = NULL;
00147           nto_procfs_node = ND_LOCAL_NODE;
00148         }
00149       else if (*endstr)
00150         {
00151           if (*(endstr - 1) == '/')
00152             *(endstr - 1) = 0;
00153           else
00154             *endstr = 0;
00155         }
00156     }
00157   snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "",
00158             "/proc");
00159   if (nodestr)
00160     xfree (nodestr);
00161 
00162   fd = open (nto_procfs_path, O_RDONLY);
00163   if (fd == -1)
00164     {
00165       printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
00166                        safe_strerror (errno));
00167       error (_("Invalid procfs arg"));
00168     }
00169   cleanups = make_cleanup_close (fd);
00170 
00171   sysinfo = (void *) buffer;
00172   if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
00173     {
00174       printf_filtered ("Error getting size: %d (%s)\n", errno,
00175                        safe_strerror (errno));
00176       error (_("Devctl failed."));
00177     }
00178   else
00179     {
00180       total_size = sysinfo->total_size;
00181       sysinfo = alloca (total_size);
00182       if (!sysinfo)
00183         {
00184           printf_filtered ("Memory error: %d (%s)\n", errno,
00185                            safe_strerror (errno));
00186           error (_("alloca failed."));
00187         }
00188       else
00189         {
00190           if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
00191             {
00192               printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
00193                                safe_strerror (errno));
00194               error (_("Devctl failed."));
00195             }
00196           else
00197             {
00198               if (sysinfo->type !=
00199                   nto_map_arch_to_cputype (gdbarch_bfd_arch_info
00200                                            (target_gdbarch ())->arch_name))
00201                 error (_("Invalid target CPU."));
00202             }
00203         }
00204     }
00205   do_cleanups (cleanups);
00206   printf_filtered ("Debugging using %s\n", nto_procfs_path);
00207 }
00208 
00209 static void
00210 procfs_set_thread (ptid_t ptid)
00211 {
00212   pid_t tid;
00213 
00214   tid = ptid_get_tid (ptid);
00215   devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
00216 }
00217 
00218 /*  Return nonzero if the thread TH is still alive.  */
00219 static int
00220 procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
00221 {
00222   pid_t tid;
00223   pid_t pid;
00224   procfs_status status;
00225   int err;
00226 
00227   tid = ptid_get_tid (ptid);
00228   pid = ptid_get_pid (ptid);
00229 
00230   if (kill (pid, 0) == -1)
00231     return 0;
00232 
00233   status.tid = tid;
00234   if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS,
00235                      &status, sizeof (status), 0)) != EOK)
00236     return 0;
00237 
00238   /* Thread is alive or dead but not yet joined,
00239      or dead and there is an alive (or dead unjoined) thread with
00240      higher tid.
00241 
00242      If the tid is not the same as requested, requested tid is dead.  */
00243   return (status.tid == tid) && (status.state != STATE_DEAD);
00244 }
00245 
00246 static void
00247 update_thread_private_data_name (struct thread_info *new_thread,
00248                                  const char *newname)
00249 {
00250   int newnamelen;
00251   struct private_thread_info *pti;
00252 
00253   gdb_assert (newname != NULL);
00254   gdb_assert (new_thread != NULL);
00255   newnamelen = strlen (newname);
00256   if (!new_thread->private)
00257     {
00258       new_thread->private = xmalloc (offsetof (struct private_thread_info,
00259                                                name)
00260                                      + newnamelen + 1);
00261       memcpy (new_thread->private->name, newname, newnamelen + 1);
00262     }
00263   else if (strcmp (newname, new_thread->private->name) != 0)
00264     {
00265       /* Reallocate if neccessary.  */
00266       int oldnamelen = strlen (new_thread->private->name);
00267 
00268       if (oldnamelen < newnamelen)
00269         new_thread->private = xrealloc (new_thread->private,
00270                                         offsetof (struct private_thread_info,
00271                                                   name)
00272                                         + newnamelen + 1);
00273       memcpy (new_thread->private->name, newname, newnamelen + 1);
00274     }
00275 }
00276 
00277 static void 
00278 update_thread_private_data (struct thread_info *new_thread, 
00279                             pthread_t tid, int state, int flags)
00280 {
00281   struct private_thread_info *pti;
00282   procfs_info pidinfo;
00283   struct _thread_name *tn;
00284   procfs_threadctl tctl;
00285 
00286 #if _NTO_VERSION > 630
00287   gdb_assert (new_thread != NULL);
00288 
00289   if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo,
00290               sizeof(pidinfo), 0) != EOK)
00291     return;
00292 
00293   memset (&tctl, 0, sizeof (tctl));
00294   tctl.cmd = _NTO_TCTL_NAME;
00295   tn = (struct _thread_name *) (&tctl.data);
00296 
00297   /* Fetch name for the given thread.  */
00298   tctl.tid = tid;
00299   tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn);
00300   tn->new_name_len = -1; /* Getting, not setting.  */
00301   if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK)
00302     tn->name_buf[0] = '\0';
00303 
00304   tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0';
00305 
00306   update_thread_private_data_name (new_thread, tn->name_buf);
00307 
00308   pti = (struct private_thread_info *) new_thread->private;
00309   pti->tid = tid;
00310   pti->state = state;
00311   pti->flags = flags;
00312 #endif /* _NTO_VERSION */
00313 }
00314 
00315 static void
00316 procfs_find_new_threads (struct target_ops *ops)
00317 {
00318   procfs_status status;
00319   pid_t pid;
00320   ptid_t ptid;
00321   pthread_t tid;
00322   struct thread_info *new_thread;
00323 
00324   if (ctl_fd == -1)
00325     return;
00326 
00327   pid = ptid_get_pid (inferior_ptid);
00328 
00329   status.tid = 1;
00330 
00331   for (tid = 1;; ++tid)
00332     {
00333       if (status.tid == tid 
00334           && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0)
00335               != EOK))
00336         break;
00337       if (status.tid != tid)
00338         /* The reason why this would not be equal is that devctl might have 
00339            returned different tid, meaning the requested tid no longer exists
00340            (e.g. thread exited).  */
00341         continue;
00342       ptid = ptid_build (pid, 0, tid);
00343       new_thread = find_thread_ptid (ptid);
00344       if (!new_thread)
00345         new_thread = add_thread (ptid);
00346       update_thread_private_data (new_thread, tid, status.state, 0);
00347       status.tid++;
00348     }
00349   return;
00350 }
00351 
00352 static void
00353 do_closedir_cleanup (void *dir)
00354 {
00355   closedir (dir);
00356 }
00357 
00358 void
00359 procfs_pidlist (char *args, int from_tty)
00360 {
00361   DIR *dp = NULL;
00362   struct dirent *dirp = NULL;
00363   char buf[512];
00364   procfs_info *pidinfo = NULL;
00365   procfs_debuginfo *info = NULL;
00366   procfs_status *status = NULL;
00367   pid_t num_threads = 0;
00368   pid_t pid;
00369   char name[512];
00370   struct cleanup *cleanups;
00371 
00372   dp = opendir (nto_procfs_path);
00373   if (dp == NULL)
00374     {
00375       fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
00376                           nto_procfs_path, errno, safe_strerror (errno));
00377       return;
00378     }
00379 
00380   cleanups = make_cleanup (do_closedir_cleanup, dp);
00381 
00382   /* Start scan at first pid.  */
00383   rewinddir (dp);
00384 
00385   do
00386     {
00387       int fd;
00388       struct cleanup *inner_cleanup;
00389 
00390       /* Get the right pid and procfs path for the pid.  */
00391       do
00392         {
00393           dirp = readdir (dp);
00394           if (dirp == NULL)
00395             {
00396               do_cleanups (cleanups);
00397               return;
00398             }
00399           snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
00400           pid = atoi (dirp->d_name);
00401         }
00402       while (pid == 0);
00403 
00404       /* Open the procfs path.  */
00405       fd = open (buf, O_RDONLY);
00406       if (fd == -1)
00407         {
00408           fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
00409                               buf, errno, safe_strerror (errno));
00410           do_cleanups (cleanups);
00411           return;
00412         }
00413       inner_cleanup = make_cleanup_close (fd);
00414 
00415       pidinfo = (procfs_info *) buf;
00416       if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
00417         {
00418           fprintf_unfiltered (gdb_stderr,
00419                               "devctl DCMD_PROC_INFO failed - %d (%s)\n",
00420                               errno, safe_strerror (errno));
00421           break;
00422         }
00423       num_threads = pidinfo->num_threads;
00424 
00425       info = (procfs_debuginfo *) buf;
00426       if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
00427         strcpy (name, "unavailable");
00428       else
00429         strcpy (name, info->path);
00430 
00431       /* Collect state info on all the threads.  */
00432       status = (procfs_status *) buf;
00433       for (status->tid = 1; status->tid <= num_threads; status->tid++)
00434         {
00435           if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
00436               && status->tid != 0)
00437             break;
00438           if (status->tid != 0)
00439             printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
00440         }
00441 
00442       do_cleanups (inner_cleanup);
00443     }
00444   while (dirp != NULL);
00445 
00446   do_cleanups (cleanups);
00447   return;
00448 }
00449 
00450 void
00451 procfs_meminfo (char *args, int from_tty)
00452 {
00453   procfs_mapinfo *mapinfos = NULL;
00454   static int num_mapinfos = 0;
00455   procfs_mapinfo *mapinfo_p, *mapinfo_p2;
00456   int flags = ~0, err, num, i, j;
00457 
00458   struct
00459   {
00460     procfs_debuginfo info;
00461     char buff[_POSIX_PATH_MAX];
00462   } map;
00463 
00464   struct info
00465   {
00466     unsigned addr;
00467     unsigned size;
00468     unsigned flags;
00469     unsigned debug_vaddr;
00470     unsigned long long offset;
00471   };
00472 
00473   struct printinfo
00474   {
00475     unsigned long long ino;
00476     unsigned dev;
00477     struct info text;
00478     struct info data;
00479     char name[256];
00480   } printme;
00481 
00482   /* Get the number of map entrys.  */
00483   err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num);
00484   if (err != EOK)
00485     {
00486       printf ("failed devctl num mapinfos - %d (%s)\n", err,
00487               safe_strerror (err));
00488       return;
00489     }
00490 
00491   mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
00492 
00493   num_mapinfos = num;
00494   mapinfo_p = mapinfos;
00495 
00496   /* Fill the map entrys.  */
00497   err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num
00498                 * sizeof (procfs_mapinfo), &num);
00499   if (err != EOK)
00500     {
00501       printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
00502       xfree (mapinfos);
00503       return;
00504     }
00505 
00506   num = min (num, num_mapinfos);
00507 
00508   /* Run through the list of mapinfos, and store the data and text info
00509      so we can print it at the bottom of the loop.  */
00510   for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
00511     {
00512       if (!(mapinfo_p->flags & flags))
00513         mapinfo_p->ino = 0;
00514 
00515       if (mapinfo_p->ino == 0)  /* Already visited.  */
00516         continue;
00517 
00518       map.info.vaddr = mapinfo_p->vaddr;
00519 
00520       err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
00521       if (err != EOK)
00522         continue;
00523 
00524       memset (&printme, 0, sizeof printme);
00525       printme.dev = mapinfo_p->dev;
00526       printme.ino = mapinfo_p->ino;
00527       printme.text.addr = mapinfo_p->vaddr;
00528       printme.text.size = mapinfo_p->size;
00529       printme.text.flags = mapinfo_p->flags;
00530       printme.text.offset = mapinfo_p->offset;
00531       printme.text.debug_vaddr = map.info.vaddr;
00532       strcpy (printme.name, map.info.path);
00533 
00534       /* Check for matching data.  */
00535       for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
00536         {
00537           if (mapinfo_p2->vaddr != mapinfo_p->vaddr
00538               && mapinfo_p2->ino == mapinfo_p->ino
00539               && mapinfo_p2->dev == mapinfo_p->dev)
00540             {
00541               map.info.vaddr = mapinfo_p2->vaddr;
00542               err =
00543                 devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
00544               if (err != EOK)
00545                 continue;
00546 
00547               if (strcmp (map.info.path, printme.name))
00548                 continue;
00549 
00550               /* Lower debug_vaddr is always text, if nessessary, swap.  */
00551               if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
00552                 {
00553                   memcpy (&(printme.data), &(printme.text),
00554                           sizeof (printme.data));
00555                   printme.text.addr = mapinfo_p2->vaddr;
00556                   printme.text.size = mapinfo_p2->size;
00557                   printme.text.flags = mapinfo_p2->flags;
00558                   printme.text.offset = mapinfo_p2->offset;
00559                   printme.text.debug_vaddr = map.info.vaddr;
00560                 }
00561               else
00562                 {
00563                   printme.data.addr = mapinfo_p2->vaddr;
00564                   printme.data.size = mapinfo_p2->size;
00565                   printme.data.flags = mapinfo_p2->flags;
00566                   printme.data.offset = mapinfo_p2->offset;
00567                   printme.data.debug_vaddr = map.info.vaddr;
00568                 }
00569               mapinfo_p2->ino = 0;
00570             }
00571         }
00572       mapinfo_p->ino = 0;
00573 
00574       printf_filtered ("%s\n", printme.name);
00575       printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
00576                        printme.text.addr);
00577       printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
00578       printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
00579       printf_filtered ("\t\toffset=%s\n", phex (printme.text.offset, 8));
00580       if (printme.data.size)
00581         {
00582           printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
00583                            printme.data.addr);
00584           printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
00585           printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
00586           printf_filtered ("\t\toffset=%s\n", phex (printme.data.offset, 8));
00587         }
00588       printf_filtered ("\tdev=0x%x\n", printme.dev);
00589       printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
00590     }
00591   xfree (mapinfos);
00592   return;
00593 }
00594 
00595 /* Print status information about what we're accessing.  */
00596 static void
00597 procfs_files_info (struct target_ops *ignore)
00598 {
00599   struct inferior *inf = current_inferior ();
00600 
00601   printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
00602                      inf->attach_flag ? "attached" : "child",
00603                      target_pid_to_str (inferior_ptid), nto_procfs_path);
00604 }
00605 
00606 /* Mark our target-struct as eligible for stray "run" and "attach"
00607    commands.  */
00608 static int
00609 procfs_can_run (void)
00610 {
00611   return 1;
00612 }
00613 
00614 /* Attach to process PID, then initialize for debugging it.  */
00615 static void
00616 procfs_attach (struct target_ops *ops, char *args, int from_tty)
00617 {
00618   char *exec_file;
00619   int pid;
00620   struct inferior *inf;
00621 
00622   pid = parse_pid_to_attach (args);
00623 
00624   if (pid == getpid ())
00625     error (_("Attaching GDB to itself is not a good idea..."));
00626 
00627   if (from_tty)
00628     {
00629       exec_file = (char *) get_exec_file (0);
00630 
00631       if (exec_file)
00632         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
00633                            target_pid_to_str (pid_to_ptid (pid)));
00634       else
00635         printf_unfiltered ("Attaching to %s\n",
00636                            target_pid_to_str (pid_to_ptid (pid)));
00637 
00638       gdb_flush (gdb_stdout);
00639     }
00640   inferior_ptid = do_attach (pid_to_ptid (pid));
00641   inf = current_inferior ();
00642   inferior_appeared (inf, pid);
00643   inf->attach_flag = 1;
00644 
00645   push_target (ops);
00646 
00647   procfs_find_new_threads (ops);
00648 }
00649 
00650 static void
00651 procfs_post_attach (pid_t pid)
00652 {
00653   if (exec_bfd)
00654     solib_create_inferior_hook (0);
00655 }
00656 
00657 static ptid_t
00658 do_attach (ptid_t ptid)
00659 {
00660   procfs_status status;
00661   struct sigevent event;
00662   char path[PATH_MAX];
00663 
00664   snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path,
00665             ptid_get_pid (ptid));
00666   ctl_fd = open (path, O_RDWR);
00667   if (ctl_fd == -1)
00668     error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
00669            safe_strerror (errno));
00670   if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
00671     error (_("Couldn't stop process"));
00672 
00673   /* Define a sigevent for process stopped notification.  */
00674   event.sigev_notify = SIGEV_SIGNAL_THREAD;
00675   event.sigev_signo = SIGUSR1;
00676   event.sigev_code = 0;
00677   event.sigev_value.sival_ptr = NULL;
00678   event.sigev_priority = -1;
00679   devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
00680 
00681   if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
00682       && status.flags & _DEBUG_FLAG_STOPPED)
00683     SignalKill (nto_node (), ptid_get_pid (ptid), 0, SIGCONT, 0, 0);
00684   nto_init_solib_absolute_prefix ();
00685   return ptid_build (ptid_get_pid (ptid), 0, status.tid);
00686 }
00687 
00688 /* Ask the user what to do when an interrupt is received.  */
00689 static void
00690 interrupt_query (void)
00691 {
00692   target_terminal_ours ();
00693 
00694   if (query (_("Interrupted while waiting for the program.\n\
00695 Give up (and stop debugging it)? ")))
00696     {
00697       target_mourn_inferior ();
00698       quit ();
00699     }
00700 
00701   target_terminal_inferior ();
00702 }
00703 
00704 /* The user typed ^C twice.  */
00705 static void
00706 nto_interrupt_twice (int signo)
00707 {
00708   signal (signo, ofunc);
00709   interrupt_query ();
00710   signal (signo, nto_interrupt_twice);
00711 }
00712 
00713 static void
00714 nto_interrupt (int signo)
00715 {
00716   /* If this doesn't work, try more severe steps.  */
00717   signal (signo, nto_interrupt_twice);
00718 
00719   target_stop (inferior_ptid);
00720 }
00721 
00722 static ptid_t
00723 procfs_wait (struct target_ops *ops,
00724              ptid_t ptid, struct target_waitstatus *ourstatus, int options)
00725 {
00726   sigset_t set;
00727   siginfo_t info;
00728   procfs_status status;
00729   static int exit_signo = 0;    /* To track signals that cause termination.  */
00730 
00731   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
00732 
00733   if (ptid_equal (inferior_ptid, null_ptid))
00734     {
00735       ourstatus->kind = TARGET_WAITKIND_STOPPED;
00736       ourstatus->value.sig = GDB_SIGNAL_0;
00737       exit_signo = 0;
00738       return null_ptid;
00739     }
00740 
00741   sigemptyset (&set);
00742   sigaddset (&set, SIGUSR1);
00743 
00744   devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
00745   while (!(status.flags & _DEBUG_FLAG_ISTOP))
00746     {
00747       ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
00748       sigwaitinfo (&set, &info);
00749       signal (SIGINT, ofunc);
00750       devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
00751     }
00752 
00753   if (status.flags & _DEBUG_FLAG_SSTEP)
00754     {
00755       ourstatus->kind = TARGET_WAITKIND_STOPPED;
00756       ourstatus->value.sig = GDB_SIGNAL_TRAP;
00757     }
00758   /* Was it a breakpoint?  */
00759   else if (status.flags & _DEBUG_FLAG_TRACE)
00760     {
00761       ourstatus->kind = TARGET_WAITKIND_STOPPED;
00762       ourstatus->value.sig = GDB_SIGNAL_TRAP;
00763     }
00764   else if (status.flags & _DEBUG_FLAG_ISTOP)
00765     {
00766       switch (status.why)
00767         {
00768         case _DEBUG_WHY_SIGNALLED:
00769           ourstatus->kind = TARGET_WAITKIND_STOPPED;
00770           ourstatus->value.sig =
00771             gdb_signal_from_host (status.info.si_signo);
00772           exit_signo = 0;
00773           break;
00774         case _DEBUG_WHY_FAULTED:
00775           ourstatus->kind = TARGET_WAITKIND_STOPPED;
00776           if (status.info.si_signo == SIGTRAP)
00777             {
00778               ourstatus->value.sig = 0;
00779               exit_signo = 0;
00780             }
00781           else
00782             {
00783               ourstatus->value.sig =
00784                 gdb_signal_from_host (status.info.si_signo);
00785               exit_signo = ourstatus->value.sig;
00786             }
00787           break;
00788 
00789         case _DEBUG_WHY_TERMINATED:
00790           {
00791             int waitval = 0;
00792 
00793             waitpid (ptid_get_pid (inferior_ptid), &waitval, WNOHANG);
00794             if (exit_signo)
00795               {
00796                 /* Abnormal death.  */
00797                 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
00798                 ourstatus->value.sig = exit_signo;
00799               }
00800             else
00801               {
00802                 /* Normal death.  */
00803                 ourstatus->kind = TARGET_WAITKIND_EXITED;
00804                 ourstatus->value.integer = WEXITSTATUS (waitval);
00805               }
00806             exit_signo = 0;
00807             break;
00808           }
00809 
00810         case _DEBUG_WHY_REQUESTED:
00811           /* We are assuming a requested stop is due to a SIGINT.  */
00812           ourstatus->kind = TARGET_WAITKIND_STOPPED;
00813           ourstatus->value.sig = GDB_SIGNAL_INT;
00814           exit_signo = 0;
00815           break;
00816         }
00817     }
00818 
00819   return ptid_build (status.pid, 0, status.tid);
00820 }
00821 
00822 /* Read the current values of the inferior's registers, both the
00823    general register set and floating point registers (if supported)
00824    and update gdb's idea of their current values.  */
00825 static void
00826 procfs_fetch_registers (struct target_ops *ops,
00827                         struct regcache *regcache, int regno)
00828 {
00829   union
00830   {
00831     procfs_greg greg;
00832     procfs_fpreg fpreg;
00833     procfs_altreg altreg;
00834   }
00835   reg;
00836   int regsize;
00837 
00838   procfs_set_thread (inferior_ptid);
00839   if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
00840     nto_supply_gregset (regcache, (char *) &reg.greg);
00841   if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
00842       == EOK)
00843     nto_supply_fpregset (regcache, (char *) &reg.fpreg);
00844   if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
00845       == EOK)
00846     nto_supply_altregset (regcache, (char *) &reg.altreg);
00847 }
00848 
00849 /* Copy LEN bytes to/from inferior's memory starting at MEMADDR
00850    from/to debugger memory starting at MYADDR.  Copy from inferior
00851    if DOWRITE is zero or to inferior if DOWRITE is nonzero.
00852 
00853    Returns the length copied, which is either the LEN argument or
00854    zero.  This xfer function does not do partial moves, since procfs_ops
00855    doesn't allow memory operations to cross below us in the target stack
00856    anyway.  */
00857 static int
00858 procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
00859                     struct mem_attrib *attrib, struct target_ops *target)
00860 {
00861   int nbytes = 0;
00862 
00863   if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
00864     {
00865       if (dowrite)
00866         nbytes = write (ctl_fd, myaddr, len);
00867       else
00868         nbytes = read (ctl_fd, myaddr, len);
00869       if (nbytes < 0)
00870         nbytes = 0;
00871     }
00872   return (nbytes);
00873 }
00874 
00875 /* Take a program previously attached to and detaches it.
00876    The program resumes execution and will no longer stop
00877    on signals, etc.  We'd better not have left any breakpoints
00878    in the program or it'll die when it hits one.  */
00879 static void
00880 procfs_detach (struct target_ops *ops, char *args, int from_tty)
00881 {
00882   int siggnal = 0;
00883   int pid;
00884 
00885   if (from_tty)
00886     {
00887       char *exec_file = get_exec_file (0);
00888       if (exec_file == 0)
00889         exec_file = "";
00890       printf_unfiltered ("Detaching from program: %s %s\n",
00891                          exec_file, target_pid_to_str (inferior_ptid));
00892       gdb_flush (gdb_stdout);
00893     }
00894   if (args)
00895     siggnal = atoi (args);
00896 
00897   if (siggnal)
00898     SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, siggnal, 0, 0);
00899 
00900   close (ctl_fd);
00901   ctl_fd = -1;
00902 
00903   pid = ptid_get_pid (inferior_ptid);
00904   inferior_ptid = null_ptid;
00905   detach_inferior (pid);
00906   init_thread_list ();
00907   unpush_target (&procfs_ops);  /* Pop out of handling an inferior.  */
00908 }
00909 
00910 static int
00911 procfs_breakpoint (CORE_ADDR addr, int type, int size)
00912 {
00913   procfs_break brk;
00914 
00915   brk.type = type;
00916   brk.addr = addr;
00917   brk.size = size;
00918   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
00919   if (errno != EOK)
00920     return 1;
00921   return 0;
00922 }
00923 
00924 static int
00925 procfs_insert_breakpoint (struct gdbarch *gdbarch,
00926                           struct bp_target_info *bp_tgt)
00927 {
00928   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
00929 }
00930 
00931 static int
00932 procfs_remove_breakpoint (struct gdbarch *gdbarch,
00933                           struct bp_target_info *bp_tgt)
00934 {
00935   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
00936 }
00937 
00938 static int
00939 procfs_insert_hw_breakpoint (struct gdbarch *gdbarch,
00940                              struct bp_target_info *bp_tgt)
00941 {
00942   return procfs_breakpoint (bp_tgt->placed_address,
00943                             _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
00944 }
00945 
00946 static int
00947 procfs_remove_hw_breakpoint (struct gdbarch *gdbarch,
00948                              struct bp_target_info *bp_tgt)
00949 {
00950   return procfs_breakpoint (bp_tgt->placed_address,
00951                             _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
00952 }
00953 
00954 static void
00955 procfs_resume (struct target_ops *ops,
00956                ptid_t ptid, int step, enum gdb_signal signo)
00957 {
00958   int signal_to_pass;
00959   procfs_status status;
00960   sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
00961 
00962   if (ptid_equal (inferior_ptid, null_ptid))
00963     return;
00964 
00965   procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
00966                      ptid);
00967 
00968   run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
00969   if (step)
00970     run.flags |= _DEBUG_RUN_STEP;
00971 
00972   sigemptyset (run_fault);
00973   sigaddset (run_fault, FLTBPT);
00974   sigaddset (run_fault, FLTTRACE);
00975   sigaddset (run_fault, FLTILL);
00976   sigaddset (run_fault, FLTPRIV);
00977   sigaddset (run_fault, FLTBOUNDS);
00978   sigaddset (run_fault, FLTIOVF);
00979   sigaddset (run_fault, FLTIZDIV);
00980   sigaddset (run_fault, FLTFPE);
00981   /* Peter V will be changing this at some point.  */
00982   sigaddset (run_fault, FLTPAGE);
00983 
00984   run.flags |= _DEBUG_RUN_ARM;
00985 
00986   signal_to_pass = gdb_signal_to_host (signo);
00987 
00988   if (signal_to_pass)
00989     {
00990       devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
00991       signal_to_pass = gdb_signal_to_host (signo);
00992       if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
00993         {
00994           if (signal_to_pass != status.info.si_signo)
00995             {
00996               SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0,
00997                           signal_to_pass, 0, 0);
00998               run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
00999             }
01000           else          /* Let it kill the program without telling us.  */
01001             sigdelset (&run.trace, signal_to_pass);
01002         }
01003     }
01004   else
01005     run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
01006 
01007   errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
01008   if (errno != EOK)
01009     {
01010       perror (_("run error!\n"));
01011       return;
01012     }
01013 }
01014 
01015 static void
01016 procfs_mourn_inferior (struct target_ops *ops)
01017 {
01018   if (!ptid_equal (inferior_ptid, null_ptid))
01019     {
01020       SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, SIGKILL, 0, 0);
01021       close (ctl_fd);
01022     }
01023   inferior_ptid = null_ptid;
01024   init_thread_list ();
01025   unpush_target (&procfs_ops);
01026   generic_mourn_inferior ();
01027 }
01028 
01029 /* This function breaks up an argument string into an argument
01030    vector suitable for passing to execvp().
01031    E.g., on "run a b c d" this routine would get as input
01032    the string "a b c d", and as output it would fill in argv with
01033    the four arguments "a", "b", "c", "d".  The only additional
01034    functionality is simple quoting.  The gdb command:
01035         run a "b c d" f
01036    will fill in argv with the three args "a", "b c d", "e".  */
01037 static void
01038 breakup_args (char *scratch, char **argv)
01039 {
01040   char *pp, *cp = scratch;
01041   char quoting = 0;
01042 
01043   for (;;)
01044     {
01045       /* Scan past leading separators.  */
01046       quoting = 0;
01047       while (*cp == ' ' || *cp == '\t' || *cp == '\n')
01048         cp++;
01049 
01050       /* Break if at end of string.  */
01051       if (*cp == '\0')
01052         break;
01053 
01054       /* Take an arg.  */
01055       if (*cp == '"')
01056         {
01057           cp++;
01058           quoting = strchr (cp, '"') ? 1 : 0;
01059         }
01060 
01061       *argv++ = cp;
01062 
01063       /* Scan for next arg separator.  */
01064       pp = cp;
01065       if (quoting)
01066         cp = strchr (pp, '"');
01067       if ((cp == NULL) || (!quoting))
01068         cp = strchr (pp, ' ');
01069       if (cp == NULL)
01070         cp = strchr (pp, '\t');
01071       if (cp == NULL)
01072         cp = strchr (pp, '\n');
01073 
01074       /* No separators => end of string => break.  */
01075       if (cp == NULL)
01076         {
01077           pp = cp;
01078           break;
01079         }
01080 
01081       /* Replace the separator with a terminator.  */
01082       *cp++ = '\0';
01083     }
01084 
01085   /* Execv requires a null-terminated arg vector.  */
01086   *argv = NULL;
01087 }
01088 
01089 static void
01090 procfs_create_inferior (struct target_ops *ops, char *exec_file,
01091                         char *allargs, char **env, int from_tty)
01092 {
01093   struct inheritance inherit;
01094   pid_t pid;
01095   int flags, errn;
01096   char **argv, *args;
01097   const char *in = "", *out = "", *err = "";
01098   int fd, fds[3];
01099   sigset_t set;
01100   const char *inferior_io_terminal = get_inferior_io_terminal ();
01101   struct inferior *inf;
01102 
01103   argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
01104                   sizeof (*argv));
01105   argv[0] = get_exec_file (1);
01106   if (!argv[0])
01107     {
01108       if (exec_file)
01109         argv[0] = exec_file;
01110       else
01111         return;
01112     }
01113 
01114   args = xstrdup (allargs);
01115   breakup_args (args, exec_file ? &argv[1] : &argv[0]);
01116 
01117   argv = nto_parse_redirection (argv, &in, &out, &err);
01118 
01119   fds[0] = STDIN_FILENO;
01120   fds[1] = STDOUT_FILENO;
01121   fds[2] = STDERR_FILENO;
01122 
01123   /* If the user specified I/O via gdb's --tty= arg, use it, but only
01124      if the i/o is not also being specified via redirection.  */
01125   if (inferior_io_terminal)
01126     {
01127       if (!in[0])
01128         in = inferior_io_terminal;
01129       if (!out[0])
01130         out = inferior_io_terminal;
01131       if (!err[0])
01132         err = inferior_io_terminal;
01133     }
01134 
01135   if (in[0])
01136     {
01137       fd = open (in, O_RDONLY);
01138       if (fd == -1)
01139         perror (in);
01140       else
01141         fds[0] = fd;
01142     }
01143   if (out[0])
01144     {
01145       fd = open (out, O_WRONLY);
01146       if (fd == -1)
01147         perror (out);
01148       else
01149         fds[1] = fd;
01150     }
01151   if (err[0])
01152     {
01153       fd = open (err, O_WRONLY);
01154       if (fd == -1)
01155         perror (err);
01156       else
01157         fds[2] = fd;
01158     }
01159 
01160   /* Clear any pending SIGUSR1's but keep the behavior the same.  */
01161   signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
01162 
01163   sigemptyset (&set);
01164   sigaddset (&set, SIGUSR1);
01165   sigprocmask (SIG_UNBLOCK, &set, NULL);
01166 
01167   memset (&inherit, 0, sizeof (inherit));
01168 
01169   if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
01170     {
01171       inherit.nd = nto_node ();
01172       inherit.flags |= SPAWN_SETND;
01173       inherit.flags &= ~SPAWN_EXEC;
01174     }
01175   inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
01176   inherit.pgroup = SPAWN_NEWPGROUP;
01177   pid = spawnp (argv[0], 3, fds, &inherit, argv,
01178                 ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
01179   xfree (args);
01180 
01181   sigprocmask (SIG_BLOCK, &set, NULL);
01182 
01183   if (pid == -1)
01184     error (_("Error spawning %s: %d (%s)"), argv[0], errno,
01185            safe_strerror (errno));
01186 
01187   if (fds[0] != STDIN_FILENO)
01188     close (fds[0]);
01189   if (fds[1] != STDOUT_FILENO)
01190     close (fds[1]);
01191   if (fds[2] != STDERR_FILENO)
01192     close (fds[2]);
01193 
01194   inferior_ptid = do_attach (pid_to_ptid (pid));
01195   procfs_find_new_threads (ops);
01196 
01197   inf = current_inferior ();
01198   inferior_appeared (inf, pid);
01199   inf->attach_flag = 0;
01200 
01201   flags = _DEBUG_FLAG_KLC;      /* Kill-on-Last-Close flag.  */
01202   errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
01203   if (errn != EOK)
01204     {
01205       /* FIXME: expected warning?  */
01206       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
01207          errn, strerror(errn) ); */
01208     }
01209   push_target (ops);
01210   target_terminal_init ();
01211 
01212   if (exec_bfd != NULL
01213       || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
01214     solib_create_inferior_hook (0);
01215 }
01216 
01217 static void
01218 procfs_stop (ptid_t ptid)
01219 {
01220   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
01221 }
01222 
01223 static void
01224 procfs_kill_inferior (struct target_ops *ops)
01225 {
01226   target_mourn_inferior ();
01227 }
01228 
01229 /* Store register REGNO, or all registers if REGNO == -1, from the contents
01230    of REGISTERS.  */
01231 static void
01232 procfs_prepare_to_store (struct regcache *regcache)
01233 {
01234 }
01235 
01236 /* Fill buf with regset and return devctl cmd to do the setting.  Return
01237    -1 if we fail to get the regset.  Store size of regset in regsize.  */
01238 static int
01239 get_regset (int regset, char *buf, int bufsize, int *regsize)
01240 {
01241   int dev_get, dev_set;
01242   switch (regset)
01243     {
01244     case NTO_REG_GENERAL:
01245       dev_get = DCMD_PROC_GETGREG;
01246       dev_set = DCMD_PROC_SETGREG;
01247       break;
01248 
01249     case NTO_REG_FLOAT:
01250       dev_get = DCMD_PROC_GETFPREG;
01251       dev_set = DCMD_PROC_SETFPREG;
01252       break;
01253 
01254     case NTO_REG_ALT:
01255       dev_get = DCMD_PROC_GETALTREG;
01256       dev_set = DCMD_PROC_SETALTREG;
01257       break;
01258 
01259     case NTO_REG_SYSTEM:
01260     default:
01261       return -1;
01262     }
01263   if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK)
01264     return -1;
01265 
01266   return dev_set;
01267 }
01268 
01269 void
01270 procfs_store_registers (struct target_ops *ops,
01271                         struct regcache *regcache, int regno)
01272 {
01273   union
01274   {
01275     procfs_greg greg;
01276     procfs_fpreg fpreg;
01277     procfs_altreg altreg;
01278   }
01279   reg;
01280   unsigned off;
01281   int len, regset, regsize, dev_set, err;
01282   char *data;
01283 
01284   if (ptid_equal (inferior_ptid, null_ptid))
01285     return;
01286   procfs_set_thread (inferior_ptid);
01287 
01288   if (regno == -1)
01289     {
01290       for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
01291         {
01292           dev_set = get_regset (regset, (char *) &reg,
01293                                 sizeof (reg), &regsize);
01294           if (dev_set == -1)
01295             continue;
01296 
01297           if (nto_regset_fill (regcache, regset, (char *) &reg) == -1)
01298             continue;
01299 
01300           err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
01301           if (err != EOK)
01302             fprintf_unfiltered (gdb_stderr,
01303                                 "Warning unable to write regset %d: %s\n",
01304                                 regno, safe_strerror (err));
01305         }
01306     }
01307   else
01308     {
01309       regset = nto_regset_id (regno);
01310       if (regset == -1)
01311         return;
01312 
01313       dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
01314       if (dev_set == -1)
01315         return;
01316 
01317       len = nto_register_area (get_regcache_arch (regcache),
01318                                regno, regset, &off);
01319 
01320       if (len < 1)
01321         return;
01322 
01323       regcache_raw_collect (regcache, regno, (char *) &reg + off);
01324 
01325       err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
01326       if (err != EOK)
01327         fprintf_unfiltered (gdb_stderr,
01328                             "Warning unable to write regset %d: %s\n", regno,
01329                             safe_strerror (err));
01330     }
01331 }
01332 
01333 /* Set list of signals to be handled in the target.  */
01334 
01335 static void
01336 procfs_pass_signals (int numsigs, unsigned char *pass_signals)
01337 {
01338   int signo;
01339 
01340   sigfillset (&run.trace);
01341 
01342   for (signo = 1; signo < NSIG; signo++)
01343     {
01344       int target_signo = gdb_signal_from_host (signo);
01345       if (target_signo < numsigs && pass_signals[target_signo])
01346         sigdelset (&run.trace, signo);
01347     }
01348 }
01349 
01350 static struct tidinfo *
01351 procfs_thread_info (pid_t pid, short tid)
01352 {
01353 /* NYI */
01354   return NULL;
01355 }
01356 
01357 static char *
01358 procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
01359 {
01360   static char buf[1024];
01361   int pid, tid, n;
01362   struct tidinfo *tip;
01363 
01364   pid = ptid_get_pid (ptid);
01365   tid = ptid_get_tid (ptid);
01366 
01367   n = snprintf (buf, 1023, "process %d", pid);
01368 
01369 #if 0                           /* NYI */
01370   tip = procfs_thread_info (pid, tid);
01371   if (tip != NULL)
01372     snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
01373 #endif
01374 
01375   return buf;
01376 }
01377 
01378 static void
01379 init_procfs_ops (void)
01380 {
01381   procfs_ops.to_shortname = "procfs";
01382   procfs_ops.to_longname = "QNX Neutrino procfs child process";
01383   procfs_ops.to_doc =
01384     "QNX Neutrino procfs child process (started by the \"run\" command).\n\
01385         target procfs <node>";
01386   procfs_ops.to_open = procfs_open;
01387   procfs_ops.to_attach = procfs_attach;
01388   procfs_ops.to_post_attach = procfs_post_attach;
01389   procfs_ops.to_detach = procfs_detach;
01390   procfs_ops.to_resume = procfs_resume;
01391   procfs_ops.to_wait = procfs_wait;
01392   procfs_ops.to_fetch_registers = procfs_fetch_registers;
01393   procfs_ops.to_store_registers = procfs_store_registers;
01394   procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
01395   procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
01396   procfs_ops.to_files_info = procfs_files_info;
01397   procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
01398   procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
01399   procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
01400   procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
01401   procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
01402   procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
01403   procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
01404   procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
01405   procfs_ops.to_terminal_init = terminal_init_inferior;
01406   procfs_ops.to_terminal_inferior = terminal_inferior;
01407   procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
01408   procfs_ops.to_terminal_ours = terminal_ours;
01409   procfs_ops.to_terminal_info = child_terminal_info;
01410   procfs_ops.to_kill = procfs_kill_inferior;
01411   procfs_ops.to_create_inferior = procfs_create_inferior;
01412   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
01413   procfs_ops.to_can_run = procfs_can_run;
01414   procfs_ops.to_pass_signals = procfs_pass_signals;
01415   procfs_ops.to_thread_alive = procfs_thread_alive;
01416   procfs_ops.to_find_new_threads = procfs_find_new_threads;
01417   procfs_ops.to_pid_to_str = procfs_pid_to_str;
01418   procfs_ops.to_stop = procfs_stop;
01419   procfs_ops.to_stratum = process_stratum;
01420   procfs_ops.to_has_all_memory = default_child_has_all_memory;
01421   procfs_ops.to_has_memory = default_child_has_memory;
01422   procfs_ops.to_has_stack = default_child_has_stack;
01423   procfs_ops.to_has_registers = default_child_has_registers;
01424   procfs_ops.to_has_execution = default_child_has_execution;
01425   procfs_ops.to_magic = OPS_MAGIC;
01426   procfs_ops.to_have_continuable_watchpoint = 1;
01427   procfs_ops.to_extra_thread_info = nto_extra_thread_info;
01428 }
01429 
01430 #define OSTYPE_NTO 1
01431 
01432 void
01433 _initialize_procfs (void)
01434 {
01435   sigset_t set;
01436 
01437   init_procfs_ops ();
01438   add_target (&procfs_ops);
01439 
01440   /* We use SIGUSR1 to gain control after we block waiting for a process.
01441      We use sigwaitevent to wait.  */
01442   sigemptyset (&set);
01443   sigaddset (&set, SIGUSR1);
01444   sigprocmask (SIG_BLOCK, &set, NULL);
01445 
01446   /* Initially, make sure all signals are reported.  */
01447   sigfillset (&run.trace);
01448 
01449   /* Stuff some information.  */
01450   nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
01451   nto_cpuinfo_valid = 1;
01452 
01453   add_info ("pidlist", procfs_pidlist, _("pidlist"));
01454   add_info ("meminfo", procfs_meminfo, _("memory information"));
01455 
01456   nto_is_nto_target = procfs_is_nto_target;
01457 }
01458 
01459 
01460 static int
01461 procfs_hw_watchpoint (int addr, int len, int type)
01462 {
01463   procfs_break brk;
01464 
01465   switch (type)
01466     {
01467     case 1:                     /* Read.  */
01468       brk.type = _DEBUG_BREAK_RD;
01469       break;
01470     case 2:                     /* Read/Write.  */
01471       brk.type = _DEBUG_BREAK_RW;
01472       break;
01473     default:                    /* Modify.  */
01474 /* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason.  */
01475       brk.type = _DEBUG_BREAK_RW;
01476     }
01477   brk.type |= _DEBUG_BREAK_HW;  /* Always ask for HW.  */
01478   brk.addr = addr;
01479   brk.size = len;
01480 
01481   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
01482   if (errno != EOK)
01483     {
01484       perror (_("Failed to set hardware watchpoint"));
01485       return -1;
01486     }
01487   return 0;
01488 }
01489 
01490 static int
01491 procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
01492 {
01493   return 1;
01494 }
01495 
01496 static int
01497 procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type,
01498                              struct expression *cond)
01499 {
01500   return procfs_hw_watchpoint (addr, -1, type);
01501 }
01502 
01503 static int
01504 procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type,
01505                              struct expression *cond)
01506 {
01507   return procfs_hw_watchpoint (addr, len, type);
01508 }
01509 
01510 static int
01511 procfs_stopped_by_watchpoint (void)
01512 {
01513   return 0;
01514 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines