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