* breakpoint.h (struct breakpoint): New member GDBARCH.
[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                                            (target_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, int options)
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 gdbarch *gdbarch,
828                           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 gdbarch *gdbarch,
835                           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 gdbarch *gdbarch,
842                              struct bp_target_info *bp_tgt)
843 {
844   return procfs_breakpoint (bp_tgt->placed_address,
845                             _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
846 }
847
848 static int
849 procfs_remove_hw_breakpoint (struct gdbarch *gdbarch,
850                              struct bp_target_info *bp_tgt)
851 {
852   return procfs_breakpoint (bp_tgt->placed_address,
853                             _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
854 }
855
856 static void
857 procfs_resume (struct target_ops *ops,
858                ptid_t ptid, int step, enum target_signal signo)
859 {
860   int signal_to_pass;
861   procfs_status status;
862   sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
863
864   if (ptid_equal (inferior_ptid, null_ptid))
865     return;
866
867   procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
868                      ptid);
869
870   run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
871   if (step)
872     run.flags |= _DEBUG_RUN_STEP;
873
874   sigemptyset (run_fault);
875   sigaddset (run_fault, FLTBPT);
876   sigaddset (run_fault, FLTTRACE);
877   sigaddset (run_fault, FLTILL);
878   sigaddset (run_fault, FLTPRIV);
879   sigaddset (run_fault, FLTBOUNDS);
880   sigaddset (run_fault, FLTIOVF);
881   sigaddset (run_fault, FLTIZDIV);
882   sigaddset (run_fault, FLTFPE);
883   /* Peter V will be changing this at some point.  */
884   sigaddset (run_fault, FLTPAGE);
885
886   run.flags |= _DEBUG_RUN_ARM;
887
888   sigemptyset (&run.trace);
889   notice_signals ();
890   signal_to_pass = target_signal_to_host (signo);
891
892   if (signal_to_pass)
893     {
894       devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
895       signal_to_pass = target_signal_to_host (signo);
896       if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
897         {
898           if (signal_to_pass != status.info.si_signo)
899             {
900               SignalKill (nto_node (), PIDGET (inferior_ptid), 0,
901                           signal_to_pass, 0, 0);
902               run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
903             }
904           else                  /* Let it kill the program without telling us.  */
905             sigdelset (&run.trace, signal_to_pass);
906         }
907     }
908   else
909     run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
910
911   errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
912   if (errno != EOK)
913     {
914       perror ("run error!\n");
915       return;
916     }
917 }
918
919 static void
920 procfs_mourn_inferior (struct target_ops *ops)
921 {
922   if (!ptid_equal (inferior_ptid, null_ptid))
923     {
924       SignalKill (nto_node (), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
925       close (ctl_fd);
926     }
927   inferior_ptid = null_ptid;
928   init_thread_list ();
929   unpush_target (&procfs_ops);
930   generic_mourn_inferior ();
931 }
932
933 /* This function breaks up an argument string into an argument
934    vector suitable for passing to execvp().
935    E.g., on "run a b c d" this routine would get as input
936    the string "a b c d", and as output it would fill in argv with
937    the four arguments "a", "b", "c", "d".  The only additional
938    functionality is simple quoting.  The gdb command:
939         run a "b c d" f
940    will fill in argv with the three args "a", "b c d", "e".  */
941 static void
942 breakup_args (char *scratch, char **argv)
943 {
944   char *pp, *cp = scratch;
945   char quoting = 0;
946
947   for (;;)
948     {
949       /* Scan past leading separators.  */
950       quoting = 0;
951       while (*cp == ' ' || *cp == '\t' || *cp == '\n')
952         cp++;
953
954       /* Break if at end of string.  */
955       if (*cp == '\0')
956         break;
957
958       /* Take an arg.  */
959       if (*cp == '"')
960         {
961           cp++;
962           quoting = strchr (cp, '"') ? 1 : 0;
963         }
964
965       *argv++ = cp;
966
967       /* Scan for next arg separator.  */
968       pp = cp;
969       if (quoting)
970         cp = strchr (pp, '"');
971       if ((cp == NULL) || (!quoting))
972         cp = strchr (pp, ' ');
973       if (cp == NULL)
974         cp = strchr (pp, '\t');
975       if (cp == NULL)
976         cp = strchr (pp, '\n');
977
978       /* No separators => end of string => break.  */
979       if (cp == NULL)
980         {
981           pp = cp;
982           break;
983         }
984
985       /* Replace the separator with a terminator.  */
986       *cp++ = '\0';
987     }
988
989   /* Execv requires a null-terminated arg vector.  */
990   *argv = NULL;
991 }
992
993 static void
994 procfs_create_inferior (struct target_ops *ops, char *exec_file,
995                         char *allargs, char **env, int from_tty)
996 {
997   struct inheritance inherit;
998   pid_t pid;
999   int flags, errn;
1000   char **argv, *args;
1001   const char *in = "", *out = "", *err = "";
1002   int fd, fds[3];
1003   sigset_t set;
1004   const char *inferior_io_terminal = get_inferior_io_terminal ();
1005   struct inferior *inf;
1006
1007   argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
1008                   sizeof (*argv));
1009   argv[0] = get_exec_file (1);
1010   if (!argv[0])
1011     {
1012       if (exec_file)
1013         argv[0] = exec_file;
1014       else
1015         return;
1016     }
1017
1018   args = xstrdup (allargs);
1019   breakup_args (args, exec_file ? &argv[1] : &argv[0]);
1020
1021   argv = nto_parse_redirection (argv, &in, &out, &err);
1022
1023   fds[0] = STDIN_FILENO;
1024   fds[1] = STDOUT_FILENO;
1025   fds[2] = STDERR_FILENO;
1026
1027   /* If the user specified I/O via gdb's --tty= arg, use it, but only
1028      if the i/o is not also being specified via redirection.  */
1029   if (inferior_io_terminal)
1030     {
1031       if (!in[0])
1032         in = inferior_io_terminal;
1033       if (!out[0])
1034         out = inferior_io_terminal;
1035       if (!err[0])
1036         err = inferior_io_terminal;
1037     }
1038
1039   if (in[0])
1040     {
1041       fd = open (in, O_RDONLY);
1042       if (fd == -1)
1043         perror (in);
1044       else
1045         fds[0] = fd;
1046     }
1047   if (out[0])
1048     {
1049       fd = open (out, O_WRONLY);
1050       if (fd == -1)
1051         perror (out);
1052       else
1053         fds[1] = fd;
1054     }
1055   if (err[0])
1056     {
1057       fd = open (err, O_WRONLY);
1058       if (fd == -1)
1059         perror (err);
1060       else
1061         fds[2] = fd;
1062     }
1063
1064   /* Clear any pending SIGUSR1's but keep the behavior the same.  */
1065   signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
1066
1067   sigemptyset (&set);
1068   sigaddset (&set, SIGUSR1);
1069   sigprocmask (SIG_UNBLOCK, &set, NULL);
1070
1071   memset (&inherit, 0, sizeof (inherit));
1072
1073   if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
1074     {
1075       inherit.nd = nto_node ();
1076       inherit.flags |= SPAWN_SETND;
1077       inherit.flags &= ~SPAWN_EXEC;
1078     }
1079   inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
1080   inherit.pgroup = SPAWN_NEWPGROUP;
1081   pid = spawnp (argv[0], 3, fds, &inherit, argv,
1082                 ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
1083   xfree (args);
1084
1085   sigprocmask (SIG_BLOCK, &set, NULL);
1086
1087   if (pid == -1)
1088     error (_("Error spawning %s: %d (%s)"), argv[0], errno,
1089            safe_strerror (errno));
1090
1091   if (fds[0] != STDIN_FILENO)
1092     close (fds[0]);
1093   if (fds[1] != STDOUT_FILENO)
1094     close (fds[1]);
1095   if (fds[2] != STDERR_FILENO)
1096     close (fds[2]);
1097
1098   inferior_ptid = do_attach (pid_to_ptid (pid));
1099   procfs_find_new_threads (ops);
1100
1101   inf = add_inferior (pid);
1102   inf->attach_flag = 0;
1103
1104   flags = _DEBUG_FLAG_KLC;      /* Kill-on-Last-Close flag.  */
1105   errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
1106   if (errn != EOK)
1107     {
1108       /* FIXME: expected warning?  */
1109       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
1110          errn, strerror(errn) ); */
1111     }
1112   push_target (ops);
1113   target_terminal_init ();
1114
1115   if (exec_bfd != NULL
1116       || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
1117     solib_create_inferior_hook ();
1118 }
1119
1120 static void
1121 procfs_stop (ptid_t ptid)
1122 {
1123   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1124 }
1125
1126 static void
1127 procfs_kill_inferior (struct target_ops *ops)
1128 {
1129   target_mourn_inferior ();
1130 }
1131
1132 /* Store register REGNO, or all registers if REGNO == -1, from the contents
1133    of REGISTERS.  */
1134 static void
1135 procfs_prepare_to_store (struct regcache *regcache)
1136 {
1137 }
1138
1139 /* Fill buf with regset and return devctl cmd to do the setting.  Return
1140    -1 if we fail to get the regset.  Store size of regset in regsize.  */
1141 static int
1142 get_regset (int regset, char *buf, int bufsize, int *regsize)
1143 {
1144   int dev_get, dev_set;
1145   switch (regset)
1146     {
1147     case NTO_REG_GENERAL:
1148       dev_get = DCMD_PROC_GETGREG;
1149       dev_set = DCMD_PROC_SETGREG;
1150       break;
1151
1152     case NTO_REG_FLOAT:
1153       dev_get = DCMD_PROC_GETFPREG;
1154       dev_set = DCMD_PROC_SETFPREG;
1155       break;
1156
1157     case NTO_REG_ALT:
1158       dev_get = DCMD_PROC_GETALTREG;
1159       dev_set = DCMD_PROC_SETALTREG;
1160       break;
1161
1162     case NTO_REG_SYSTEM:
1163     default:
1164       return -1;
1165     }
1166   if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK)
1167     return -1;
1168
1169   return dev_set;
1170 }
1171
1172 void
1173 procfs_store_registers (struct target_ops *ops,
1174                         struct regcache *regcache, int regno)
1175 {
1176   union
1177   {
1178     procfs_greg greg;
1179     procfs_fpreg fpreg;
1180     procfs_altreg altreg;
1181   }
1182   reg;
1183   unsigned off;
1184   int len, regset, regsize, dev_set, err;
1185   char *data;
1186
1187   if (ptid_equal (inferior_ptid, null_ptid))
1188     return;
1189   procfs_set_thread (inferior_ptid);
1190
1191   if (regno == -1)
1192     {
1193       for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
1194         {
1195           dev_set = get_regset (regset, (char *) &reg,
1196                                 sizeof (reg), &regsize);
1197           if (dev_set == -1)
1198             continue;
1199
1200           if (nto_regset_fill (regcache, regset, (char *) &reg) == -1)
1201             continue;
1202
1203           err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1204           if (err != EOK)
1205             fprintf_unfiltered (gdb_stderr,
1206                                 "Warning unable to write regset %d: %s\n",
1207                                 regno, safe_strerror (err));
1208         }
1209     }
1210   else
1211     {
1212       regset = nto_regset_id (regno);
1213       if (regset == -1)
1214         return;
1215
1216       dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
1217       if (dev_set == -1)
1218         return;
1219
1220       len = nto_register_area (get_regcache_arch (regcache),
1221                                regno, regset, &off);
1222
1223       if (len < 1)
1224         return;
1225
1226       regcache_raw_collect (regcache, regno, (char *) &reg + off);
1227
1228       err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1229       if (err != EOK)
1230         fprintf_unfiltered (gdb_stderr,
1231                             "Warning unable to write regset %d: %s\n", regno,
1232                             safe_strerror (err));
1233     }
1234 }
1235
1236 static void
1237 notice_signals (void)
1238 {
1239   int signo;
1240
1241   for (signo = 1; signo < NSIG; signo++)
1242     {
1243       if (signal_stop_state (target_signal_from_host (signo)) == 0
1244           && signal_print_state (target_signal_from_host (signo)) == 0
1245           && signal_pass_state (target_signal_from_host (signo)) == 1)
1246         sigdelset (&run.trace, signo);
1247       else
1248         sigaddset (&run.trace, signo);
1249     }
1250 }
1251
1252 /* When the user changes the state of gdb's signal handling via the
1253    "handle" command, this function gets called to see if any change
1254    in the /proc interface is required.  It is also called internally
1255    by other /proc interface functions to initialize the state of
1256    the traced signal set.  */
1257 static void
1258 procfs_notice_signals (ptid_t ptid)
1259 {
1260   sigemptyset (&run.trace);
1261   notice_signals ();
1262 }
1263
1264 static struct tidinfo *
1265 procfs_thread_info (pid_t pid, short tid)
1266 {
1267 /* NYI */
1268   return NULL;
1269 }
1270
1271 char *
1272 procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
1273 {
1274   static char buf[1024];
1275   int pid, tid, n;
1276   struct tidinfo *tip;
1277
1278   pid = ptid_get_pid (ptid);
1279   tid = ptid_get_tid (ptid);
1280
1281   n = snprintf (buf, 1023, "process %d", pid);
1282
1283 #if 0                           /* NYI */
1284   tip = procfs_thread_info (pid, tid);
1285   if (tip != NULL)
1286     snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
1287 #endif
1288
1289   return buf;
1290 }
1291
1292 static void
1293 init_procfs_ops (void)
1294 {
1295   procfs_ops.to_shortname = "procfs";
1296   procfs_ops.to_longname = "QNX Neutrino procfs child process";
1297   procfs_ops.to_doc =
1298     "QNX Neutrino procfs child process (started by the \"run\" command).\n\
1299         target procfs <node>";
1300   procfs_ops.to_open = procfs_open;
1301   procfs_ops.to_attach = procfs_attach;
1302   procfs_ops.to_post_attach = procfs_post_attach;
1303   procfs_ops.to_detach = procfs_detach;
1304   procfs_ops.to_resume = procfs_resume;
1305   procfs_ops.to_wait = procfs_wait;
1306   procfs_ops.to_fetch_registers = procfs_fetch_registers;
1307   procfs_ops.to_store_registers = procfs_store_registers;
1308   procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
1309   procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
1310   procfs_ops.to_files_info = procfs_files_info;
1311   procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
1312   procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
1313   procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
1314   procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
1315   procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
1316   procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
1317   procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
1318   procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
1319   procfs_ops.to_terminal_init = terminal_init_inferior;
1320   procfs_ops.to_terminal_inferior = terminal_inferior;
1321   procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1322   procfs_ops.to_terminal_ours = terminal_ours;
1323   procfs_ops.to_terminal_info = child_terminal_info;
1324   procfs_ops.to_kill = procfs_kill_inferior;
1325   procfs_ops.to_create_inferior = procfs_create_inferior;
1326   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
1327   procfs_ops.to_can_run = procfs_can_run;
1328   procfs_ops.to_notice_signals = procfs_notice_signals;
1329   procfs_ops.to_thread_alive = procfs_thread_alive;
1330   procfs_ops.to_find_new_threads = procfs_find_new_threads;
1331   procfs_ops.to_pid_to_str = procfs_pid_to_str;
1332   procfs_ops.to_stop = procfs_stop;
1333   procfs_ops.to_stratum = process_stratum;
1334   procfs_ops.to_has_all_memory = default_child_has_all_memory;
1335   procfs_ops.to_has_memory = default_child_has_memory;
1336   procfs_ops.to_has_stack = default_child_has_stack;
1337   procfs_ops.to_has_registers = default_child_has_registers;
1338   procfs_ops.to_has_execution = default_child_has_execution;
1339   procfs_ops.to_magic = OPS_MAGIC;
1340   procfs_ops.to_have_continuable_watchpoint = 1;
1341 }
1342
1343 #define OSTYPE_NTO 1
1344
1345 void
1346 _initialize_procfs (void)
1347 {
1348   sigset_t set;
1349
1350   init_procfs_ops ();
1351   add_target (&procfs_ops);
1352
1353   /* We use SIGUSR1 to gain control after we block waiting for a process.
1354      We use sigwaitevent to wait.  */
1355   sigemptyset (&set);
1356   sigaddset (&set, SIGUSR1);
1357   sigprocmask (SIG_BLOCK, &set, NULL);
1358
1359   /* Set up trace and fault sets, as gdb expects them.  */
1360   sigemptyset (&run.trace);
1361
1362   /* Stuff some information.  */
1363   nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1364   nto_cpuinfo_valid = 1;
1365
1366   add_info ("pidlist", procfs_pidlist, _("pidlist"));
1367   add_info ("meminfo", procfs_meminfo, _("memory information"));
1368
1369   nto_is_nto_target = procfs_is_nto_target;
1370 }
1371
1372
1373 static int
1374 procfs_hw_watchpoint (int addr, int len, int type)
1375 {
1376   procfs_break brk;
1377
1378   switch (type)
1379     {
1380     case 1:                     /* Read.  */
1381       brk.type = _DEBUG_BREAK_RD;
1382       break;
1383     case 2:                     /* Read/Write.  */
1384       brk.type = _DEBUG_BREAK_RW;
1385       break;
1386     default:                    /* Modify.  */
1387 /* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason.  */
1388       brk.type = _DEBUG_BREAK_RW;
1389     }
1390   brk.type |= _DEBUG_BREAK_HW;  /* Always ask for HW.  */
1391   brk.addr = addr;
1392   brk.size = len;
1393
1394   errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
1395   if (errno != EOK)
1396     {
1397       perror ("Failed to set hardware watchpoint");
1398       return -1;
1399     }
1400   return 0;
1401 }
1402
1403 static int
1404 procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1405 {
1406   return 1;
1407 }
1408
1409 static int
1410 procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1411 {
1412   return procfs_hw_watchpoint (addr, -1, type);
1413 }
1414
1415 static int
1416 procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1417 {
1418   return procfs_hw_watchpoint (addr, len, type);
1419 }
1420
1421 static int
1422 procfs_stopped_by_watchpoint (void)
1423 {
1424   return 0;
1425 }