* linux-nat.c (linux_nat_wait): Adjust.
[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 procfs_fetch_registers (struct regcache *, int);
67
68 static void notice_signals (void);
69
70 static void init_procfs_ops (void);
71
72 static ptid_t do_attach (ptid_t ptid);
73
74 static int procfs_can_use_hw_breakpoint (int, int, int);
75
76 static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
77
78 static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
79
80 static int procfs_stopped_by_watchpoint (void);
81
82 /* These two globals are only ever set in procfs_open(), but are
83    referenced elsewhere.  'nto_procfs_node' is a flag used to say
84    whether we are local, or we should get the current node descriptor
85    for the remote QNX node.  */
86 static char nto_procfs_path[PATH_MAX] = { "/proc" };
87 static unsigned nto_procfs_node = ND_LOCAL_NODE;
88
89 /* Return the current QNX Node, or error out.  This is a simple
90    wrapper for the netmgr_strtond() function.  The reason this
91    is required is because QNX node descriptors are transient so
92    we have to re-acquire them every time.  */
93 static unsigned
94 nto_node (void)
95 {
96   unsigned node;
97
98   if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0)
99     return ND_LOCAL_NODE;
100
101   node = netmgr_strtond (nto_procfs_path, 0);
102   if (node == -1)
103     error (_("Lost the QNX node.  Debug session probably over."));
104
105   return (node);
106 }
107
108 static enum gdb_osabi
109 procfs_is_nto_target (bfd *abfd)
110 {
111   return GDB_OSABI_QNXNTO;
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
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   struct cleanup *cleanups;
127
128   nto_is_nto_target = procfs_is_nto_target;
129
130   /* Set the default node used for spawning to this one,
131      and only override it if there is a valid arg.  */
132
133   nto_procfs_node = ND_LOCAL_NODE;
134   nodestr = arg ? xstrdup (arg) : arg;
135
136   init_thread_list ();
137
138   if (nodestr)
139     {
140       nto_procfs_node = netmgr_strtond (nodestr, &endstr);
141       if (nto_procfs_node == -1)
142         {
143           if (errno == ENOTSUP)
144             printf_filtered ("QNX Net Manager not found.\n");
145           printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
146                            errno, safe_strerror (errno));
147           xfree (nodestr);
148           nodestr = NULL;
149           nto_procfs_node = ND_LOCAL_NODE;
150         }
151       else if (*endstr)
152         {
153           if (*(endstr - 1) == '/')
154             *(endstr - 1) = 0;
155           else
156             *endstr = 0;
157         }
158     }
159   snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "",
160             "/proc");
161   if (nodestr)
162     xfree (nodestr);
163
164   fd = open (nto_procfs_path, O_RDONLY);
165   if (fd == -1)
166     {
167       printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
168                        safe_strerror (errno));
169       error (_("Invalid procfs arg"));
170     }
171   cleanups = make_cleanup_close (fd);
172
173   sysinfo = (void *) buffer;
174   if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
175     {
176       printf_filtered ("Error getting size: %d (%s)\n", errno,
177                        safe_strerror (errno));
178       error (_("Devctl failed."));
179     }
180   else
181     {
182       total_size = sysinfo->total_size;
183       sysinfo = alloca (total_size);
184       if (!sysinfo)
185         {
186           printf_filtered ("Memory error: %d (%s)\n", errno,
187                            safe_strerror (errno));
188           error (_("alloca failed."));
189         }
190       else
191         {
192           if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
193             {
194               printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
195                                safe_strerror (errno));
196               error (_("Devctl failed."));
197             }
198           else
199             {
200               if (sysinfo->type !=
201                   nto_map_arch_to_cputype (gdbarch_bfd_arch_info
202                                            (current_gdbarch)->arch_name))
203                 error (_("Invalid target CPU."));
204             }
205         }
206     }
207   do_cleanups (cleanups);
208   printf_filtered ("Debugging using %s\n", nto_procfs_path);
209 }
210
211 static void
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
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
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 static void
257 do_closedir_cleanup (void *dir)
258 {
259   closedir (dir);
260 }
261
262 void
263 procfs_pidlist (char *args, int from_tty)
264 {
265   DIR *dp = NULL;
266   struct dirent *dirp = NULL;
267   char buf[512];
268   procfs_info *pidinfo = NULL;
269   procfs_debuginfo *info = NULL;
270   procfs_status *status = NULL;
271   pid_t num_threads = 0;
272   pid_t pid;
273   char name[512];
274   struct cleanup *cleanups;
275
276   dp = opendir (nto_procfs_path);
277   if (dp == NULL)
278     {
279       fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
280                           nto_procfs_path, errno, safe_strerror (errno));
281       return;
282     }
283
284   cleanups = make_cleanup (do_closedir_cleanup, dp);
285
286   /* Start scan at first pid.  */
287   rewinddir (dp);
288
289   do
290     {
291       int fd;
292       struct cleanup *inner_cleanup;
293
294       /* Get the right pid and procfs path for the pid.  */
295       do
296         {
297           dirp = readdir (dp);
298           if (dirp == NULL)
299             {
300               do_cleanups (cleanups);
301               return;
302             }
303           snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
304           pid = atoi (dirp->d_name);
305         }
306       while (pid == 0);
307
308       /* Open the procfs path. */
309       fd = open (buf, O_RDONLY);
310       if (fd == -1)
311         {
312           fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
313                               buf, errno, safe_strerror (errno));
314           do_cleanups (cleanups);
315           return;
316         }
317       inner_cleanup = make_cleanup_close (fd);
318
319       pidinfo = (procfs_info *) buf;
320       if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
321         {
322           fprintf_unfiltered (gdb_stderr,
323                               "devctl DCMD_PROC_INFO failed - %d (%s)\n",
324                               errno, safe_strerror (errno));
325           break;
326         }
327       num_threads = pidinfo->num_threads;
328
329       info = (procfs_debuginfo *) buf;
330       if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
331         strcpy (name, "unavailable");
332       else
333         strcpy (name, info->path);
334
335       /* Collect state info on all the threads.  */
336       status = (procfs_status *) buf;
337       for (status->tid = 1; status->tid <= num_threads; status->tid++)
338         {
339           if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
340               && status->tid != 0)
341             break;
342           if (status->tid != 0)
343             printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
344         }
345
346       do_cleanups (inner_cleanup);
347     }
348   while (dirp != NULL);
349
350   do_cleanups (cleanups);
351   return;
352 }
353
354 void
355 procfs_meminfo (char *args, int from_tty)
356 {
357   procfs_mapinfo *mapinfos = NULL;
358   static int num_mapinfos = 0;
359   procfs_mapinfo *mapinfo_p, *mapinfo_p2;
360   int flags = ~0, err, num, i, j;
361
362   struct
363   {
364     procfs_debuginfo info;
365     char buff[_POSIX_PATH_MAX];
366   } map;
367
368   struct info
369   {
370     unsigned addr;
371     unsigned size;
372     unsigned flags;
373     unsigned debug_vaddr;
374     unsigned long long offset;
375   };
376
377   struct printinfo
378   {
379     unsigned long long ino;
380     unsigned dev;
381     struct info text;
382     struct info data;
383     char name[256];
384   } printme;
385
386   /* Get the number of map entrys.  */
387   err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num);
388   if (err != EOK)
389     {
390       printf ("failed devctl num mapinfos - %d (%s)\n", err,
391               safe_strerror (err));
392       return;
393     }
394
395   mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
396
397   num_mapinfos = num;
398   mapinfo_p = mapinfos;
399
400   /* Fill the map entrys.  */
401   err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num
402                 * sizeof (procfs_mapinfo), &num);
403   if (err != EOK)
404     {
405       printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
406       xfree (mapinfos);
407       return;
408     }
409
410   num = min (num, num_mapinfos);
411
412   /* Run through the list of mapinfos, and store the data and text info
413      so we can print it at the bottom of the loop.  */
414   for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
415     {
416       if (!(mapinfo_p->flags & flags))
417         mapinfo_p->ino = 0;
418
419       if (mapinfo_p->ino == 0)  /* Already visited.  */
420         continue;
421
422       map.info.vaddr = mapinfo_p->vaddr;
423
424       err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
425       if (err != EOK)
426         continue;
427
428       memset (&printme, 0, sizeof printme);
429       printme.dev = mapinfo_p->dev;
430       printme.ino = mapinfo_p->ino;
431       printme.text.addr = mapinfo_p->vaddr;
432       printme.text.size = mapinfo_p->size;
433       printme.text.flags = mapinfo_p->flags;
434       printme.text.offset = mapinfo_p->offset;
435       printme.text.debug_vaddr = map.info.vaddr;
436       strcpy (printme.name, map.info.path);
437
438       /* Check for matching data.  */
439       for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
440         {
441           if (mapinfo_p2->vaddr != mapinfo_p->vaddr
442               && mapinfo_p2->ino == mapinfo_p->ino
443               && mapinfo_p2->dev == mapinfo_p->dev)
444             {
445               map.info.vaddr = mapinfo_p2->vaddr;
446               err =
447                 devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
448               if (err != EOK)
449                 continue;
450
451               if (strcmp (map.info.path, printme.name))
452                 continue;
453
454               /* Lower debug_vaddr is always text, if nessessary, swap.  */
455               if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
456                 {
457                   memcpy (&(printme.data), &(printme.text),
458                           sizeof (printme.data));
459                   printme.text.addr = mapinfo_p2->vaddr;
460                   printme.text.size = mapinfo_p2->size;
461                   printme.text.flags = mapinfo_p2->flags;
462                   printme.text.offset = mapinfo_p2->offset;
463                   printme.text.debug_vaddr = map.info.vaddr;
464                 }
465               else
466                 {
467                   printme.data.addr = mapinfo_p2->vaddr;
468                   printme.data.size = mapinfo_p2->size;
469                   printme.data.flags = mapinfo_p2->flags;
470                   printme.data.offset = mapinfo_p2->offset;
471                   printme.data.debug_vaddr = map.info.vaddr;
472                 }
473               mapinfo_p2->ino = 0;
474             }
475         }
476       mapinfo_p->ino = 0;
477
478       printf_filtered ("%s\n", printme.name);
479       printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
480                        printme.text.addr);
481       printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
482       printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
483       printf_filtered ("\t\toffset=%016llx\n", printme.text.offset);
484       if (printme.data.size)
485         {
486           printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
487                            printme.data.addr);
488           printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
489           printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
490           printf_filtered ("\t\toffset=%016llx\n", printme.data.offset);
491         }
492       printf_filtered ("\tdev=0x%x\n", printme.dev);
493       printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
494     }
495   xfree (mapinfos);
496   return;
497 }
498
499 /* Print status information about what we're accessing.  */
500 static void
501 procfs_files_info (struct target_ops *ignore)
502 {
503   struct inferior *inf = current_inferior ();
504
505   printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
506                      inf->attach_flag ? "attached" : "child",
507                      target_pid_to_str (inferior_ptid), nto_procfs_path);
508 }
509
510 /* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
511 static int
512 procfs_can_run (void)
513 {
514   return 1;
515 }
516
517 /* Attach to process PID, then initialize for debugging it.  */
518 static void
519 procfs_attach (struct target_ops *ops, char *args, int from_tty)
520 {
521   char *exec_file;
522   int pid;
523   struct inferior *inf;
524
525   if (!args)
526     error_no_arg (_("process-id to attach"));
527
528   pid = atoi (args);
529
530   if (pid == getpid ())
531     error (_("Attaching GDB to itself is not a good idea..."));
532
533   if (from_tty)
534     {
535       exec_file = (char *) get_exec_file (0);
536
537       if (exec_file)
538         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
539                            target_pid_to_str (pid_to_ptid (pid)));
540       else
541         printf_unfiltered ("Attaching to %s\n",
542                            target_pid_to_str (pid_to_ptid (pid)));
543
544       gdb_flush (gdb_stdout);
545     }
546   inferior_ptid = do_attach (pid_to_ptid (pid));
547   inf = add_inferior (pid);
548   inf->attach_flag = 1;
549
550   push_target (&procfs_ops);
551
552   procfs_find_new_threads ();
553 }
554
555 static void
556 procfs_post_attach (pid_t pid)
557 {
558   if (exec_bfd)
559     solib_create_inferior_hook ();
560 }
561
562 static ptid_t
563 do_attach (ptid_t ptid)
564 {
565   procfs_status status;
566   struct sigevent event;
567   char path[PATH_MAX];
568
569   snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
570   ctl_fd = open (path, O_RDWR);
571   if (ctl_fd == -1)
572     error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
573            safe_strerror (errno));
574   if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
575     error (_("Couldn't stop process"));
576
577   /* Define a sigevent for process stopped notification.  */
578   event.sigev_notify = SIGEV_SIGNAL_THREAD;
579   event.sigev_signo = SIGUSR1;
580   event.sigev_code = 0;
581   event.sigev_value.sival_ptr = NULL;
582   event.sigev_priority = -1;
583   devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
584
585   if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
586       && status.flags & _DEBUG_FLAG_STOPPED)
587     SignalKill (nto_node (), PIDGET (ptid), 0, SIGCONT, 0, 0);
588   nto_init_solib_absolute_prefix ();
589   return ptid_build (PIDGET (ptid), 0, status.tid);
590 }
591
592 /* Ask the user what to do when an interrupt is received.  */
593 static void
594 interrupt_query (void)
595 {
596   target_terminal_ours ();
597
598   if (query ("Interrupted while waiting for the program.\n\
599 Give up (and stop debugging it)? "))
600     {
601       target_mourn_inferior ();
602       deprecated_throw_reason (RETURN_QUIT);
603     }
604
605   target_terminal_inferior ();
606 }
607
608 /* The user typed ^C twice.  */
609 static void
610 nto_interrupt_twice (int signo)
611 {
612   signal (signo, ofunc);
613   interrupt_query ();
614   signal (signo, nto_interrupt_twice);
615 }
616
617 static void
618 nto_interrupt (int signo)
619 {
620   /* If this doesn't work, try more severe steps.  */
621   signal (signo, nto_interrupt_twice);
622
623   target_stop (inferior_ptid);
624 }
625
626 static ptid_t
627 procfs_wait (struct target_ops *ops,
628              ptid_t ptid, struct target_waitstatus *ourstatus)
629 {
630   sigset_t set;
631   siginfo_t info;
632   procfs_status status;
633   static int exit_signo = 0;    /* To track signals that cause termination.  */
634
635   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
636
637   if (ptid_equal (inferior_ptid, null_ptid))
638     {
639       ourstatus->kind = TARGET_WAITKIND_STOPPED;
640       ourstatus->value.sig = TARGET_SIGNAL_0;
641       exit_signo = 0;
642       return null_ptid;
643     }
644
645   sigemptyset (&set);
646   sigaddset (&set, SIGUSR1);
647
648   devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
649   while (!(status.flags & _DEBUG_FLAG_ISTOP))
650     {
651       ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
652       sigwaitinfo (&set, &info);
653       signal (SIGINT, ofunc);
654       devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
655     }
656
657   if (status.flags & _DEBUG_FLAG_SSTEP)
658     {
659       ourstatus->kind = TARGET_WAITKIND_STOPPED;
660       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
661     }
662   /* Was it a breakpoint?  */
663   else if (status.flags & _DEBUG_FLAG_TRACE)
664     {
665       ourstatus->kind = TARGET_WAITKIND_STOPPED;
666       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
667     }
668   else if (status.flags & _DEBUG_FLAG_ISTOP)
669     {
670       switch (status.why)
671         {
672         case _DEBUG_WHY_SIGNALLED:
673           ourstatus->kind = TARGET_WAITKIND_STOPPED;
674           ourstatus->value.sig =
675             target_signal_from_host (status.info.si_signo);
676           exit_signo = 0;
677           break;
678         case _DEBUG_WHY_FAULTED:
679           ourstatus->kind = TARGET_WAITKIND_STOPPED;
680           if (status.info.si_signo == SIGTRAP)
681             {
682               ourstatus->value.sig = 0;
683               exit_signo = 0;
684             }
685           else
686             {
687               ourstatus->value.sig =
688                 target_signal_from_host (status.info.si_signo);
689               exit_signo = ourstatus->value.sig;
690             }
691           break;
692
693         case _DEBUG_WHY_TERMINATED:
694           {
695             int waitval = 0;
696
697             waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
698             if (exit_signo)
699               {
700                 /* Abnormal death.  */
701                 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
702                 ourstatus->value.sig = exit_signo;
703               }
704             else
705               {
706                 /* Normal death.  */
707                 ourstatus->kind = TARGET_WAITKIND_EXITED;
708                 ourstatus->value.integer = WEXITSTATUS (waitval);
709               }
710             exit_signo = 0;
711             break;
712           }
713
714         case _DEBUG_WHY_REQUESTED:
715           /* We are assuming a requested stop is due to a SIGINT.  */
716           ourstatus->kind = TARGET_WAITKIND_STOPPED;
717           ourstatus->value.sig = TARGET_SIGNAL_INT;
718           exit_signo = 0;
719           break;
720         }
721     }
722
723   return ptid_build (status.pid, 0, status.tid);
724 }
725
726 /* Read the current values of the inferior's registers, both the
727    general register set and floating point registers (if supported)
728    and update gdb's idea of their current values.  */
729 static void
730 procfs_fetch_registers (struct regcache *regcache, int regno)
731 {
732   union
733   {
734     procfs_greg greg;
735     procfs_fpreg fpreg;
736     procfs_altreg altreg;
737   }
738   reg;
739   int regsize;
740
741   procfs_set_thread (inferior_ptid);
742   if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
743     nto_supply_gregset (regcache, (char *) &reg.greg);
744   if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
745       == EOK)
746     nto_supply_fpregset (regcache, (char *) &reg.fpreg);
747   if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
748       == EOK)
749     nto_supply_altregset (regcache, (char *) &reg.altreg);
750 }
751
752 /* Copy LEN bytes to/from inferior's memory starting at MEMADDR
753    from/to debugger memory starting at MYADDR.  Copy from inferior
754    if DOWRITE is zero or to inferior if DOWRITE is nonzero.
755
756    Returns the length copied, which is either the LEN argument or
757    zero.  This xfer function does not do partial moves, since procfs_ops
758    doesn't allow memory operations to cross below us in the target stack
759    anyway.  */
760 static int
761 procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
762                     struct mem_attrib *attrib, struct target_ops *target)
763 {
764   int nbytes = 0;
765
766   if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
767     {
768       if (dowrite)
769         nbytes = write (ctl_fd, myaddr, len);
770       else
771         nbytes = read (ctl_fd, myaddr, len);
772       if (nbytes < 0)
773         nbytes = 0;
774     }
775   return (nbytes);
776 }
777
778 /* Take a program previously attached to and detaches it.
779    The program resumes execution and will no longer stop
780    on signals, etc.  We'd better not have left any breakpoints
781    in the program or it'll die when it hits one.  */
782 static void
783 procfs_detach (struct target_ops *ops, char *args, int from_tty)
784 {
785   int siggnal = 0;
786   int pid;
787
788   if (from_tty)
789     {
790       char *exec_file = get_exec_file (0);
791       if (exec_file == 0)
792         exec_file = "";
793       printf_unfiltered ("Detaching from program: %s %s\n",
794                          exec_file, target_pid_to_str (inferior_ptid));
795       gdb_flush (gdb_stdout);
796     }
797   if (args)
798     siggnal = atoi (args);
799
800   if (siggnal)
801     SignalKill (nto_node (), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
802
803   close (ctl_fd);
804   ctl_fd = -1;
805
806   pid = ptid_get_pid (inferior_ptid);
807   inferior_ptid = null_ptid;
808   detach_inferior (pid);
809   init_thread_list ();
810   unpush_target (&procfs_ops);  /* Pop out of handling an inferior.  */
811 }
812
813 static int
814 procfs_breakpoint (CORE_ADDR addr, int type, int size)
815 {
816   procfs_break brk;
817
818   brk.type = type;
819   brk.addr = addr;
820   brk.size = size;
821   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
822   if (errno != EOK)
823     return 1;
824   return 0;
825 }
826
827 static int
828 procfs_insert_breakpoint (struct bp_target_info *bp_tgt)
829 {
830   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
831 }
832
833 static int
834 procfs_remove_breakpoint (struct bp_target_info *bp_tgt)
835 {
836   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
837 }
838
839 static int
840 procfs_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
841 {
842   return procfs_breakpoint (bp_tgt->placed_address,
843                             _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
844 }
845
846 static int
847 procfs_remove_hw_breakpoint (struct bp_target_info *bp_tgt)
848 {
849   return procfs_breakpoint (bp_tgt->placed_address,
850                             _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
851 }
852
853 static void
854 procfs_resume (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 ();
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 (&procfs_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 regcache *regcache, int regno)
1170 {
1171   union
1172   {
1173     procfs_greg greg;
1174     procfs_fpreg fpreg;
1175     procfs_altreg altreg;
1176   }
1177   reg;
1178   unsigned off;
1179   int len, regset, regsize, dev_set, err;
1180   char *data;
1181
1182   if (ptid_equal (inferior_ptid, null_ptid))
1183     return;
1184   procfs_set_thread (inferior_ptid);
1185
1186   if (regno == -1)
1187     {
1188       for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
1189         {
1190           dev_set = get_regset (regset, (char *) &reg,
1191                                 sizeof (reg), &regsize);
1192           if (dev_set == -1)
1193             continue;
1194
1195           if (nto_regset_fill (regcache, regset, (char *) &reg) == -1)
1196             continue;
1197
1198           err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1199           if (err != EOK)
1200             fprintf_unfiltered (gdb_stderr,
1201                                 "Warning unable to write regset %d: %s\n",
1202                                 regno, safe_strerror (err));
1203         }
1204     }
1205   else
1206     {
1207       regset = nto_regset_id (regno);
1208       if (regset == -1)
1209         return;
1210
1211       dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
1212       if (dev_set == -1)
1213         return;
1214
1215       len = nto_register_area (get_regcache_arch (regcache),
1216                                regno, regset, &off);
1217
1218       if (len < 1)
1219         return;
1220
1221       regcache_raw_collect (regcache, regno, (char *) &reg + off);
1222
1223       err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1224       if (err != EOK)
1225         fprintf_unfiltered (gdb_stderr,
1226                             "Warning unable to write regset %d: %s\n", regno,
1227                             safe_strerror (err));
1228     }
1229 }
1230
1231 static void
1232 notice_signals (void)
1233 {
1234   int signo;
1235
1236   for (signo = 1; signo < NSIG; signo++)
1237     {
1238       if (signal_stop_state (target_signal_from_host (signo)) == 0
1239           && signal_print_state (target_signal_from_host (signo)) == 0
1240           && signal_pass_state (target_signal_from_host (signo)) == 1)
1241         sigdelset (&run.trace, signo);
1242       else
1243         sigaddset (&run.trace, signo);
1244     }
1245 }
1246
1247 /* When the user changes the state of gdb's signal handling via the
1248    "handle" command, this function gets called to see if any change
1249    in the /proc interface is required.  It is also called internally
1250    by other /proc interface functions to initialize the state of
1251    the traced signal set.  */
1252 static void
1253 procfs_notice_signals (ptid_t ptid)
1254 {
1255   sigemptyset (&run.trace);
1256   notice_signals ();
1257 }
1258
1259 static struct tidinfo *
1260 procfs_thread_info (pid_t pid, short tid)
1261 {
1262 /* NYI */
1263   return NULL;
1264 }
1265
1266 char *
1267 procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
1268 {
1269   static char buf[1024];
1270   int pid, tid, n;
1271   struct tidinfo *tip;
1272
1273   pid = ptid_get_pid (ptid);
1274   tid = ptid_get_tid (ptid);
1275
1276   n = snprintf (buf, 1023, "process %d", pid);
1277
1278 #if 0                           /* NYI */
1279   tip = procfs_thread_info (pid, tid);
1280   if (tip != NULL)
1281     snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
1282 #endif
1283
1284   return buf;
1285 }
1286
1287 static void
1288 init_procfs_ops (void)
1289 {
1290   procfs_ops.to_shortname = "procfs";
1291   procfs_ops.to_longname = "QNX Neutrino procfs child process";
1292   procfs_ops.to_doc =
1293     "QNX Neutrino procfs child process (started by the \"run\" command).\n\
1294         target procfs <node>";
1295   procfs_ops.to_open = procfs_open;
1296   procfs_ops.to_attach = procfs_attach;
1297   procfs_ops.to_post_attach = procfs_post_attach;
1298   procfs_ops.to_detach = procfs_detach;
1299   procfs_ops.to_resume = procfs_resume;
1300   procfs_ops.to_wait = procfs_wait;
1301   procfs_ops.to_fetch_registers = procfs_fetch_registers;
1302   procfs_ops.to_store_registers = procfs_store_registers;
1303   procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
1304   procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
1305   procfs_ops.to_files_info = procfs_files_info;
1306   procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
1307   procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
1308   procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
1309   procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
1310   procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
1311   procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
1312   procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
1313   procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
1314   procfs_ops.to_terminal_init = terminal_init_inferior;
1315   procfs_ops.to_terminal_inferior = terminal_inferior;
1316   procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1317   procfs_ops.to_terminal_ours = terminal_ours;
1318   procfs_ops.to_terminal_info = child_terminal_info;
1319   procfs_ops.to_kill = procfs_kill_inferior;
1320   procfs_ops.to_create_inferior = procfs_create_inferior;
1321   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
1322   procfs_ops.to_can_run = procfs_can_run;
1323   procfs_ops.to_notice_signals = procfs_notice_signals;
1324   procfs_ops.to_thread_alive = procfs_thread_alive;
1325   procfs_ops.to_find_new_threads = procfs_find_new_threads;
1326   procfs_ops.to_pid_to_str = procfs_pid_to_str;
1327   procfs_ops.to_stop = procfs_stop;
1328   procfs_ops.to_stratum = process_stratum;
1329   procfs_ops.to_has_all_memory = 1;
1330   procfs_ops.to_has_memory = 1;
1331   procfs_ops.to_has_stack = 1;
1332   procfs_ops.to_has_registers = 1;
1333   procfs_ops.to_has_execution = 1;
1334   procfs_ops.to_magic = OPS_MAGIC;
1335   procfs_ops.to_have_continuable_watchpoint = 1;
1336 }
1337
1338 #define OSTYPE_NTO 1
1339
1340 void
1341 _initialize_procfs (void)
1342 {
1343   sigset_t set;
1344
1345   init_procfs_ops ();
1346   add_target (&procfs_ops);
1347
1348   /* We use SIGUSR1 to gain control after we block waiting for a process.
1349      We use sigwaitevent to wait.  */
1350   sigemptyset (&set);
1351   sigaddset (&set, SIGUSR1);
1352   sigprocmask (SIG_BLOCK, &set, NULL);
1353
1354   /* Set up trace and fault sets, as gdb expects them.  */
1355   sigemptyset (&run.trace);
1356
1357   /* Stuff some information.  */
1358   nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1359   nto_cpuinfo_valid = 1;
1360
1361   add_info ("pidlist", procfs_pidlist, _("pidlist"));
1362   add_info ("meminfo", procfs_meminfo, _("memory information"));
1363
1364   nto_is_nto_target = procfs_is_nto_target;
1365 }
1366
1367
1368 static int
1369 procfs_hw_watchpoint (int addr, int len, int type)
1370 {
1371   procfs_break brk;
1372
1373   switch (type)
1374     {
1375     case 1:                     /* Read.  */
1376       brk.type = _DEBUG_BREAK_RD;
1377       break;
1378     case 2:                     /* Read/Write.  */
1379       brk.type = _DEBUG_BREAK_RW;
1380       break;
1381     default:                    /* Modify.  */
1382 /* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason.  */
1383       brk.type = _DEBUG_BREAK_RW;
1384     }
1385   brk.type |= _DEBUG_BREAK_HW;  /* Always ask for HW.  */
1386   brk.addr = addr;
1387   brk.size = len;
1388
1389   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
1390   if (errno != EOK)
1391     {
1392       perror ("Failed to set hardware watchpoint");
1393       return -1;
1394     }
1395   return 0;
1396 }
1397
1398 static int
1399 procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1400 {
1401   return 1;
1402 }
1403
1404 static int
1405 procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1406 {
1407   return procfs_hw_watchpoint (addr, -1, type);
1408 }
1409
1410 static int
1411 procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1412 {
1413   return procfs_hw_watchpoint (addr, len, type);
1414 }
1415
1416 static int
1417 procfs_stopped_by_watchpoint (void)
1418 {
1419   return 0;
1420 }