* lib/gdb.exp (get_hexadecimal_valueof): New procedure.
[deliverable/binutils-gdb.git] / gdb / nto-procfs.c
CommitLineData
61bb466e
KW
1/* Machine independent support for QNX Neutrino /proc (process file system)
2 for GDB. Written by Colin Burgess at QNX Software Systems Limited.
3
0fb0cc75 4 Copyright (C) 2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
61bb466e
KW
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
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
61bb466e
KW
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
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
61bb466e
KW
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>
5483d879 31#include "gdb_dirent.h"
61bb466e
KW
32#include <sys/netmgr.h>
33
60250e8b 34#include "exceptions.h"
61bb466e
KW
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"
5ea03926 44#include "solib.h"
61bb466e
KW
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
50static struct target_ops procfs_ops;
51
52int ctl_fd;
53
54static void (*ofunc) ();
55
56static procfs_run run;
57
58static void procfs_open (char *, int);
59
60static int procfs_can_run (void);
61
14ef7606 62static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
61bb466e
KW
63 struct mem_attrib *attrib,
64 struct target_ops *);
65
56be3814 66static void procfs_fetch_registers (struct regcache *, int);
61bb466e
KW
67
68static void notice_signals (void);
69
70static void init_procfs_ops (void);
71
72static ptid_t do_attach (ptid_t ptid);
73
74static int procfs_can_use_hw_breakpoint (int, int, int);
75
61bb466e
KW
76static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
77
78static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
79
80static 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. */
86static char nto_procfs_path[PATH_MAX] = { "/proc" };
87static 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. */
93static unsigned
d737fd7f 94nto_node (void)
61bb466e
KW
95{
96 unsigned node;
97
d737fd7f 98 if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0)
61bb466e
KW
99 return ND_LOCAL_NODE;
100
d737fd7f 101 node = netmgr_strtond (nto_procfs_path, 0);
61bb466e 102 if (node == -1)
8a3fe4f8 103 error (_("Lost the QNX node. Debug session probably over."));
61bb466e
KW
104
105 return (node);
106}
107
d737fd7f
KW
108static enum gdb_osabi
109procfs_is_nto_target (bfd *abfd)
110{
111 return GDB_OSABI_QNXNTO;
112}
113
61bb466e
KW
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. */
118static void
119procfs_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;
9fe4a216 126 struct cleanup *cleanups;
61bb466e 127
d737fd7f
KW
128 nto_is_nto_target = procfs_is_nto_target;
129
61bb466e
KW
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,
dc5dd1eb 146 errno, safe_strerror (errno));
61bb466e
KW
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 }
d737fd7f
KW
159 snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "",
160 "/proc");
61bb466e
KW
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,
dc5dd1eb 168 safe_strerror (errno));
8a3fe4f8 169 error (_("Invalid procfs arg"));
61bb466e 170 }
9fe4a216 171 cleanups = make_cleanup_close (fd);
61bb466e
KW
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,
dc5dd1eb 177 safe_strerror (errno));
8a3fe4f8 178 error (_("Devctl failed."));
61bb466e
KW
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,
dc5dd1eb 187 safe_strerror (errno));
8a3fe4f8 188 error (_("alloca failed."));
61bb466e
KW
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,
dc5dd1eb 195 safe_strerror (errno));
8a3fe4f8 196 error (_("Devctl failed."));
61bb466e
KW
197 }
198 else
199 {
200 if (sysinfo->type !=
1143fffb
UW
201 nto_map_arch_to_cputype (gdbarch_bfd_arch_info
202 (current_gdbarch)->arch_name))
9fe4a216 203 error (_("Invalid target CPU."));
61bb466e
KW
204 }
205 }
206 }
9fe4a216 207 do_cleanups (cleanups);
61bb466e
KW
208 printf_filtered ("Debugging using %s\n", nto_procfs_path);
209}
210
211static void
212procfs_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. */
221static int
222procfs_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
232void
233procfs_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
9fe4a216
TT
256static void
257do_closedir_cleanup (void *dir)
258{
259 closedir (dir);
260}
261
61bb466e
KW
262void
263procfs_pidlist (char *args, int from_tty)
264{
265 DIR *dp = NULL;
266 struct dirent *dirp = NULL;
61bb466e
KW
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];
9fe4a216 274 struct cleanup *cleanups;
61bb466e
KW
275
276 dp = opendir (nto_procfs_path);
277 if (dp == NULL)
278 {
dc5dd1eb 279 fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
d737fd7f 280 nto_procfs_path, errno, safe_strerror (errno));
61bb466e
KW
281 return;
282 }
283
9fe4a216
TT
284 cleanups = make_cleanup (do_closedir_cleanup, dp);
285
61bb466e
KW
286 /* Start scan at first pid. */
287 rewinddir (dp);
288
289 do
290 {
9fe4a216
TT
291 int fd;
292 struct cleanup *inner_cleanup;
293
61bb466e
KW
294 /* Get the right pid and procfs path for the pid. */
295 do
296 {
297 dirp = readdir (dp);
298 if (dirp == NULL)
299 {
9fe4a216 300 do_cleanups (cleanups);
61bb466e
KW
301 return;
302 }
dc5dd1eb 303 snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
61bb466e
KW
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 {
dc5dd1eb 312 fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
d737fd7f 313 buf, errno, safe_strerror (errno));
9fe4a216 314 do_cleanups (cleanups);
61bb466e
KW
315 return;
316 }
9fe4a216 317 inner_cleanup = make_cleanup_close (fd);
61bb466e
KW
318
319 pidinfo = (procfs_info *) buf;
320 if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
321 {
dc5dd1eb 322 fprintf_unfiltered (gdb_stderr,
d737fd7f
KW
323 "devctl DCMD_PROC_INFO failed - %d (%s)\n",
324 errno, safe_strerror (errno));
61bb466e
KW
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 }
9fe4a216
TT
345
346 do_cleanups (inner_cleanup);
61bb466e
KW
347 }
348 while (dirp != NULL);
349
9fe4a216 350 do_cleanups (cleanups);
61bb466e
KW
351 return;
352}
353
354void
355procfs_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 {
d737fd7f
KW
390 printf ("failed devctl num mapinfos - %d (%s)\n", err,
391 safe_strerror (err));
61bb466e
KW
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 {
5483d879 405 printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
61bb466e
KW
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. */
500static void
501procfs_files_info (struct target_ops *ignore)
502{
181e7f93
PA
503 struct inferior *inf = current_inferior ();
504
61bb466e 505 printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
3fdfcbf1 506 inf->attach_flag ? "attached" : "child",
61bb466e
KW
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. */
511static int
5483d879 512procfs_can_run (void)
61bb466e
KW
513{
514 return 1;
515}
516
517/* Attach to process PID, then initialize for debugging it. */
518static void
136d6dae 519procfs_attach (struct target_ops *ops, char *args, int from_tty)
61bb466e
KW
520{
521 char *exec_file;
522 int pid;
181e7f93 523 struct inferior *inf;
61bb466e
KW
524
525 if (!args)
e2e0b3e5 526 error_no_arg (_("process-id to attach"));
61bb466e
KW
527
528 pid = atoi (args);
529
530 if (pid == getpid ())
8a3fe4f8 531 error (_("Attaching GDB to itself is not a good idea..."));
61bb466e
KW
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));
181e7f93
PA
547 inf = add_inferior (pid);
548 inf->attach_flag = 1;
7f9f62ba 549
61bb466e 550 push_target (&procfs_ops);
7f9f62ba
PA
551
552 procfs_find_new_threads ();
61bb466e
KW
553}
554
555static void
556procfs_post_attach (pid_t pid)
557{
61bb466e 558 if (exec_bfd)
42e9a5a0 559 solib_create_inferior_hook ();
61bb466e
KW
560}
561
562static ptid_t
563do_attach (ptid_t ptid)
564{
565 procfs_status status;
566 struct sigevent event;
dc5dd1eb 567 char path[PATH_MAX];
61bb466e 568
dc5dd1eb 569 snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
61bb466e
KW
570 ctl_fd = open (path, O_RDWR);
571 if (ctl_fd == -1)
8a3fe4f8 572 error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
dc5dd1eb 573 safe_strerror (errno));
61bb466e 574 if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
8a3fe4f8 575 error (_("Couldn't stop process"));
61bb466e
KW
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)
d737fd7f 587 SignalKill (nto_node (), PIDGET (ptid), 0, SIGCONT, 0, 0);
61bb466e 588 nto_init_solib_absolute_prefix ();
103fd00d 589 return ptid_build (PIDGET (ptid), 0, status.tid);
61bb466e
KW
590}
591
592/* Ask the user what to do when an interrupt is received. */
593static void
dc5dd1eb 594interrupt_query (void)
61bb466e
KW
595{
596 target_terminal_ours ();
597
598 if (query ("Interrupted while waiting for the program.\n\
599Give up (and stop debugging it)? "))
600 {
601 target_mourn_inferior ();
315a522e 602 deprecated_throw_reason (RETURN_QUIT);
61bb466e
KW
603 }
604
605 target_terminal_inferior ();
606}
607
608/* The user typed ^C twice. */
609static void
610nto_interrupt_twice (int signo)
611{
612 signal (signo, ofunc);
613 interrupt_query ();
614 signal (signo, nto_interrupt_twice);
615}
616
617static void
618nto_interrupt (int signo)
619{
620 /* If this doesn't work, try more severe steps. */
621 signal (signo, nto_interrupt_twice);
622
f9c72d52 623 target_stop (inferior_ptid);
61bb466e
KW
624}
625
626static ptid_t
117de6a9
PA
627procfs_wait (struct target_ops *ops,
628 ptid_t ptid, struct target_waitstatus *ourstatus)
61bb466e
KW
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
a6a7f2a5 723 return ptid_build (status.pid, 0, status.tid);
61bb466e
KW
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. */
729static void
56be3814 730procfs_fetch_registers (struct regcache *regcache, int regno)
61bb466e
KW
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)
56be3814 743 nto_supply_gregset (regcache, (char *) &reg.greg);
61bb466e
KW
744 if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
745 == EOK)
56be3814 746 nto_supply_fpregset (regcache, (char *) &reg.fpreg);
61bb466e
KW
747 if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
748 == EOK)
56be3814 749 nto_supply_altregset (regcache, (char *) &reg.altreg);
61bb466e
KW
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. */
760static int
14ef7606 761procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
61bb466e
KW
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. */
782static void
136d6dae 783procfs_detach (struct target_ops *ops, char *args, int from_tty)
61bb466e
KW
784{
785 int siggnal = 0;
7f9f62ba 786 int pid;
61bb466e
KW
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)
d737fd7f 801 SignalKill (nto_node (), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
61bb466e
KW
802
803 close (ctl_fd);
804 ctl_fd = -1;
7f9f62ba
PA
805
806 pid = ptid_get_pid (inferior_ptid);
61bb466e 807 inferior_ptid = null_ptid;
7f9f62ba
PA
808 detach_inferior (pid);
809 init_thread_list ();
61bb466e
KW
810 unpush_target (&procfs_ops); /* Pop out of handling an inferior. */
811}
812
813static int
814procfs_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
827static int
8181d85f 828procfs_insert_breakpoint (struct bp_target_info *bp_tgt)
61bb466e 829{
8181d85f 830 return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
61bb466e
KW
831}
832
833static int
8181d85f 834procfs_remove_breakpoint (struct bp_target_info *bp_tgt)
61bb466e 835{
8181d85f 836 return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
61bb466e
KW
837}
838
839static int
8181d85f 840procfs_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
61bb466e 841{
8181d85f
DJ
842 return procfs_breakpoint (bp_tgt->placed_address,
843 _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
61bb466e
KW
844}
845
846static int
8181d85f 847procfs_remove_hw_breakpoint (struct bp_target_info *bp_tgt)
61bb466e 848{
8181d85f
DJ
849 return procfs_breakpoint (bp_tgt->placed_address,
850 _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
61bb466e
KW
851}
852
853static void
854procfs_resume (ptid_t ptid, int step, enum target_signal signo)
855{
856 int signal_to_pass;
857 procfs_status status;
14ef7606 858 sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
61bb466e
KW
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
14ef7606
AR
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);
61bb466e 879 /* Peter V will be changing this at some point. */
14ef7606 880 sigaddset (run_fault, FLTPAGE);
61bb466e
KW
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 {
d737fd7f
KW
896 SignalKill (nto_node (), PIDGET (inferior_ptid), 0,
897 signal_to_pass, 0, 0);
61bb466e
KW
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
915static void
136d6dae 916procfs_mourn_inferior (struct target_ops *ops)
61bb466e
KW
917{
918 if (!ptid_equal (inferior_ptid, null_ptid))
919 {
d737fd7f 920 SignalKill (nto_node (), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
61bb466e
KW
921 close (ctl_fd);
922 }
923 inferior_ptid = null_ptid;
924 init_thread_list ();
925 unpush_target (&procfs_ops);
926 generic_mourn_inferior ();
61bb466e
KW
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". */
937static void
938breakup_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
989static void
136d6dae
VP
990procfs_create_inferior (struct target_ops *ops, char *exec_file,
991 char *allargs, char **env, int from_tty)
61bb466e
KW
992{
993 struct inheritance inherit;
994 pid_t pid;
995 int flags, errn;
996 char **argv, *args;
3cb3b8df 997 const char *in = "", *out = "", *err = "";
61bb466e
KW
998 int fd, fds[3];
999 sigset_t set;
3cb3b8df 1000 const char *inferior_io_terminal = get_inferior_io_terminal ();
3fdfcbf1 1001 struct inferior *inf;
61bb466e
KW
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 {
d737fd7f 1071 inherit.nd = nto_node ();
61bb466e
KW
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)
8a3fe4f8 1084 error (_("Error spawning %s: %d (%s)"), argv[0], errno,
d737fd7f 1085 safe_strerror (errno));
61bb466e
KW
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));
103fd00d 1095 procfs_find_new_threads ();
61bb466e 1096
3fdfcbf1
AR
1097 inf = add_inferior (pid);
1098 inf->attach_flag = 0;
7f9f62ba 1099
61bb466e
KW
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
61bb466e
KW
1111 if (exec_bfd != NULL
1112 || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
42e9a5a0 1113 solib_create_inferior_hook ();
61bb466e
KW
1114}
1115
1116static void
f9c72d52 1117procfs_stop (ptid_t ptid)
61bb466e
KW
1118{
1119 devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1120}
1121
1122static void
dc5dd1eb 1123procfs_kill_inferior (void)
61bb466e
KW
1124{
1125 target_mourn_inferior ();
1126}
1127
1128/* Store register REGNO, or all registers if REGNO == -1, from the contents
1129 of REGISTERS. */
1130static void
316f2060 1131procfs_prepare_to_store (struct regcache *regcache)
61bb466e
KW
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. */
1137static int
1138get_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
1168void
56be3814 1169procfs_store_registers (struct regcache *regcache, int regno)
61bb466e
KW
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
56be3814 1195 if (nto_regset_fill (regcache, regset, (char *) &reg) == -1)
61bb466e
KW
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",
dc5dd1eb 1202 regno, safe_strerror (err));
61bb466e
KW
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
60441ab9
UW
1215 len = nto_register_area (get_regcache_arch (regcache),
1216 regno, regset, &off);
61bb466e
KW
1217
1218 if (len < 1)
1219 return;
1220
56be3814 1221 regcache_raw_collect (regcache, regno, (char *) &reg + off);
61bb466e
KW
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,
dc5dd1eb 1227 safe_strerror (err));
61bb466e
KW
1228 }
1229}
1230
1231static void
1232notice_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. */
1252static void
1253procfs_notice_signals (ptid_t ptid)
1254{
1255 sigemptyset (&run.trace);
1256 notice_signals ();
1257}
1258
1259static struct tidinfo *
1260procfs_thread_info (pid_t pid, short tid)
1261{
1262/* NYI */
1263 return NULL;
1264}
1265
1266char *
117de6a9 1267procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
61bb466e
KW
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
dc5dd1eb 1276 n = snprintf (buf, 1023, "process %d", pid);
61bb466e
KW
1277
1278#if 0 /* NYI */
1279 tip = procfs_thread_info (pid, tid);
1280 if (tip != NULL)
dc5dd1eb 1281 snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
61bb466e
KW
1282#endif
1283
1284 return buf;
1285}
1286
1287static void
dc5dd1eb 1288init_procfs_ops (void)
61bb466e
KW
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;
c8e73a31 1304 procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
61bb466e
KW
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
1340void
dc5dd1eb 1341_initialize_procfs (void)
61bb466e
KW
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);
61bb466e
KW
1356
1357 /* Stuff some information. */
1358 nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1359 nto_cpuinfo_valid = 1;
1360
1bedd215
AC
1361 add_info ("pidlist", procfs_pidlist, _("pidlist"));
1362 add_info ("meminfo", procfs_meminfo, _("memory information"));
d737fd7f
KW
1363
1364 nto_is_nto_target = procfs_is_nto_target;
61bb466e
KW
1365}
1366
1367
1368static int
1369procfs_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
1398static int
1399procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1400{
1401 return 1;
1402}
1403
1404static int
1405procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1406{
1407 return procfs_hw_watchpoint (addr, -1, type);
1408}
1409
1410static int
1411procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1412{
1413 return procfs_hw_watchpoint (addr, len, type);
1414}
1415
1416static int
1417procfs_stopped_by_watchpoint (void)
1418{
1419 return 0;
1420}
This page took 0.569065 seconds and 4 git commands to generate.