b8bfcbe142aab86969e25d5d43fb03c6210998f6
[deliverable/binutils-gdb.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 }
This page took 0.05977 seconds and 4 git commands to generate.