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{
968  struct inheritance inherit;
969  pid_t pid;
970  int flags, errn;
971  char **argv, *args;
972  char *in = "", *out = "", *err = "";
973  int fd, fds[3];
974  sigset_t set;
975
976  argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
977		  sizeof (*argv));
978  argv[0] = get_exec_file (1);
979  if (!argv[0])
980    {
981      if (exec_file)
982	argv[0] = exec_file;
983      else
984	return;
985    }
986
987  args = xstrdup (allargs);
988  breakup_args (args, exec_file ? &argv[1] : &argv[0]);
989
990  argv = nto_parse_redirection (argv, &in, &out, &err);
991
992  fds[0] = STDIN_FILENO;
993  fds[1] = STDOUT_FILENO;
994  fds[2] = STDERR_FILENO;
995
996  /* If the user specified I/O via gdb's --tty= arg, use it, but only
997     if the i/o is not also being specified via redirection.  */
998  if (inferior_io_terminal)
999    {
1000      if (!in[0])
1001	in = inferior_io_terminal;
1002      if (!out[0])
1003	out = inferior_io_terminal;
1004      if (!err[0])
1005	err = inferior_io_terminal;
1006    }
1007
1008  if (in[0])
1009    {
1010      fd = open (in, O_RDONLY);
1011      if (fd == -1)
1012	perror (in);
1013      else
1014	fds[0] = fd;
1015    }
1016  if (out[0])
1017    {
1018      fd = open (out, O_WRONLY);
1019      if (fd == -1)
1020	perror (out);
1021      else
1022	fds[1] = fd;
1023    }
1024  if (err[0])
1025    {
1026      fd = open (err, O_WRONLY);
1027      if (fd == -1)
1028	perror (err);
1029      else
1030	fds[2] = fd;
1031    }
1032
1033  /* Clear any pending SIGUSR1's but keep the behavior the same.  */
1034  signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
1035
1036  sigemptyset (&set);
1037  sigaddset (&set, SIGUSR1);
1038  sigprocmask (SIG_UNBLOCK, &set, NULL);
1039
1040  memset (&inherit, 0, sizeof (inherit));
1041
1042  if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
1043    {
1044      inherit.nd = nto_node();
1045      inherit.flags |= SPAWN_SETND;
1046      inherit.flags &= ~SPAWN_EXEC;
1047    }
1048  inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
1049  inherit.pgroup = SPAWN_NEWPGROUP;
1050  pid = spawnp (argv[0], 3, fds, &inherit, argv,
1051		ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
1052  xfree (args);
1053
1054  sigprocmask (SIG_BLOCK, &set, NULL);
1055
1056  if (pid == -1)
1057    error ("Error spawning %s: %d (%s)", argv[0], errno, safe_strerror (errno));
1058
1059  if (fds[0] != STDIN_FILENO)
1060    close (fds[0]);
1061  if (fds[1] != STDOUT_FILENO)
1062    close (fds[1]);
1063  if (fds[2] != STDERR_FILENO)
1064    close (fds[2]);
1065
1066  inferior_ptid = do_attach (pid_to_ptid (pid));
1067
1068  attach_flag = 0;
1069  flags = _DEBUG_FLAG_KLC;	/* Kill-on-Last-Close flag.  */
1070  errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
1071  if (errn != EOK)
1072    {
1073      /* FIXME: expected warning?  */
1074      /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
1075         errn, strerror(errn) ); */
1076    }
1077  push_target (&procfs_ops);
1078  target_terminal_init ();
1079
1080#ifdef SOLIB_CREATE_INFERIOR_HOOK
1081  if (exec_bfd != NULL
1082      || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
1083    SOLIB_CREATE_INFERIOR_HOOK (pid);
1084#endif
1085}
1086
1087static void
1088procfs_stop (void)
1089{
1090  devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1091}
1092
1093static void
1094procfs_kill_inferior (void)
1095{
1096  target_mourn_inferior ();
1097}
1098
1099/* Store register REGNO, or all registers if REGNO == -1, from the contents
1100   of REGISTERS.  */
1101static void
1102procfs_prepare_to_store (void)
1103{
1104}
1105
1106/* Fill buf with regset and return devctl cmd to do the setting.  Return
1107   -1 if we fail to get the regset.  Store size of regset in regsize.  */
1108static int
1109get_regset (int regset, char *buf, int bufsize, int *regsize)
1110{
1111  int dev_get, dev_set;
1112  switch (regset)
1113    {
1114    case NTO_REG_GENERAL:
1115      dev_get = DCMD_PROC_GETGREG;
1116      dev_set = DCMD_PROC_SETGREG;
1117      break;
1118
1119    case NTO_REG_FLOAT:
1120      dev_get = DCMD_PROC_GETFPREG;
1121      dev_set = DCMD_PROC_SETFPREG;
1122      break;
1123
1124    case NTO_REG_ALT:
1125      dev_get = DCMD_PROC_GETALTREG;
1126      dev_set = DCMD_PROC_SETALTREG;
1127      break;
1128
1129    case NTO_REG_SYSTEM:
1130    default:
1131      return -1;
1132    }
1133  if (devctl (ctl_fd, dev_get, &buf, bufsize, regsize) != EOK)
1134    return -1;
1135
1136  return dev_set;
1137}
1138
1139void
1140procfs_store_registers (int regno)
1141{
1142  union
1143  {
1144    procfs_greg greg;
1145    procfs_fpreg fpreg;
1146    procfs_altreg altreg;
1147  }
1148  reg;
1149  unsigned off;
1150  int len, regset, regsize, dev_set, err;
1151  char *data;
1152
1153  if (ptid_equal (inferior_ptid, null_ptid))
1154    return;
1155  procfs_set_thread (inferior_ptid);
1156
1157  if (regno == -1)
1158    {
1159      for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
1160	{
1161	  dev_set = get_regset (regset, (char *) &reg,
1162				sizeof (reg), &regsize);
1163	  if (dev_set == -1)
1164	    continue;
1165
1166	  if (nto_regset_fill (regset, (char *) &reg) == -1)
1167	    continue;
1168
1169	  err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1170	  if (err != EOK)
1171	    fprintf_unfiltered (gdb_stderr,
1172				"Warning unable to write regset %d: %s\n",
1173				regno, safe_strerror (err));
1174	}
1175    }
1176  else
1177    {
1178      regset = nto_regset_id (regno);
1179      if (regset == -1)
1180	return;
1181
1182      dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
1183      if (dev_set == -1)
1184	return;
1185
1186      len = nto_register_area (regno, regset, &off);
1187
1188      if (len < 1)
1189	return;
1190
1191      regcache_collect (regno, (char *) &reg + off);
1192
1193      err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1194      if (err != EOK)
1195	fprintf_unfiltered (gdb_stderr,
1196			    "Warning unable to write regset %d: %s\n", regno,
1197			    safe_strerror (err));
1198    }
1199}
1200
1201static void
1202notice_signals (void)
1203{
1204  int signo;
1205
1206  for (signo = 1; signo < NSIG; signo++)
1207    {
1208      if (signal_stop_state (target_signal_from_host (signo)) == 0
1209	  && signal_print_state (target_signal_from_host (signo)) == 0
1210	  && signal_pass_state (target_signal_from_host (signo)) == 1)
1211	sigdelset (&run.trace, signo);
1212      else
1213	sigaddset (&run.trace, signo);
1214    }
1215}
1216
1217/* When the user changes the state of gdb's signal handling via the
1218   "handle" command, this function gets called to see if any change
1219   in the /proc interface is required.  It is also called internally
1220   by other /proc interface functions to initialize the state of
1221   the traced signal set.  */
1222static void
1223procfs_notice_signals (ptid_t ptid)
1224{
1225  sigemptyset (&run.trace);
1226  notice_signals ();
1227}
1228
1229static struct tidinfo *
1230procfs_thread_info (pid_t pid, short tid)
1231{
1232/* NYI */
1233  return NULL;
1234}
1235
1236char *
1237procfs_pid_to_str (ptid_t ptid)
1238{
1239  static char buf[1024];
1240  int pid, tid, n;
1241  struct tidinfo *tip;
1242
1243  pid = ptid_get_pid (ptid);
1244  tid = ptid_get_tid (ptid);
1245
1246  n = snprintf (buf, 1023, "process %d", pid);
1247
1248#if 0				/* NYI */
1249  tip = procfs_thread_info (pid, tid);
1250  if (tip != NULL)
1251    snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
1252#endif
1253
1254  return buf;
1255}
1256
1257static void
1258init_procfs_ops (void)
1259{
1260  procfs_ops.to_shortname = "procfs";
1261  procfs_ops.to_longname = "QNX Neutrino procfs child process";
1262  procfs_ops.to_doc =
1263    "QNX Neutrino procfs child process (started by the \"run\" command).\n\
1264	target procfs <node>";
1265  procfs_ops.to_open = procfs_open;
1266  procfs_ops.to_attach = procfs_attach;
1267  procfs_ops.to_post_attach = procfs_post_attach;
1268  procfs_ops.to_detach = procfs_detach;
1269  procfs_ops.to_resume = procfs_resume;
1270  procfs_ops.to_wait = procfs_wait;
1271  procfs_ops.to_fetch_registers = procfs_fetch_registers;
1272  procfs_ops.to_store_registers = procfs_store_registers;
1273  procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
1274  procfs_ops.to_xfer_memory = procfs_xfer_memory;
1275  procfs_ops.to_files_info = procfs_files_info;
1276  procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
1277  procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
1278  procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
1279  procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
1280  procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
1281  procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
1282  procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
1283  procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
1284  procfs_ops.to_terminal_init = terminal_init_inferior;
1285  procfs_ops.to_terminal_inferior = terminal_inferior;
1286  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1287  procfs_ops.to_terminal_ours = terminal_ours;
1288  procfs_ops.to_terminal_info = child_terminal_info;
1289  procfs_ops.to_kill = procfs_kill_inferior;
1290  procfs_ops.to_create_inferior = procfs_create_inferior;
1291  procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
1292  procfs_ops.to_can_run = procfs_can_run;
1293  procfs_ops.to_notice_signals = procfs_notice_signals;
1294  procfs_ops.to_thread_alive = procfs_thread_alive;
1295  procfs_ops.to_find_new_threads = procfs_find_new_threads;
1296  procfs_ops.to_pid_to_str = procfs_pid_to_str;
1297  procfs_ops.to_stop = procfs_stop;
1298  procfs_ops.to_stratum = process_stratum;
1299  procfs_ops.to_has_all_memory = 1;
1300  procfs_ops.to_has_memory = 1;
1301  procfs_ops.to_has_stack = 1;
1302  procfs_ops.to_has_registers = 1;
1303  procfs_ops.to_has_execution = 1;
1304  procfs_ops.to_magic = OPS_MAGIC;
1305  procfs_ops.to_have_continuable_watchpoint = 1;
1306}
1307
1308#define OSTYPE_NTO 1
1309
1310void
1311_initialize_procfs (void)
1312{
1313  sigset_t set;
1314
1315  init_procfs_ops ();
1316  add_target (&procfs_ops);
1317
1318  /* We use SIGUSR1 to gain control after we block waiting for a process.
1319     We use sigwaitevent to wait.  */
1320  sigemptyset (&set);
1321  sigaddset (&set, SIGUSR1);
1322  sigprocmask (SIG_BLOCK, &set, NULL);
1323
1324  /* Set up trace and fault sets, as gdb expects them.  */
1325  sigemptyset (&run.trace);
1326  notice_signals ();
1327
1328  /* Stuff some information.  */
1329  nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1330  nto_cpuinfo_valid = 1;
1331
1332  add_info ("pidlist", procfs_pidlist, "pidlist");
1333  add_info ("meminfo", procfs_meminfo, "memory information");
1334}
1335
1336
1337static int
1338procfs_hw_watchpoint (int addr, int len, int type)
1339{
1340  procfs_break brk;
1341
1342  switch (type)
1343    {
1344    case 1:			/* Read.  */
1345      brk.type = _DEBUG_BREAK_RD;
1346      break;
1347    case 2:			/* Read/Write.  */
1348      brk.type = _DEBUG_BREAK_RW;
1349      break;
1350    default:			/* Modify.  */
1351/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason.  */
1352      brk.type = _DEBUG_BREAK_RW;
1353    }
1354  brk.type |= _DEBUG_BREAK_HW;	/* Always ask for HW.  */
1355  brk.addr = addr;
1356  brk.size = len;
1357
1358  errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
1359  if (errno != EOK)
1360    {
1361      perror ("Failed to set hardware watchpoint");
1362      return -1;
1363    }
1364  return 0;
1365}
1366
1367static int
1368procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1369{
1370  return 1;
1371}
1372
1373static int
1374procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1375{
1376  return procfs_hw_watchpoint (addr, -1, type);
1377}
1378
1379static int
1380procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1381{
1382  return procfs_hw_watchpoint (addr, len, type);
1383}
1384
1385static int
1386procfs_stopped_by_watchpoint (void)
1387{
1388  return 0;
1389}
1390