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