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