1/* Machine independent support for QNX Neutrino /proc (process file system)
2   for GDB.  Written by Colin Burgess at QNX Software Systems Limited.
3
4   Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011
5   Free Software Foundation, Inc.
6
7   Contributed by QNX Software Systems Ltd.
8
9   This file is part of GDB.
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 3 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23
24#include "defs.h"
25
26#include <fcntl.h>
27#include <spawn.h>
28#include <sys/debug.h>
29#include <sys/procfs.h>
30#include <sys/neutrino.h>
31#include <sys/syspage.h>
32#include "gdb_dirent.h"
33#include <sys/netmgr.h>
34
35#include "exceptions.h"
36#include "gdb_string.h"
37#include "gdbcore.h"
38#include "inferior.h"
39#include "target.h"
40#include "objfiles.h"
41#include "gdbthread.h"
42#include "nto-tdep.h"
43#include "command.h"
44#include "regcache.h"
45#include "solib.h"
46
47#define NULL_PID		0
48#define _DEBUG_FLAG_TRACE	(_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
49		_DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY)
50
51static struct target_ops procfs_ops;
52
53int ctl_fd;
54
55static void (*ofunc) ();
56
57static procfs_run run;
58
59static void procfs_open (char *, int);
60
61static int procfs_can_run (void);
62
63static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
64			       struct mem_attrib *attrib,
65			       struct target_ops *);
66
67static void notice_signals (void);
68
69static void init_procfs_ops (void);
70
71static ptid_t do_attach (ptid_t ptid);
72
73static int procfs_can_use_hw_breakpoint (int, int, int);
74
75static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
76
77static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
78
79static int procfs_stopped_by_watchpoint (void);
80
81/* These two globals are only ever set in procfs_open(), but are
82   referenced elsewhere.  'nto_procfs_node' is a flag used to say
83   whether we are local, or we should get the current node descriptor
84   for the remote QNX node.  */
85static char nto_procfs_path[PATH_MAX] = { "/proc" };
86static unsigned nto_procfs_node = ND_LOCAL_NODE;
87
88/* Return the current QNX Node, or error out.  This is a simple
89   wrapper for the netmgr_strtond() function.  The reason this
90   is required is because QNX node descriptors are transient so
91   we have to re-acquire them every time.  */
92static unsigned
93nto_node (void)
94{
95  unsigned node;
96
97  if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0)
98    return ND_LOCAL_NODE;
99
100  node = netmgr_strtond (nto_procfs_path, 0);
101  if (node == -1)
102    error (_("Lost the QNX node.  Debug session probably over."));
103
104  return (node);
105}
106
107static enum gdb_osabi
108procfs_is_nto_target (bfd *abfd)
109{
110  return GDB_OSABI_QNXNTO;
111}
112
113/* This is called when we call 'target procfs <arg>' from the (gdb) prompt.
114   For QNX6 (nto), the only valid arg will be a QNX node string,
115   eg: "/net/some_node".  If arg is not a valid QNX node, we will
116   default to local.  */
117static void
118procfs_open (char *arg, int from_tty)
119{
120  char *nodestr;
121  char *endstr;
122  char buffer[50];
123  int fd, total_size;
124  procfs_sysinfo *sysinfo;
125  struct cleanup *cleanups;
126
127  nto_is_nto_target = procfs_is_nto_target;
128
129  /* Set the default node used for spawning to this one,
130     and only override it if there is a valid arg.  */
131
132  nto_procfs_node = ND_LOCAL_NODE;
133  nodestr = arg ? xstrdup (arg) : arg;
134
135  init_thread_list ();
136
137  if (nodestr)
138    {
139      nto_procfs_node = netmgr_strtond (nodestr, &endstr);
140      if (nto_procfs_node == -1)
141	{
142	  if (errno == ENOTSUP)
143	    printf_filtered ("QNX Net Manager not found.\n");
144	  printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
145			   errno, safe_strerror (errno));
146	  xfree (nodestr);
147	  nodestr = NULL;
148	  nto_procfs_node = ND_LOCAL_NODE;
149	}
150      else if (*endstr)
151	{
152	  if (*(endstr - 1) == '/')
153	    *(endstr - 1) = 0;
154	  else
155	    *endstr = 0;
156	}
157    }
158  snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "",
159	    "/proc");
160  if (nodestr)
161    xfree (nodestr);
162
163  fd = open (nto_procfs_path, O_RDONLY);
164  if (fd == -1)
165    {
166      printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
167		       safe_strerror (errno));
168      error (_("Invalid procfs arg"));
169    }
170  cleanups = make_cleanup_close (fd);
171
172  sysinfo = (void *) buffer;
173  if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
174    {
175      printf_filtered ("Error getting size: %d (%s)\n", errno,
176		       safe_strerror (errno));
177      error (_("Devctl failed."));
178    }
179  else
180    {
181      total_size = sysinfo->total_size;
182      sysinfo = alloca (total_size);
183      if (!sysinfo)
184	{
185	  printf_filtered ("Memory error: %d (%s)\n", errno,
186			   safe_strerror (errno));
187	  error (_("alloca failed."));
188	}
189      else
190	{
191	  if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
192	    {
193	      printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
194			       safe_strerror (errno));
195	      error (_("Devctl failed."));
196	    }
197	  else
198	    {
199	      if (sysinfo->type !=
200		  nto_map_arch_to_cputype (gdbarch_bfd_arch_info
201					   (target_gdbarch)->arch_name))
202		error (_("Invalid target CPU."));
203	    }
204	}
205    }
206  do_cleanups (cleanups);
207  printf_filtered ("Debugging using %s\n", nto_procfs_path);
208}
209
210static void
211procfs_set_thread (ptid_t ptid)
212{
213  pid_t tid;
214
215  tid = ptid_get_tid (ptid);
216  devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
217}
218
219/*  Return nonzero if the thread TH is still alive.  */
220static int
221procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
222{
223  pid_t tid;
224  pid_t pid;
225  procfs_status status;
226  int err;
227
228  tid = ptid_get_tid (ptid);
229  pid = ptid_get_pid (ptid);
230
231  if (kill (pid, 0) == -1)
232    return 0;
233
234  status.tid = tid;
235  if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS,
236		     &status, sizeof (status), 0)) != EOK)
237    return 0;
238
239  /* Thread is alive or dead but not yet joined,
240     or dead and there is an alive (or dead unjoined) thread with
241     higher tid.
242
243     If the tid is not the same as requested, requested tid is dead.  */
244  return (status.tid == tid) && (status.state != STATE_DEAD);
245}
246
247static void
248update_thread_private_data_name (struct thread_info *new_thread,
249				 const char *newname)
250{
251  int newnamelen;
252  struct private_thread_info *pti;
253
254  gdb_assert (newname != NULL);
255  gdb_assert (new_thread != NULL);
256  newnamelen = strlen (newname);
257  if (!new_thread->private)
258    {
259      new_thread->private = xmalloc (offsetof (struct private_thread_info,
260					       name)
261				     + newnamelen + 1);
262      memcpy (new_thread->private->name, newname, newnamelen + 1);
263    }
264  else if (strcmp (newname, new_thread->private->name) != 0)
265    {
266      /* Reallocate if neccessary.  */
267      int oldnamelen = strlen (new_thread->private->name);
268
269      if (oldnamelen < newnamelen)
270	new_thread->private = xrealloc (new_thread->private,
271					offsetof (struct private_thread_info,
272						  name)
273					+ newnamelen + 1);
274      memcpy (new_thread->private->name, newname, newnamelen + 1);
275    }
276}
277
278static void
279update_thread_private_data (struct thread_info *new_thread,
280			    pthread_t tid, int state, int flags)
281{
282  struct private_thread_info *pti;
283  procfs_info pidinfo;
284  struct _thread_name *tn;
285  procfs_threadctl tctl;
286
287#if _NTO_VERSION > 630
288  gdb_assert (new_thread != NULL);
289
290  if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo,
291	      sizeof(pidinfo), 0) != EOK)
292    return;
293
294  memset (&tctl, 0, sizeof (tctl));
295  tctl.cmd = _NTO_TCTL_NAME;
296  tn = (struct _thread_name *) (&tctl.data);
297
298  /* Fetch name for the given thread.  */
299  tctl.tid = tid;
300  tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn);
301  tn->new_name_len = -1; /* Getting, not setting.  */
302  if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK)
303    tn->name_buf[0] = '\0';
304
305  tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0';
306
307  update_thread_private_data_name (new_thread, tn->name_buf);
308
309  pti = (struct private_thread_info *) new_thread->private;
310  pti->tid = tid;
311  pti->state = state;
312  pti->flags = flags;
313#endif /* _NTO_VERSION */
314}
315
316void
317procfs_find_new_threads (struct target_ops *ops)
318{
319  procfs_status status;
320  pid_t pid;
321  ptid_t ptid;
322  pthread_t tid;
323  struct thread_info *new_thread;
324
325  if (ctl_fd == -1)
326    return;
327
328  pid = ptid_get_pid (inferior_ptid);
329
330  status.tid = 1;
331
332  for (tid = 1;; ++tid)
333    {
334      if (status.tid == tid
335	  && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0)
336	      != EOK))
337	break;
338      if (status.tid != tid)
339	/* The reason why this would not be equal is that devctl might have
340	   returned different tid, meaning the requested tid no longer exists
341	   (e.g. thread exited).  */
342	continue;
343      ptid = ptid_build (pid, 0, tid);
344      new_thread = find_thread_ptid (ptid);
345      if (!new_thread)
346	new_thread = add_thread (ptid);
347      update_thread_private_data (new_thread, tid, status.state, 0);
348      status.tid++;
349    }
350  return;
351}
352
353static void
354do_closedir_cleanup (void *dir)
355{
356  closedir (dir);
357}
358
359void
360procfs_pidlist (char *args, int from_tty)
361{
362  DIR *dp = NULL;
363  struct dirent *dirp = NULL;
364  char buf[512];
365  procfs_info *pidinfo = NULL;
366  procfs_debuginfo *info = NULL;
367  procfs_status *status = NULL;
368  pid_t num_threads = 0;
369  pid_t pid;
370  char name[512];
371  struct cleanup *cleanups;
372
373  dp = opendir (nto_procfs_path);
374  if (dp == NULL)
375    {
376      fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
377			  nto_procfs_path, errno, safe_strerror (errno));
378      return;
379    }
380
381  cleanups = make_cleanup (do_closedir_cleanup, dp);
382
383  /* Start scan at first pid.  */
384  rewinddir (dp);
385
386  do
387    {
388      int fd;
389      struct cleanup *inner_cleanup;
390
391      /* Get the right pid and procfs path for the pid.  */
392      do
393	{
394	  dirp = readdir (dp);
395	  if (dirp == NULL)
396	    {
397	      do_cleanups (cleanups);
398	      return;
399	    }
400	  snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
401	  pid = atoi (dirp->d_name);
402	}
403      while (pid == 0);
404
405      /* Open the procfs path.  */
406      fd = open (buf, O_RDONLY);
407      if (fd == -1)
408	{
409	  fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
410			      buf, errno, safe_strerror (errno));
411	  do_cleanups (cleanups);
412	  return;
413	}
414      inner_cleanup = make_cleanup_close (fd);
415
416      pidinfo = (procfs_info *) buf;
417      if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
418	{
419	  fprintf_unfiltered (gdb_stderr,
420			      "devctl DCMD_PROC_INFO failed - %d (%s)\n",
421			      errno, safe_strerror (errno));
422	  break;
423	}
424      num_threads = pidinfo->num_threads;
425
426      info = (procfs_debuginfo *) buf;
427      if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
428	strcpy (name, "unavailable");
429      else
430	strcpy (name, info->path);
431
432      /* Collect state info on all the threads.  */
433      status = (procfs_status *) buf;
434      for (status->tid = 1; status->tid <= num_threads; status->tid++)
435	{
436	  if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
437	      && status->tid != 0)
438	    break;
439	  if (status->tid != 0)
440	    printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
441	}
442
443      do_cleanups (inner_cleanup);
444    }
445  while (dirp != NULL);
446
447  do_cleanups (cleanups);
448  return;
449}
450
451void
452procfs_meminfo (char *args, int from_tty)
453{
454  procfs_mapinfo *mapinfos = NULL;
455  static int num_mapinfos = 0;
456  procfs_mapinfo *mapinfo_p, *mapinfo_p2;
457  int flags = ~0, err, num, i, j;
458
459  struct
460  {
461    procfs_debuginfo info;
462    char buff[_POSIX_PATH_MAX];
463  } map;
464
465  struct info
466  {
467    unsigned addr;
468    unsigned size;
469    unsigned flags;
470    unsigned debug_vaddr;
471    unsigned long long offset;
472  };
473
474  struct printinfo
475  {
476    unsigned long long ino;
477    unsigned dev;
478    struct info text;
479    struct info data;
480    char name[256];
481  } printme;
482
483  /* Get the number of map entrys.  */
484  err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num);
485  if (err != EOK)
486    {
487      printf ("failed devctl num mapinfos - %d (%s)\n", err,
488	      safe_strerror (err));
489      return;
490    }
491
492  mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
493
494  num_mapinfos = num;
495  mapinfo_p = mapinfos;
496
497  /* Fill the map entrys.  */
498  err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num
499		* sizeof (procfs_mapinfo), &num);
500  if (err != EOK)
501    {
502      printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
503      xfree (mapinfos);
504      return;
505    }
506
507  num = min (num, num_mapinfos);
508
509  /* Run through the list of mapinfos, and store the data and text info
510     so we can print it at the bottom of the loop.  */
511  for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
512    {
513      if (!(mapinfo_p->flags & flags))
514	mapinfo_p->ino = 0;
515
516      if (mapinfo_p->ino == 0)	/* Already visited.  */
517	continue;
518
519      map.info.vaddr = mapinfo_p->vaddr;
520
521      err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
522      if (err != EOK)
523	continue;
524
525      memset (&printme, 0, sizeof printme);
526      printme.dev = mapinfo_p->dev;
527      printme.ino = mapinfo_p->ino;
528      printme.text.addr = mapinfo_p->vaddr;
529      printme.text.size = mapinfo_p->size;
530      printme.text.flags = mapinfo_p->flags;
531      printme.text.offset = mapinfo_p->offset;
532      printme.text.debug_vaddr = map.info.vaddr;
533      strcpy (printme.name, map.info.path);
534
535      /* Check for matching data.  */
536      for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
537	{
538	  if (mapinfo_p2->vaddr != mapinfo_p->vaddr
539	      && mapinfo_p2->ino == mapinfo_p->ino
540	      && mapinfo_p2->dev == mapinfo_p->dev)
541	    {
542	      map.info.vaddr = mapinfo_p2->vaddr;
543	      err =
544		devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
545	      if (err != EOK)
546		continue;
547
548	      if (strcmp (map.info.path, printme.name))
549		continue;
550
551	      /* Lower debug_vaddr is always text, if nessessary, swap.  */
552	      if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
553		{
554		  memcpy (&(printme.data), &(printme.text),
555			  sizeof (printme.data));
556		  printme.text.addr = mapinfo_p2->vaddr;
557		  printme.text.size = mapinfo_p2->size;
558		  printme.text.flags = mapinfo_p2->flags;
559		  printme.text.offset = mapinfo_p2->offset;
560		  printme.text.debug_vaddr = map.info.vaddr;
561		}
562	      else
563		{
564		  printme.data.addr = mapinfo_p2->vaddr;
565		  printme.data.size = mapinfo_p2->size;
566		  printme.data.flags = mapinfo_p2->flags;
567		  printme.data.offset = mapinfo_p2->offset;
568		  printme.data.debug_vaddr = map.info.vaddr;
569		}
570	      mapinfo_p2->ino = 0;
571	    }
572	}
573      mapinfo_p->ino = 0;
574
575      printf_filtered ("%s\n", printme.name);
576      printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
577		       printme.text.addr);
578      printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
579      printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
580      printf_filtered ("\t\toffset=%s\n", phex (printme.text.offset, 8));
581      if (printme.data.size)
582	{
583	  printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
584			   printme.data.addr);
585	  printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
586	  printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
587	  printf_filtered ("\t\toffset=%s\n", phex (printme.data.offset, 8));
588	}
589      printf_filtered ("\tdev=0x%x\n", printme.dev);
590      printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
591    }
592  xfree (mapinfos);
593  return;
594}
595
596/* Print status information about what we're accessing.  */
597static void
598procfs_files_info (struct target_ops *ignore)
599{
600  struct inferior *inf = current_inferior ();
601
602  printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
603		     inf->attach_flag ? "attached" : "child",
604		     target_pid_to_str (inferior_ptid), nto_procfs_path);
605}
606
607/* Mark our target-struct as eligible for stray "run" and "attach"
608   commands.  */
609static int
610procfs_can_run (void)
611{
612  return 1;
613}
614
615/* Attach to process PID, then initialize for debugging it.  */
616static void
617procfs_attach (struct target_ops *ops, char *args, int from_tty)
618{
619  char *exec_file;
620  int pid;
621  struct inferior *inf;
622
623  pid = parse_pid_to_attach (args);
624
625  if (pid == getpid ())
626    error (_("Attaching GDB to itself is not a good idea..."));
627
628  if (from_tty)
629    {
630      exec_file = (char *) get_exec_file (0);
631
632      if (exec_file)
633	printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
634			   target_pid_to_str (pid_to_ptid (pid)));
635      else
636	printf_unfiltered ("Attaching to %s\n",
637			   target_pid_to_str (pid_to_ptid (pid)));
638
639      gdb_flush (gdb_stdout);
640    }
641  inferior_ptid = do_attach (pid_to_ptid (pid));
642  inf = current_inferior ();
643  inferior_appeared (inf, pid);
644  inf->attach_flag = 1;
645
646  push_target (ops);
647
648  procfs_find_new_threads (ops);
649}
650
651static void
652procfs_post_attach (pid_t pid)
653{
654  if (exec_bfd)
655    solib_create_inferior_hook (0);
656}
657
658static ptid_t
659do_attach (ptid_t ptid)
660{
661  procfs_status status;
662  struct sigevent event;
663  char path[PATH_MAX];
664
665  snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
666  ctl_fd = open (path, O_RDWR);
667  if (ctl_fd == -1)
668    error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
669	   safe_strerror (errno));
670  if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
671    error (_("Couldn't stop process"));
672
673  /* Define a sigevent for process stopped notification.  */
674  event.sigev_notify = SIGEV_SIGNAL_THREAD;
675  event.sigev_signo = SIGUSR1;
676  event.sigev_code = 0;
677  event.sigev_value.sival_ptr = NULL;
678  event.sigev_priority = -1;
679  devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
680
681  if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
682      && status.flags & _DEBUG_FLAG_STOPPED)
683    SignalKill (nto_node (), PIDGET (ptid), 0, SIGCONT, 0, 0);
684  nto_init_solib_absolute_prefix ();
685  return ptid_build (PIDGET (ptid), 0, status.tid);
686}
687
688/* Ask the user what to do when an interrupt is received.  */
689static void
690interrupt_query (void)
691{
692  target_terminal_ours ();
693
694  if (query (_("Interrupted while waiting for the program.\n\
695Give up (and stop debugging it)? ")))
696    {
697      target_mourn_inferior ();
698      deprecated_throw_reason (RETURN_QUIT);
699    }
700
701  target_terminal_inferior ();
702}
703
704/* The user typed ^C twice.  */
705static void
706nto_interrupt_twice (int signo)
707{
708  signal (signo, ofunc);
709  interrupt_query ();
710  signal (signo, nto_interrupt_twice);
711}
712
713static void
714nto_interrupt (int signo)
715{
716  /* If this doesn't work, try more severe steps.  */
717  signal (signo, nto_interrupt_twice);
718
719  target_stop (inferior_ptid);
720}
721
722static ptid_t
723procfs_wait (struct target_ops *ops,
724	     ptid_t ptid, struct target_waitstatus *ourstatus, int options)
725{
726  sigset_t set;
727  siginfo_t info;
728  procfs_status status;
729  static int exit_signo = 0;	/* To track signals that cause termination.  */
730
731  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
732
733  if (ptid_equal (inferior_ptid, null_ptid))
734    {
735      ourstatus->kind = TARGET_WAITKIND_STOPPED;
736      ourstatus->value.sig = TARGET_SIGNAL_0;
737      exit_signo = 0;
738      return null_ptid;
739    }
740
741  sigemptyset (&set);
742  sigaddset (&set, SIGUSR1);
743
744  devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
745  while (!(status.flags & _DEBUG_FLAG_ISTOP))
746    {
747      ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
748      sigwaitinfo (&set, &info);
749      signal (SIGINT, ofunc);
750      devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
751    }
752
753  if (status.flags & _DEBUG_FLAG_SSTEP)
754    {
755      ourstatus->kind = TARGET_WAITKIND_STOPPED;
756      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
757    }
758  /* Was it a breakpoint?  */
759  else if (status.flags & _DEBUG_FLAG_TRACE)
760    {
761      ourstatus->kind = TARGET_WAITKIND_STOPPED;
762      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
763    }
764  else if (status.flags & _DEBUG_FLAG_ISTOP)
765    {
766      switch (status.why)
767	{
768	case _DEBUG_WHY_SIGNALLED:
769	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
770	  ourstatus->value.sig =
771	    target_signal_from_host (status.info.si_signo);
772	  exit_signo = 0;
773	  break;
774	case _DEBUG_WHY_FAULTED:
775	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
776	  if (status.info.si_signo == SIGTRAP)
777	    {
778	      ourstatus->value.sig = 0;
779	      exit_signo = 0;
780	    }
781	  else
782	    {
783	      ourstatus->value.sig =
784		target_signal_from_host (status.info.si_signo);
785	      exit_signo = ourstatus->value.sig;
786	    }
787	  break;
788
789	case _DEBUG_WHY_TERMINATED:
790	  {
791	    int waitval = 0;
792
793	    waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
794	    if (exit_signo)
795	      {
796		/* Abnormal death.  */
797		ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
798		ourstatus->value.sig = exit_signo;
799	      }
800	    else
801	      {
802		/* Normal death.  */
803		ourstatus->kind = TARGET_WAITKIND_EXITED;
804		ourstatus->value.integer = WEXITSTATUS (waitval);
805	      }
806	    exit_signo = 0;
807	    break;
808	  }
809
810	case _DEBUG_WHY_REQUESTED:
811	  /* We are assuming a requested stop is due to a SIGINT.  */
812	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
813	  ourstatus->value.sig = TARGET_SIGNAL_INT;
814	  exit_signo = 0;
815	  break;
816	}
817    }
818
819  return ptid_build (status.pid, 0, status.tid);
820}
821
822/* Read the current values of the inferior's registers, both the
823   general register set and floating point registers (if supported)
824   and update gdb's idea of their current values.  */
825static void
826procfs_fetch_registers (struct target_ops *ops,
827			struct regcache *regcache, int regno)
828{
829  union
830  {
831    procfs_greg greg;
832    procfs_fpreg fpreg;
833    procfs_altreg altreg;
834  }
835  reg;
836  int regsize;
837
838  procfs_set_thread (inferior_ptid);
839  if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
840    nto_supply_gregset (regcache, (char *) &reg.greg);
841  if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
842      == EOK)
843    nto_supply_fpregset (regcache, (char *) &reg.fpreg);
844  if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
845      == EOK)
846    nto_supply_altregset (regcache, (char *) &reg.altreg);
847}
848
849/* Copy LEN bytes to/from inferior's memory starting at MEMADDR
850   from/to debugger memory starting at MYADDR.  Copy from inferior
851   if DOWRITE is zero or to inferior if DOWRITE is nonzero.
852
853   Returns the length copied, which is either the LEN argument or
854   zero.  This xfer function does not do partial moves, since procfs_ops
855   doesn't allow memory operations to cross below us in the target stack
856   anyway.  */
857static int
858procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
859		    struct mem_attrib *attrib, struct target_ops *target)
860{
861  int nbytes = 0;
862
863  if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
864    {
865      if (dowrite)
866	nbytes = write (ctl_fd, myaddr, len);
867      else
868	nbytes = read (ctl_fd, myaddr, len);
869      if (nbytes < 0)
870	nbytes = 0;
871    }
872  return (nbytes);
873}
874
875/* Take a program previously attached to and detaches it.
876   The program resumes execution and will no longer stop
877   on signals, etc.  We'd better not have left any breakpoints
878   in the program or it'll die when it hits one.  */
879static void
880procfs_detach (struct target_ops *ops, char *args, int from_tty)
881{
882  int siggnal = 0;
883  int pid;
884
885  if (from_tty)
886    {
887      char *exec_file = get_exec_file (0);
888      if (exec_file == 0)
889	exec_file = "";
890      printf_unfiltered ("Detaching from program: %s %s\n",
891			 exec_file, target_pid_to_str (inferior_ptid));
892      gdb_flush (gdb_stdout);
893    }
894  if (args)
895    siggnal = atoi (args);
896
897  if (siggnal)
898    SignalKill (nto_node (), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
899
900  close (ctl_fd);
901  ctl_fd = -1;
902
903  pid = ptid_get_pid (inferior_ptid);
904  inferior_ptid = null_ptid;
905  detach_inferior (pid);
906  init_thread_list ();
907  unpush_target (&procfs_ops);	/* Pop out of handling an inferior.  */
908}
909
910static int
911procfs_breakpoint (CORE_ADDR addr, int type, int size)
912{
913  procfs_break brk;
914
915  brk.type = type;
916  brk.addr = addr;
917  brk.size = size;
918  errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
919  if (errno != EOK)
920    return 1;
921  return 0;
922}
923
924static int
925procfs_insert_breakpoint (struct gdbarch *gdbarch,
926			  struct bp_target_info *bp_tgt)
927{
928  return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
929}
930
931static int
932procfs_remove_breakpoint (struct gdbarch *gdbarch,
933			  struct bp_target_info *bp_tgt)
934{
935  return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
936}
937
938static int
939procfs_insert_hw_breakpoint (struct gdbarch *gdbarch,
940			     struct bp_target_info *bp_tgt)
941{
942  return procfs_breakpoint (bp_tgt->placed_address,
943			    _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
944}
945
946static int
947procfs_remove_hw_breakpoint (struct gdbarch *gdbarch,
948			     struct bp_target_info *bp_tgt)
949{
950  return procfs_breakpoint (bp_tgt->placed_address,
951			    _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
952}
953
954static void
955procfs_resume (struct target_ops *ops,
956	       ptid_t ptid, int step, enum target_signal signo)
957{
958  int signal_to_pass;
959  procfs_status status;
960  sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
961
962  if (ptid_equal (inferior_ptid, null_ptid))
963    return;
964
965  procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
966		     ptid);
967
968  run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
969  if (step)
970    run.flags |= _DEBUG_RUN_STEP;
971
972  sigemptyset (run_fault);
973  sigaddset (run_fault, FLTBPT);
974  sigaddset (run_fault, FLTTRACE);
975  sigaddset (run_fault, FLTILL);
976  sigaddset (run_fault, FLTPRIV);
977  sigaddset (run_fault, FLTBOUNDS);
978  sigaddset (run_fault, FLTIOVF);
979  sigaddset (run_fault, FLTIZDIV);
980  sigaddset (run_fault, FLTFPE);
981  /* Peter V will be changing this at some point.  */
982  sigaddset (run_fault, FLTPAGE);
983
984  run.flags |= _DEBUG_RUN_ARM;
985
986  sigemptyset (&run.trace);
987  notice_signals ();
988  signal_to_pass = target_signal_to_host (signo);
989
990  if (signal_to_pass)
991    {
992      devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
993      signal_to_pass = target_signal_to_host (signo);
994      if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
995	{
996	  if (signal_to_pass != status.info.si_signo)
997	    {
998	      SignalKill (nto_node (), PIDGET (inferior_ptid), 0,
999			  signal_to_pass, 0, 0);
1000	      run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
1001	    }
1002	  else		/* Let it kill the program without telling us.  */
1003	    sigdelset (&run.trace, signal_to_pass);
1004	}
1005    }
1006  else
1007    run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
1008
1009  errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
1010  if (errno != EOK)
1011    {
1012      perror (_("run error!\n"));
1013      return;
1014    }
1015}
1016
1017static void
1018procfs_mourn_inferior (struct target_ops *ops)
1019{
1020  if (!ptid_equal (inferior_ptid, null_ptid))
1021    {
1022      SignalKill (nto_node (), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
1023      close (ctl_fd);
1024    }
1025  inferior_ptid = null_ptid;
1026  init_thread_list ();
1027  unpush_target (&procfs_ops);
1028  generic_mourn_inferior ();
1029}
1030
1031/* This function breaks up an argument string into an argument
1032   vector suitable for passing to execvp().
1033   E.g., on "run a b c d" this routine would get as input
1034   the string "a b c d", and as output it would fill in argv with
1035   the four arguments "a", "b", "c", "d".  The only additional
1036   functionality is simple quoting.  The gdb command:
1037  	run a "b c d" f
1038   will fill in argv with the three args "a", "b c d", "e".  */
1039static void
1040breakup_args (char *scratch, char **argv)
1041{
1042  char *pp, *cp = scratch;
1043  char quoting = 0;
1044
1045  for (;;)
1046    {
1047      /* Scan past leading separators.  */
1048      quoting = 0;
1049      while (*cp == ' ' || *cp == '\t' || *cp == '\n')
1050	cp++;
1051
1052      /* Break if at end of string.  */
1053      if (*cp == '\0')
1054	break;
1055
1056      /* Take an arg.  */
1057      if (*cp == '"')
1058	{
1059	  cp++;
1060	  quoting = strchr (cp, '"') ? 1 : 0;
1061	}
1062
1063      *argv++ = cp;
1064
1065      /* Scan for next arg separator.  */
1066      pp = cp;
1067      if (quoting)
1068	cp = strchr (pp, '"');
1069      if ((cp == NULL) || (!quoting))
1070	cp = strchr (pp, ' ');
1071      if (cp == NULL)
1072	cp = strchr (pp, '\t');
1073      if (cp == NULL)
1074	cp = strchr (pp, '\n');
1075
1076      /* No separators => end of string => break.  */
1077      if (cp == NULL)
1078	{
1079	  pp = cp;
1080	  break;
1081	}
1082
1083      /* Replace the separator with a terminator.  */
1084      *cp++ = '\0';
1085    }
1086
1087  /* Execv requires a null-terminated arg vector.  */
1088  *argv = NULL;
1089}
1090
1091static void
1092procfs_create_inferior (struct target_ops *ops, char *exec_file,
1093			char *allargs, char **env, int from_tty)
1094{
1095  struct inheritance inherit;
1096  pid_t pid;
1097  int flags, errn;
1098  char **argv, *args;
1099  const char *in = "", *out = "", *err = "";
1100  int fd, fds[3];
1101  sigset_t set;
1102  const char *inferior_io_terminal = get_inferior_io_terminal ();
1103  struct inferior *inf;
1104
1105  argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
1106		  sizeof (*argv));
1107  argv[0] = get_exec_file (1);
1108  if (!argv[0])
1109    {
1110      if (exec_file)
1111	argv[0] = exec_file;
1112      else
1113	return;
1114    }
1115
1116  args = xstrdup (allargs);
1117  breakup_args (args, exec_file ? &argv[1] : &argv[0]);
1118
1119  argv = nto_parse_redirection (argv, &in, &out, &err);
1120
1121  fds[0] = STDIN_FILENO;
1122  fds[1] = STDOUT_FILENO;
1123  fds[2] = STDERR_FILENO;
1124
1125  /* If the user specified I/O via gdb's --tty= arg, use it, but only
1126     if the i/o is not also being specified via redirection.  */
1127  if (inferior_io_terminal)
1128    {
1129      if (!in[0])
1130	in = inferior_io_terminal;
1131      if (!out[0])
1132	out = inferior_io_terminal;
1133      if (!err[0])
1134	err = inferior_io_terminal;
1135    }
1136
1137  if (in[0])
1138    {
1139      fd = open (in, O_RDONLY);
1140      if (fd == -1)
1141	perror (in);
1142      else
1143	fds[0] = fd;
1144    }
1145  if (out[0])
1146    {
1147      fd = open (out, O_WRONLY);
1148      if (fd == -1)
1149	perror (out);
1150      else
1151	fds[1] = fd;
1152    }
1153  if (err[0])
1154    {
1155      fd = open (err, O_WRONLY);
1156      if (fd == -1)
1157	perror (err);
1158      else
1159	fds[2] = fd;
1160    }
1161
1162  /* Clear any pending SIGUSR1's but keep the behavior the same.  */
1163  signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
1164
1165  sigemptyset (&set);
1166  sigaddset (&set, SIGUSR1);
1167  sigprocmask (SIG_UNBLOCK, &set, NULL);
1168
1169  memset (&inherit, 0, sizeof (inherit));
1170
1171  if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
1172    {
1173      inherit.nd = nto_node ();
1174      inherit.flags |= SPAWN_SETND;
1175      inherit.flags &= ~SPAWN_EXEC;
1176    }
1177  inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
1178  inherit.pgroup = SPAWN_NEWPGROUP;
1179  pid = spawnp (argv[0], 3, fds, &inherit, argv,
1180		ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
1181  xfree (args);
1182
1183  sigprocmask (SIG_BLOCK, &set, NULL);
1184
1185  if (pid == -1)
1186    error (_("Error spawning %s: %d (%s)"), argv[0], errno,
1187	   safe_strerror (errno));
1188
1189  if (fds[0] != STDIN_FILENO)
1190    close (fds[0]);
1191  if (fds[1] != STDOUT_FILENO)
1192    close (fds[1]);
1193  if (fds[2] != STDERR_FILENO)
1194    close (fds[2]);
1195
1196  inferior_ptid = do_attach (pid_to_ptid (pid));
1197  procfs_find_new_threads (ops);
1198
1199  inf = current_inferior ();
1200  inferior_appeared (inf, pid);
1201  inf->attach_flag = 0;
1202
1203  flags = _DEBUG_FLAG_KLC;	/* Kill-on-Last-Close flag.  */
1204  errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
1205  if (errn != EOK)
1206    {
1207      /* FIXME: expected warning?  */
1208      /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
1209         errn, strerror(errn) ); */
1210    }
1211  push_target (ops);
1212  target_terminal_init ();
1213
1214  if (exec_bfd != NULL
1215      || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
1216    solib_create_inferior_hook (0);
1217}
1218
1219static void
1220procfs_stop (ptid_t ptid)
1221{
1222  devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1223}
1224
1225static void
1226procfs_kill_inferior (struct target_ops *ops)
1227{
1228  target_mourn_inferior ();
1229}
1230
1231/* Store register REGNO, or all registers if REGNO == -1, from the contents
1232   of REGISTERS.  */
1233static void
1234procfs_prepare_to_store (struct regcache *regcache)
1235{
1236}
1237
1238/* Fill buf with regset and return devctl cmd to do the setting.  Return
1239   -1 if we fail to get the regset.  Store size of regset in regsize.  */
1240static int
1241get_regset (int regset, char *buf, int bufsize, int *regsize)
1242{
1243  int dev_get, dev_set;
1244  switch (regset)
1245    {
1246    case NTO_REG_GENERAL:
1247      dev_get = DCMD_PROC_GETGREG;
1248      dev_set = DCMD_PROC_SETGREG;
1249      break;
1250
1251    case NTO_REG_FLOAT:
1252      dev_get = DCMD_PROC_GETFPREG;
1253      dev_set = DCMD_PROC_SETFPREG;
1254      break;
1255
1256    case NTO_REG_ALT:
1257      dev_get = DCMD_PROC_GETALTREG;
1258      dev_set = DCMD_PROC_SETALTREG;
1259      break;
1260
1261    case NTO_REG_SYSTEM:
1262    default:
1263      return -1;
1264    }
1265  if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK)
1266    return -1;
1267
1268  return dev_set;
1269}
1270
1271void
1272procfs_store_registers (struct target_ops *ops,
1273			struct regcache *regcache, int regno)
1274{
1275  union
1276  {
1277    procfs_greg greg;
1278    procfs_fpreg fpreg;
1279    procfs_altreg altreg;
1280  }
1281  reg;
1282  unsigned off;
1283  int len, regset, regsize, dev_set, err;
1284  char *data;
1285
1286  if (ptid_equal (inferior_ptid, null_ptid))
1287    return;
1288  procfs_set_thread (inferior_ptid);
1289
1290  if (regno == -1)
1291    {
1292      for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
1293	{
1294	  dev_set = get_regset (regset, (char *) &reg,
1295				sizeof (reg), &regsize);
1296	  if (dev_set == -1)
1297	    continue;
1298
1299	  if (nto_regset_fill (regcache, regset, (char *) &reg) == -1)
1300	    continue;
1301
1302	  err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1303	  if (err != EOK)
1304	    fprintf_unfiltered (gdb_stderr,
1305				"Warning unable to write regset %d: %s\n",
1306				regno, safe_strerror (err));
1307	}
1308    }
1309  else
1310    {
1311      regset = nto_regset_id (regno);
1312      if (regset == -1)
1313	return;
1314
1315      dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
1316      if (dev_set == -1)
1317	return;
1318
1319      len = nto_register_area (get_regcache_arch (regcache),
1320			       regno, regset, &off);
1321
1322      if (len < 1)
1323	return;
1324
1325      regcache_raw_collect (regcache, regno, (char *) &reg + off);
1326
1327      err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1328      if (err != EOK)
1329	fprintf_unfiltered (gdb_stderr,
1330			    "Warning unable to write regset %d: %s\n", regno,
1331			    safe_strerror (err));
1332    }
1333}
1334
1335static void
1336notice_signals (void)
1337{
1338  int signo;
1339
1340  for (signo = 1; signo < NSIG; signo++)
1341    {
1342      if (signal_stop_state (target_signal_from_host (signo)) == 0
1343	  && signal_print_state (target_signal_from_host (signo)) == 0
1344	  && signal_pass_state (target_signal_from_host (signo)) == 1)
1345	sigdelset (&run.trace, signo);
1346      else
1347	sigaddset (&run.trace, signo);
1348    }
1349}
1350
1351/* When the user changes the state of gdb's signal handling via the
1352   "handle" command, this function gets called to see if any change
1353   in the /proc interface is required.  It is also called internally
1354   by other /proc interface functions to initialize the state of
1355   the traced signal set.  */
1356static void
1357procfs_notice_signals (ptid_t ptid)
1358{
1359  sigemptyset (&run.trace);
1360  notice_signals ();
1361}
1362
1363static struct tidinfo *
1364procfs_thread_info (pid_t pid, short tid)
1365{
1366/* NYI */
1367  return NULL;
1368}
1369
1370char *
1371procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
1372{
1373  static char buf[1024];
1374  int pid, tid, n;
1375  struct tidinfo *tip;
1376
1377  pid = ptid_get_pid (ptid);
1378  tid = ptid_get_tid (ptid);
1379
1380  n = snprintf (buf, 1023, "process %d", pid);
1381
1382#if 0				/* NYI */
1383  tip = procfs_thread_info (pid, tid);
1384  if (tip != NULL)
1385    snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
1386#endif
1387
1388  return buf;
1389}
1390
1391static void
1392init_procfs_ops (void)
1393{
1394  procfs_ops.to_shortname = "procfs";
1395  procfs_ops.to_longname = "QNX Neutrino procfs child process";
1396  procfs_ops.to_doc =
1397    "QNX Neutrino procfs child process (started by the \"run\" command).\n\
1398	target procfs <node>";
1399  procfs_ops.to_open = procfs_open;
1400  procfs_ops.to_attach = procfs_attach;
1401  procfs_ops.to_post_attach = procfs_post_attach;
1402  procfs_ops.to_detach = procfs_detach;
1403  procfs_ops.to_resume = procfs_resume;
1404  procfs_ops.to_wait = procfs_wait;
1405  procfs_ops.to_fetch_registers = procfs_fetch_registers;
1406  procfs_ops.to_store_registers = procfs_store_registers;
1407  procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
1408  procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
1409  procfs_ops.to_files_info = procfs_files_info;
1410  procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
1411  procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
1412  procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
1413  procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
1414  procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
1415  procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
1416  procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
1417  procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
1418  procfs_ops.to_terminal_init = terminal_init_inferior;
1419  procfs_ops.to_terminal_inferior = terminal_inferior;
1420  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1421  procfs_ops.to_terminal_ours = terminal_ours;
1422  procfs_ops.to_terminal_info = child_terminal_info;
1423  procfs_ops.to_kill = procfs_kill_inferior;
1424  procfs_ops.to_create_inferior = procfs_create_inferior;
1425  procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
1426  procfs_ops.to_can_run = procfs_can_run;
1427  procfs_ops.to_notice_signals = procfs_notice_signals;
1428  procfs_ops.to_thread_alive = procfs_thread_alive;
1429  procfs_ops.to_find_new_threads = procfs_find_new_threads;
1430  procfs_ops.to_pid_to_str = procfs_pid_to_str;
1431  procfs_ops.to_stop = procfs_stop;
1432  procfs_ops.to_stratum = process_stratum;
1433  procfs_ops.to_has_all_memory = default_child_has_all_memory;
1434  procfs_ops.to_has_memory = default_child_has_memory;
1435  procfs_ops.to_has_stack = default_child_has_stack;
1436  procfs_ops.to_has_registers = default_child_has_registers;
1437  procfs_ops.to_has_execution = default_child_has_execution;
1438  procfs_ops.to_magic = OPS_MAGIC;
1439  procfs_ops.to_have_continuable_watchpoint = 1;
1440  procfs_ops.to_extra_thread_info = nto_extra_thread_info;
1441}
1442
1443#define OSTYPE_NTO 1
1444
1445void
1446_initialize_procfs (void)
1447{
1448  sigset_t set;
1449
1450  init_procfs_ops ();
1451  add_target (&procfs_ops);
1452
1453  /* We use SIGUSR1 to gain control after we block waiting for a process.
1454     We use sigwaitevent to wait.  */
1455  sigemptyset (&set);
1456  sigaddset (&set, SIGUSR1);
1457  sigprocmask (SIG_BLOCK, &set, NULL);
1458
1459  /* Set up trace and fault sets, as gdb expects them.  */
1460  sigemptyset (&run.trace);
1461
1462  /* Stuff some information.  */
1463  nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1464  nto_cpuinfo_valid = 1;
1465
1466  add_info ("pidlist", procfs_pidlist, _("pidlist"));
1467  add_info ("meminfo", procfs_meminfo, _("memory information"));
1468
1469  nto_is_nto_target = procfs_is_nto_target;
1470}
1471
1472
1473static int
1474procfs_hw_watchpoint (int addr, int len, int type)
1475{
1476  procfs_break brk;
1477
1478  switch (type)
1479    {
1480    case 1:			/* Read.  */
1481      brk.type = _DEBUG_BREAK_RD;
1482      break;
1483    case 2:			/* Read/Write.  */
1484      brk.type = _DEBUG_BREAK_RW;
1485      break;
1486    default:			/* Modify.  */
1487/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason.  */
1488      brk.type = _DEBUG_BREAK_RW;
1489    }
1490  brk.type |= _DEBUG_BREAK_HW;	/* Always ask for HW.  */
1491  brk.addr = addr;
1492  brk.size = len;
1493
1494  errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
1495  if (errno != EOK)
1496    {
1497      perror (_("Failed to set hardware watchpoint"));
1498      return -1;
1499    }
1500  return 0;
1501}
1502
1503static int
1504procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1505{
1506  return 1;
1507}
1508
1509static int
1510procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type,
1511			     struct expression *cond)
1512{
1513  return procfs_hw_watchpoint (addr, -1, type);
1514}
1515
1516static int
1517procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type,
1518			     struct expression *cond)
1519{
1520  return procfs_hw_watchpoint (addr, len, type);
1521}
1522
1523static int
1524procfs_stopped_by_watchpoint (void)
1525{
1526  return 0;
1527}
1528