xref: /openbsd/gnu/usr.bin/binutils/gdb/nto-procfs.c (revision 11efff7f)
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 
50 static struct target_ops procfs_ops;
51 
52 int ctl_fd;
53 
54 static void (*ofunc) ();
55 
56 static procfs_run run;
57 
58 static void procfs_open (char *, int);
59 
60 static int procfs_can_run (void);
61 
62 static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
63 
64 static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
65 			       struct mem_attrib *attrib,
66 			       struct target_ops *);
67 
68 static void procfs_fetch_registers (int);
69 
70 static void notice_signals (void);
71 
72 static void init_procfs_ops (void);
73 
74 static ptid_t do_attach (ptid_t ptid);
75 
76 static int procfs_can_use_hw_breakpoint (int, int, int);
77 
78 static int procfs_insert_hw_breakpoint (CORE_ADDR, char *);
79 
80 static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *);
81 
82 static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
83 
84 static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
85 
86 static 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.  */
92 static char nto_procfs_path[PATH_MAX] = { "/proc" };
93 static 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.  */
99 static unsigned
nto_node(void)100 nto_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.  */
118 static void
procfs_open(char * arg,int from_tty)119 procfs_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 
211 static void
procfs_set_thread(ptid_t ptid)212 procfs_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.  */
221 static int
procfs_thread_alive(ptid_t ptid)222 procfs_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 
232 void
procfs_find_new_threads(void)233 procfs_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 
256 void
procfs_pidlist(char * args,int from_tty)257 procfs_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 
342 void
procfs_meminfo(char * args,int from_tty)343 procfs_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.  */
487 static void
procfs_files_info(struct target_ops * ignore)488 procfs_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.  */
496 static int
procfs_can_run(void)497 procfs_can_run (void)
498 {
499   return 1;
500 }
501 
502 /* Attach to process PID, then initialize for debugging it.  */
503 static void
procfs_attach(char * args,int from_tty)504 procfs_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 
534 static void
procfs_post_attach(pid_t pid)535 procfs_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 
543 static ptid_t
do_attach(ptid_t ptid)544 do_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.  */
575 static void
interrupt_query(void)576 interrupt_query (void)
577 {
578   target_terminal_ours ();
579 
580   if (query ("Interrupted while waiting for the program.\n\
581 Give 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.  */
591 static void
nto_interrupt_twice(int signo)592 nto_interrupt_twice (int signo)
593 {
594   signal (signo, ofunc);
595   interrupt_query ();
596   signal (signo, nto_interrupt_twice);
597 }
598 
599 static void
nto_interrupt(int signo)600 nto_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 
608 static ptid_t
procfs_wait(ptid_t ptid,struct target_waitstatus * ourstatus)609 procfs_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.  */
710 static void
procfs_fetch_registers(int regno)711 procfs_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.  */
741 static int
procfs_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int dowrite,struct mem_attrib * attrib,struct target_ops * target)742 procfs_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.  */
763 static void
procfs_detach(char * args,int from_tty)764 procfs_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 
791 static int
procfs_breakpoint(CORE_ADDR addr,int type,int size)792 procfs_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 
805 static int
procfs_insert_breakpoint(CORE_ADDR addr,char * contents_cache)806 procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
807 {
808   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
809 }
810 
811 static int
procfs_remove_breakpoint(CORE_ADDR addr,char * contents_cache)812 procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
813 {
814   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
815 }
816 
817 static int
procfs_insert_hw_breakpoint(CORE_ADDR addr,char * contents_cache)818 procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
819 {
820   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
821 }
822 
823 static int
procfs_remove_hw_breakpoint(CORE_ADDR addr,char * contents_cache)824 procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
825 {
826   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
827 }
828 
829 static void
procfs_resume(ptid_t ptid,int step,enum target_signal signo)830 procfs_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 
890 static void
procfs_mourn_inferior(void)891 procfs_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".  */
913 static void
breakup_args(char * scratch,char ** argv)914 breakup_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 
965 static void
procfs_create_inferior(char * exec_file,char * allargs,char ** env,int from_tty)966 procfs_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 
1088 static void
procfs_stop(void)1089 procfs_stop (void)
1090 {
1091   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1092 }
1093 
1094 static void
procfs_kill_inferior(void)1095 procfs_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.  */
1102 static void
procfs_prepare_to_store(void)1103 procfs_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.  */
1109 static int
get_regset(int regset,char * buf,int bufsize,int * regsize)1110 get_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 
1140 void
procfs_store_registers(int regno)1141 procfs_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 
1202 static void
notice_signals(void)1203 notice_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.  */
1223 static void
procfs_notice_signals(ptid_t ptid)1224 procfs_notice_signals (ptid_t ptid)
1225 {
1226   sigemptyset (&run.trace);
1227   notice_signals ();
1228 }
1229 
1230 static struct tidinfo *
procfs_thread_info(pid_t pid,short tid)1231 procfs_thread_info (pid_t pid, short tid)
1232 {
1233 /* NYI */
1234   return NULL;
1235 }
1236 
1237 char *
procfs_pid_to_str(ptid_t ptid)1238 procfs_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 
1258 static void
init_procfs_ops(void)1259 init_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 
1311 void
_initialize_procfs(void)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 
1338 static int
procfs_hw_watchpoint(int addr,int len,int type)1339 procfs_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 
1368 static int
procfs_can_use_hw_breakpoint(int type,int cnt,int othertype)1369 procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1370 {
1371   return 1;
1372 }
1373 
1374 static int
procfs_remove_hw_watchpoint(CORE_ADDR addr,int len,int type)1375 procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1376 {
1377   return procfs_hw_watchpoint (addr, -1, type);
1378 }
1379 
1380 static int
procfs_insert_hw_watchpoint(CORE_ADDR addr,int len,int type)1381 procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1382 {
1383   return procfs_hw_watchpoint (addr, len, type);
1384 }
1385 
1386 static int
procfs_stopped_by_watchpoint(void)1387 procfs_stopped_by_watchpoint (void)
1388 {
1389   return 0;
1390 }
1391