* NEWS (New native configurations): Mention NetBSD/vax.
[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
4 Copyright 2003 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 2 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, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25#include "defs.h"
26
27#include <fcntl.h>
28#include <spawn.h>
29#include <sys/debug.h>
30#include <sys/procfs.h>
31#include <sys/neutrino.h>
32#include <sys/syspage.h>
5483d879 33#include "gdb_dirent.h"
61bb466e
KW
34#include <sys/netmgr.h>
35
36#include "gdb_string.h"
37#include "gdbcore.h"
38#include "inferior.h"
39#include "target.h"
40#include "objfiles.h"
41#include "gdbthread.h"
42#include "nto-tdep.h"
43#include "command.h"
44#include "regcache.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
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
62static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
63
64static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
65 struct mem_attrib *attrib,
66 struct target_ops *);
67
68static void procfs_fetch_registers (int);
69
70static void notice_signals (void);
71
72static void init_procfs_ops (void);
73
74static ptid_t do_attach (ptid_t ptid);
75
76static int procfs_can_use_hw_breakpoint (int, int, int);
77
78static int procfs_insert_hw_breakpoint (CORE_ADDR, char *);
79
80static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *);
81
82static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
83
84static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
85
86static int procfs_stopped_by_watchpoint (void);
87
88/* These two globals are only ever set in procfs_open(), but are
89 referenced elsewhere. 'nto_procfs_node' is a flag used to say
90 whether we are local, or we should get the current node descriptor
91 for the remote QNX node. */
92static char nto_procfs_path[PATH_MAX] = { "/proc" };
93static unsigned nto_procfs_node = ND_LOCAL_NODE;
94
95/* Return the current QNX Node, or error out. This is a simple
96 wrapper for the netmgr_strtond() function. The reason this
97 is required is because QNX node descriptors are transient so
98 we have to re-acquire them every time. */
99static unsigned
dc5dd1eb 100nto_node(void)
61bb466e
KW
101{
102 unsigned node;
103
104 if (ND_NODE_CMP(nto_procfs_node, ND_LOCAL_NODE) == 0)
105 return ND_LOCAL_NODE;
106
107 node = netmgr_strtond(nto_procfs_path,0);
108 if (node == -1)
109 error ("Lost the QNX node. Debug session probably over.");
110
111 return (node);
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. */
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;
126
127 /* Set the default node used for spawning to this one,
128 and only override it if there is a valid arg. */
129
130 nto_procfs_node = ND_LOCAL_NODE;
131 nodestr = arg ? xstrdup (arg) : arg;
132
133 init_thread_list ();
134
135 if (nodestr)
136 {
137 nto_procfs_node = netmgr_strtond (nodestr, &endstr);
138 if (nto_procfs_node == -1)
139 {
140 if (errno == ENOTSUP)
141 printf_filtered ("QNX Net Manager not found.\n");
142 printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
dc5dd1eb 143 errno, safe_strerror (errno));
61bb466e
KW
144 xfree (nodestr);
145 nodestr = NULL;
146 nto_procfs_node = ND_LOCAL_NODE;
147 }
148 else if (*endstr)
149 {
150 if (*(endstr - 1) == '/')
151 *(endstr - 1) = 0;
152 else
153 *endstr = 0;
154 }
155 }
dc5dd1eb 156 snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "", "/proc");
61bb466e
KW
157 if (nodestr)
158 xfree (nodestr);
159
160 fd = open (nto_procfs_path, O_RDONLY);
161 if (fd == -1)
162 {
163 printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
dc5dd1eb 164 safe_strerror (errno));
61bb466e
KW
165 error ("Invalid procfs arg");
166 }
167
168 sysinfo = (void *) buffer;
169 if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
170 {
171 printf_filtered ("Error getting size: %d (%s)\n", errno,
dc5dd1eb 172 safe_strerror (errno));
61bb466e
KW
173 close (fd);
174 error ("Devctl failed.");
175 }
176 else
177 {
178 total_size = sysinfo->total_size;
179 sysinfo = alloca (total_size);
180 if (!sysinfo)
181 {
182 printf_filtered ("Memory error: %d (%s)\n", errno,
dc5dd1eb 183 safe_strerror (errno));
61bb466e
KW
184 close (fd);
185 error ("alloca failed.");
186 }
187 else
188 {
189 if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
190 {
191 printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
dc5dd1eb 192 safe_strerror (errno));
61bb466e
KW
193 close (fd);
194 error ("Devctl failed.");
195 }
196 else
197 {
198 if (sysinfo->type !=
199 nto_map_arch_to_cputype (TARGET_ARCHITECTURE->arch_name))
200 {
201 close (fd);
202 error ("Invalid target CPU.");
203 }
204 }
205 }
206 }
207 close (fd);
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
256void
257procfs_pidlist (char *args, int from_tty)
258{
259 DIR *dp = NULL;
260 struct dirent *dirp = NULL;
261 int fd = -1;
262 char buf[512];
263 procfs_info *pidinfo = NULL;
264 procfs_debuginfo *info = NULL;
265 procfs_status *status = NULL;
266 pid_t num_threads = 0;
267 pid_t pid;
268 char name[512];
269
270 dp = opendir (nto_procfs_path);
271 if (dp == NULL)
272 {
dc5dd1eb
KW
273 fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
274 nto_procfs_path, errno, safe_strerror (errno));
61bb466e
KW
275 return;
276 }
277
278 /* Start scan at first pid. */
279 rewinddir (dp);
280
281 do
282 {
283 /* Get the right pid and procfs path for the pid. */
284 do
285 {
286 dirp = readdir (dp);
287 if (dirp == NULL)
288 {
289 closedir (dp);
290 return;
291 }
dc5dd1eb 292 snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
61bb466e
KW
293 pid = atoi (dirp->d_name);
294 }
295 while (pid == 0);
296
297 /* Open the procfs path. */
298 fd = open (buf, O_RDONLY);
299 if (fd == -1)
300 {
dc5dd1eb
KW
301 fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
302 buf, errno, safe_strerror (errno));
61bb466e
KW
303 closedir (dp);
304 return;
305 }
306
307 pidinfo = (procfs_info *) buf;
308 if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
309 {
dc5dd1eb
KW
310 fprintf_unfiltered (gdb_stderr,
311 "devctl DCMD_PROC_INFO failed - %d (%s)\n", errno,
312 safe_strerror (errno));
61bb466e
KW
313 break;
314 }
315 num_threads = pidinfo->num_threads;
316
317 info = (procfs_debuginfo *) buf;
318 if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
319 strcpy (name, "unavailable");
320 else
321 strcpy (name, info->path);
322
323 /* Collect state info on all the threads. */
324 status = (procfs_status *) buf;
325 for (status->tid = 1; status->tid <= num_threads; status->tid++)
326 {
327 if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
328 && status->tid != 0)
329 break;
330 if (status->tid != 0)
331 printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
332 }
333 close (fd);
334 }
335 while (dirp != NULL);
336
337 close (fd);
338 closedir (dp);
339 return;
340}
341
342void
343procfs_meminfo (char *args, int from_tty)
344{
345 procfs_mapinfo *mapinfos = NULL;
346 static int num_mapinfos = 0;
347 procfs_mapinfo *mapinfo_p, *mapinfo_p2;
348 int flags = ~0, err, num, i, j;
349
350 struct
351 {
352 procfs_debuginfo info;
353 char buff[_POSIX_PATH_MAX];
354 } map;
355
356 struct info
357 {
358 unsigned addr;
359 unsigned size;
360 unsigned flags;
361 unsigned debug_vaddr;
362 unsigned long long offset;
363 };
364
365 struct printinfo
366 {
367 unsigned long long ino;
368 unsigned dev;
369 struct info text;
370 struct info data;
371 char name[256];
372 } printme;
373
374 /* Get the number of map entrys. */
375 err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num);
376 if (err != EOK)
377 {
5483d879 378 printf ("failed devctl num mapinfos - %d (%s)\n", err, safe_strerror (err));
61bb466e
KW
379 return;
380 }
381
382 mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
383
384 num_mapinfos = num;
385 mapinfo_p = mapinfos;
386
387 /* Fill the map entrys. */
388 err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num
389 * sizeof (procfs_mapinfo), &num);
390 if (err != EOK)
391 {
5483d879 392 printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
61bb466e
KW
393 xfree (mapinfos);
394 return;
395 }
396
397 num = min (num, num_mapinfos);
398
399 /* Run through the list of mapinfos, and store the data and text info
400 so we can print it at the bottom of the loop. */
401 for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
402 {
403 if (!(mapinfo_p->flags & flags))
404 mapinfo_p->ino = 0;
405
406 if (mapinfo_p->ino == 0) /* Already visited. */
407 continue;
408
409 map.info.vaddr = mapinfo_p->vaddr;
410
411 err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
412 if (err != EOK)
413 continue;
414
415 memset (&printme, 0, sizeof printme);
416 printme.dev = mapinfo_p->dev;
417 printme.ino = mapinfo_p->ino;
418 printme.text.addr = mapinfo_p->vaddr;
419 printme.text.size = mapinfo_p->size;
420 printme.text.flags = mapinfo_p->flags;
421 printme.text.offset = mapinfo_p->offset;
422 printme.text.debug_vaddr = map.info.vaddr;
423 strcpy (printme.name, map.info.path);
424
425 /* Check for matching data. */
426 for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
427 {
428 if (mapinfo_p2->vaddr != mapinfo_p->vaddr
429 && mapinfo_p2->ino == mapinfo_p->ino
430 && mapinfo_p2->dev == mapinfo_p->dev)
431 {
432 map.info.vaddr = mapinfo_p2->vaddr;
433 err =
434 devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
435 if (err != EOK)
436 continue;
437
438 if (strcmp (map.info.path, printme.name))
439 continue;
440
441 /* Lower debug_vaddr is always text, if nessessary, swap. */
442 if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
443 {
444 memcpy (&(printme.data), &(printme.text),
445 sizeof (printme.data));
446 printme.text.addr = mapinfo_p2->vaddr;
447 printme.text.size = mapinfo_p2->size;
448 printme.text.flags = mapinfo_p2->flags;
449 printme.text.offset = mapinfo_p2->offset;
450 printme.text.debug_vaddr = map.info.vaddr;
451 }
452 else
453 {
454 printme.data.addr = mapinfo_p2->vaddr;
455 printme.data.size = mapinfo_p2->size;
456 printme.data.flags = mapinfo_p2->flags;
457 printme.data.offset = mapinfo_p2->offset;
458 printme.data.debug_vaddr = map.info.vaddr;
459 }
460 mapinfo_p2->ino = 0;
461 }
462 }
463 mapinfo_p->ino = 0;
464
465 printf_filtered ("%s\n", printme.name);
466 printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
467 printme.text.addr);
468 printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
469 printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
470 printf_filtered ("\t\toffset=%016llx\n", printme.text.offset);
471 if (printme.data.size)
472 {
473 printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
474 printme.data.addr);
475 printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
476 printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
477 printf_filtered ("\t\toffset=%016llx\n", printme.data.offset);
478 }
479 printf_filtered ("\tdev=0x%x\n", printme.dev);
480 printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
481 }
482 xfree (mapinfos);
483 return;
484}
485
486/* Print status information about what we're accessing. */
487static void
488procfs_files_info (struct target_ops *ignore)
489{
490 printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
491 attach_flag ? "attached" : "child",
492 target_pid_to_str (inferior_ptid), nto_procfs_path);
493}
494
495/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
496static int
5483d879 497procfs_can_run (void)
61bb466e
KW
498{
499 return 1;
500}
501
502/* Attach to process PID, then initialize for debugging it. */
503static void
504procfs_attach (char *args, int from_tty)
505{
506 char *exec_file;
507 int pid;
508
509 if (!args)
510 error_no_arg ("process-id to attach");
511
512 pid = atoi (args);
513
514 if (pid == getpid ())
515 error ("Attaching GDB to itself is not a good idea...");
516
517 if (from_tty)
518 {
519 exec_file = (char *) get_exec_file (0);
520
521 if (exec_file)
522 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
523 target_pid_to_str (pid_to_ptid (pid)));
524 else
525 printf_unfiltered ("Attaching to %s\n",
526 target_pid_to_str (pid_to_ptid (pid)));
527
528 gdb_flush (gdb_stdout);
529 }
530 inferior_ptid = do_attach (pid_to_ptid (pid));
531 push_target (&procfs_ops);
532}
533
534static void
535procfs_post_attach (pid_t pid)
536{
537#ifdef SOLIB_CREATE_INFERIOR_HOOK
538 if (exec_bfd)
539 SOLIB_CREATE_INFERIOR_HOOK (pid);
540#endif
541}
542
543static ptid_t
544do_attach (ptid_t ptid)
545{
546 procfs_status status;
547 struct sigevent event;
dc5dd1eb 548 char path[PATH_MAX];
61bb466e 549
dc5dd1eb 550 snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
61bb466e
KW
551 ctl_fd = open (path, O_RDWR);
552 if (ctl_fd == -1)
553 error ("Couldn't open proc file %s, error %d (%s)", path, errno,
dc5dd1eb 554 safe_strerror (errno));
61bb466e
KW
555 if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
556 error ("Couldn't stop process");
557
558 /* Define a sigevent for process stopped notification. */
559 event.sigev_notify = SIGEV_SIGNAL_THREAD;
560 event.sigev_signo = SIGUSR1;
561 event.sigev_code = 0;
562 event.sigev_value.sival_ptr = NULL;
563 event.sigev_priority = -1;
564 devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
565
566 if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
567 && status.flags & _DEBUG_FLAG_STOPPED)
568 SignalKill (nto_node(), PIDGET (ptid), 0, SIGCONT, 0, 0);
569 attach_flag = 1;
570 nto_init_solib_absolute_prefix ();
571 return ptid;
572}
573
574/* Ask the user what to do when an interrupt is received. */
575static void
dc5dd1eb 576interrupt_query (void)
61bb466e
KW
577{
578 target_terminal_ours ();
579
580 if (query ("Interrupted while waiting for the program.\n\
581Give up (and stop debugging it)? "))
582 {
583 target_mourn_inferior ();
584 throw_exception (RETURN_QUIT);
585 }
586
587 target_terminal_inferior ();
588}
589
590/* The user typed ^C twice. */
591static void
592nto_interrupt_twice (int signo)
593{
594 signal (signo, ofunc);
595 interrupt_query ();
596 signal (signo, nto_interrupt_twice);
597}
598
599static void
600nto_interrupt (int signo)
601{
602 /* If this doesn't work, try more severe steps. */
603 signal (signo, nto_interrupt_twice);
604
605 target_stop ();
606}
607
608static ptid_t
609procfs_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
610{
611 sigset_t set;
612 siginfo_t info;
613 procfs_status status;
614 static int exit_signo = 0; /* To track signals that cause termination. */
615
616 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
617
618 if (ptid_equal (inferior_ptid, null_ptid))
619 {
620 ourstatus->kind = TARGET_WAITKIND_STOPPED;
621 ourstatus->value.sig = TARGET_SIGNAL_0;
622 exit_signo = 0;
623 return null_ptid;
624 }
625
626 sigemptyset (&set);
627 sigaddset (&set, SIGUSR1);
628
629 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
630 while (!(status.flags & _DEBUG_FLAG_ISTOP))
631 {
632 ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
633 sigwaitinfo (&set, &info);
634 signal (SIGINT, ofunc);
635 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
636 }
637
638 if (status.flags & _DEBUG_FLAG_SSTEP)
639 {
640 ourstatus->kind = TARGET_WAITKIND_STOPPED;
641 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
642 }
643 /* Was it a breakpoint? */
644 else if (status.flags & _DEBUG_FLAG_TRACE)
645 {
646 ourstatus->kind = TARGET_WAITKIND_STOPPED;
647 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
648 }
649 else if (status.flags & _DEBUG_FLAG_ISTOP)
650 {
651 switch (status.why)
652 {
653 case _DEBUG_WHY_SIGNALLED:
654 ourstatus->kind = TARGET_WAITKIND_STOPPED;
655 ourstatus->value.sig =
656 target_signal_from_host (status.info.si_signo);
657 exit_signo = 0;
658 break;
659 case _DEBUG_WHY_FAULTED:
660 ourstatus->kind = TARGET_WAITKIND_STOPPED;
661 if (status.info.si_signo == SIGTRAP)
662 {
663 ourstatus->value.sig = 0;
664 exit_signo = 0;
665 }
666 else
667 {
668 ourstatus->value.sig =
669 target_signal_from_host (status.info.si_signo);
670 exit_signo = ourstatus->value.sig;
671 }
672 break;
673
674 case _DEBUG_WHY_TERMINATED:
675 {
676 int waitval = 0;
677
678 waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
679 if (exit_signo)
680 {
681 /* Abnormal death. */
682 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
683 ourstatus->value.sig = exit_signo;
684 }
685 else
686 {
687 /* Normal death. */
688 ourstatus->kind = TARGET_WAITKIND_EXITED;
689 ourstatus->value.integer = WEXITSTATUS (waitval);
690 }
691 exit_signo = 0;
692 break;
693 }
694
695 case _DEBUG_WHY_REQUESTED:
696 /* We are assuming a requested stop is due to a SIGINT. */
697 ourstatus->kind = TARGET_WAITKIND_STOPPED;
698 ourstatus->value.sig = TARGET_SIGNAL_INT;
699 exit_signo = 0;
700 break;
701 }
702 }
703
704 return inferior_ptid;
705}
706
707/* Read the current values of the inferior's registers, both the
708 general register set and floating point registers (if supported)
709 and update gdb's idea of their current values. */
710static void
711procfs_fetch_registers (int regno)
712{
713 union
714 {
715 procfs_greg greg;
716 procfs_fpreg fpreg;
717 procfs_altreg altreg;
718 }
719 reg;
720 int regsize;
721
722 procfs_set_thread (inferior_ptid);
723 if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
724 nto_supply_gregset ((char *) &reg.greg);
725 if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
726 == EOK)
727 nto_supply_fpregset ((char *) &reg.fpreg);
728 if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
729 == EOK)
730 nto_supply_altregset ((char *) &reg.altreg);
731}
732
733/* Copy LEN bytes to/from inferior's memory starting at MEMADDR
734 from/to debugger memory starting at MYADDR. Copy from inferior
735 if DOWRITE is zero or to inferior if DOWRITE is nonzero.
736
737 Returns the length copied, which is either the LEN argument or
738 zero. This xfer function does not do partial moves, since procfs_ops
739 doesn't allow memory operations to cross below us in the target stack
740 anyway. */
741static int
742procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
743 struct mem_attrib *attrib, struct target_ops *target)
744{
745 int nbytes = 0;
746
747 if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
748 {
749 if (dowrite)
750 nbytes = write (ctl_fd, myaddr, len);
751 else
752 nbytes = read (ctl_fd, myaddr, len);
753 if (nbytes < 0)
754 nbytes = 0;
755 }
756 return (nbytes);
757}
758
759/* Take a program previously attached to and detaches it.
760 The program resumes execution and will no longer stop
761 on signals, etc. We'd better not have left any breakpoints
762 in the program or it'll die when it hits one. */
763static void
764procfs_detach (char *args, int from_tty)
765{
766 int siggnal = 0;
767
768 if (from_tty)
769 {
770 char *exec_file = get_exec_file (0);
771 if (exec_file == 0)
772 exec_file = "";
773 printf_unfiltered ("Detaching from program: %s %s\n",
774 exec_file, target_pid_to_str (inferior_ptid));
775 gdb_flush (gdb_stdout);
776 }
777 if (args)
778 siggnal = atoi (args);
779
780 if (siggnal)
781 SignalKill (nto_node(), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
782
783 close (ctl_fd);
784 ctl_fd = -1;
785 init_thread_list ();
786 inferior_ptid = null_ptid;
787 attach_flag = 0;
788 unpush_target (&procfs_ops); /* Pop out of handling an inferior. */
789}
790
791static int
792procfs_breakpoint (CORE_ADDR addr, int type, int size)
793{
794 procfs_break brk;
795
796 brk.type = type;
797 brk.addr = addr;
798 brk.size = size;
799 errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
800 if (errno != EOK)
801 return 1;
802 return 0;
803}
804
805static int
806procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
807{
808 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
809}
810
811static int
812procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
813{
814 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
815}
816
817static int
818procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
819{
820 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
821}
822
823static int
824procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
825{
826 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
827}
828
829static void
830procfs_resume (ptid_t ptid, int step, enum target_signal signo)
831{
832 int signal_to_pass;
833 procfs_status status;
834
835 if (ptid_equal (inferior_ptid, null_ptid))
836 return;
837
838 procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
839 ptid);
840
841 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
842 if (step)
843 run.flags |= _DEBUG_RUN_STEP;
844
845 sigemptyset ((sigset_t *) &run.fault);
846 sigaddset ((sigset_t *) &run.fault, FLTBPT);
847 sigaddset ((sigset_t *) &run.fault, FLTTRACE);
848 sigaddset ((sigset_t *) &run.fault, FLTILL);
849 sigaddset ((sigset_t *) &run.fault, FLTPRIV);
850 sigaddset ((sigset_t *) &run.fault, FLTBOUNDS);
851 sigaddset ((sigset_t *) &run.fault, FLTIOVF);
852 sigaddset ((sigset_t *) &run.fault, FLTIZDIV);
853 sigaddset ((sigset_t *) &run.fault, FLTFPE);
854 /* Peter V will be changing this at some point. */
855 sigaddset ((sigset_t *) &run.fault, FLTPAGE);
856
857 run.flags |= _DEBUG_RUN_ARM;
858
859 sigemptyset (&run.trace);
860 notice_signals ();
861 signal_to_pass = target_signal_to_host (signo);
862
863 if (signal_to_pass)
864 {
865 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
866 signal_to_pass = target_signal_to_host (signo);
867 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
868 {
869 if (signal_to_pass != status.info.si_signo)
870 {
871 SignalKill (nto_node(), PIDGET (inferior_ptid), 0, signal_to_pass,
872 0, 0);
873 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
874 }
875 else /* Let it kill the program without telling us. */
876 sigdelset (&run.trace, signal_to_pass);
877 }
878 }
879 else
880 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
881
882 errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
883 if (errno != EOK)
884 {
885 perror ("run error!\n");
886 return;
887 }
888}
889
890static void
dc5dd1eb 891procfs_mourn_inferior (void)
61bb466e
KW
892{
893 if (!ptid_equal (inferior_ptid, null_ptid))
894 {
895 SignalKill (nto_node(), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
896 close (ctl_fd);
897 }
898 inferior_ptid = null_ptid;
899 init_thread_list ();
900 unpush_target (&procfs_ops);
901 generic_mourn_inferior ();
902 attach_flag = 0;
903}
904
905/* This function breaks up an argument string into an argument
906 vector suitable for passing to execvp().
907 E.g., on "run a b c d" this routine would get as input
908 the string "a b c d", and as output it would fill in argv with
909 the four arguments "a", "b", "c", "d". The only additional
910 functionality is simple quoting. The gdb command:
911 run a "b c d" f
912 will fill in argv with the three args "a", "b c d", "e". */
913static void
914breakup_args (char *scratch, char **argv)
915{
916 char *pp, *cp = scratch;
917 char quoting = 0;
918
919 for (;;)
920 {
921 /* Scan past leading separators. */
922 quoting = 0;
923 while (*cp == ' ' || *cp == '\t' || *cp == '\n')
924 cp++;
925
926 /* Break if at end of string. */
927 if (*cp == '\0')
928 break;
929
930 /* Take an arg. */
931 if (*cp == '"')
932 {
933 cp++;
934 quoting = strchr (cp, '"') ? 1 : 0;
935 }
936
937 *argv++ = cp;
938
939 /* Scan for next arg separator. */
940 pp = cp;
941 if (quoting)
942 cp = strchr (pp, '"');
943 if ((cp == NULL) || (!quoting))
944 cp = strchr (pp, ' ');
945 if (cp == NULL)
946 cp = strchr (pp, '\t');
947 if (cp == NULL)
948 cp = strchr (pp, '\n');
949
950 /* No separators => end of string => break. */
951 if (cp == NULL)
952 {
953 pp = cp;
954 break;
955 }
956
957 /* Replace the separator with a terminator. */
958 *cp++ = '\0';
959 }
960
961 /* Execv requires a null-terminated arg vector. */
962 *argv = NULL;
963}
964
965static void
966procfs_create_inferior (char *exec_file, char *allargs, char **env)
967{
968 struct inheritance inherit;
969 pid_t pid;
970 int flags, errn;
971 char **argv, *args;
972 char *in = "", *out = "", *err = "";
973 int fd, fds[3];
974 sigset_t set;
975
976 argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
977 sizeof (*argv));
978 argv[0] = get_exec_file (1);
979 if (!argv[0])
980 {
981 if (exec_file)
982 argv[0] = exec_file;
983 else
984 return;
985 }
986
987 args = xstrdup (allargs);
988 breakup_args (args, exec_file ? &argv[1] : &argv[0]);
989
990 argv = nto_parse_redirection (argv, &in, &out, &err);
991
992 fds[0] = STDIN_FILENO;
993 fds[1] = STDOUT_FILENO;
994 fds[2] = STDERR_FILENO;
995
996 /* If the user specified I/O via gdb's --tty= arg, use it, but only
997 if the i/o is not also being specified via redirection. */
998 if (inferior_io_terminal)
999 {
1000 if (!in[0])
1001 in = inferior_io_terminal;
1002 if (!out[0])
1003 out = inferior_io_terminal;
1004 if (!err[0])
1005 err = inferior_io_terminal;
1006 }
1007
1008 if (in[0])
1009 {
1010 fd = open (in, O_RDONLY);
1011 if (fd == -1)
1012 perror (in);
1013 else
1014 fds[0] = fd;
1015 }
1016 if (out[0])
1017 {
1018 fd = open (out, O_WRONLY);
1019 if (fd == -1)
1020 perror (out);
1021 else
1022 fds[1] = fd;
1023 }
1024 if (err[0])
1025 {
1026 fd = open (err, O_WRONLY);
1027 if (fd == -1)
1028 perror (err);
1029 else
1030 fds[2] = fd;
1031 }
1032
1033 /* Clear any pending SIGUSR1's but keep the behavior the same. */
1034 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
1035
1036 sigemptyset (&set);
1037 sigaddset (&set, SIGUSR1);
1038 sigprocmask (SIG_UNBLOCK, &set, NULL);
1039
1040 memset (&inherit, 0, sizeof (inherit));
1041
1042 if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
1043 {
1044 inherit.nd = nto_node();
1045 inherit.flags |= SPAWN_SETND;
1046 inherit.flags &= ~SPAWN_EXEC;
1047 }
1048 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
1049 inherit.pgroup = SPAWN_NEWPGROUP;
1050 pid = spawnp (argv[0], 3, fds, &inherit, argv,
1051 ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
1052 xfree (args);
1053
1054 sigprocmask (SIG_BLOCK, &set, NULL);
1055
1056 if (pid == -1)
dc5dd1eb 1057 error ("Error spawning %s: %d (%s)", argv[0], errno, safe_strerror (errno));
61bb466e
KW
1058
1059 if (fds[0] != STDIN_FILENO)
1060 close (fds[0]);
1061 if (fds[1] != STDOUT_FILENO)
1062 close (fds[1]);
1063 if (fds[2] != STDERR_FILENO)
1064 close (fds[2]);
1065
1066 inferior_ptid = do_attach (pid_to_ptid (pid));
1067
1068 attach_flag = 0;
1069 flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */
1070 errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
1071 if (errn != EOK)
1072 {
1073 /* FIXME: expected warning? */
1074 /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
1075 errn, strerror(errn) ); */
1076 }
1077 push_target (&procfs_ops);
1078 target_terminal_init ();
1079
1080#ifdef SOLIB_CREATE_INFERIOR_HOOK
1081 if (exec_bfd != NULL
1082 || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
1083 SOLIB_CREATE_INFERIOR_HOOK (pid);
1084#endif
1085}
1086
1087static void
dc5dd1eb 1088procfs_stop (void)
61bb466e
KW
1089{
1090 devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1091}
1092
1093static void
dc5dd1eb 1094procfs_kill_inferior (void)
61bb466e
KW
1095{
1096 target_mourn_inferior ();
1097}
1098
1099/* Store register REGNO, or all registers if REGNO == -1, from the contents
1100 of REGISTERS. */
1101static void
dc5dd1eb 1102procfs_prepare_to_store (void)
61bb466e
KW
1103{
1104}
1105
1106/* Fill buf with regset and return devctl cmd to do the setting. Return
1107 -1 if we fail to get the regset. Store size of regset in regsize. */
1108static int
1109get_regset (int regset, char *buf, int bufsize, int *regsize)
1110{
1111 int dev_get, dev_set;
1112 switch (regset)
1113 {
1114 case NTO_REG_GENERAL:
1115 dev_get = DCMD_PROC_GETGREG;
1116 dev_set = DCMD_PROC_SETGREG;
1117 break;
1118
1119 case NTO_REG_FLOAT:
1120 dev_get = DCMD_PROC_GETFPREG;
1121 dev_set = DCMD_PROC_SETFPREG;
1122 break;
1123
1124 case NTO_REG_ALT:
1125 dev_get = DCMD_PROC_GETALTREG;
1126 dev_set = DCMD_PROC_SETALTREG;
1127 break;
1128
1129 case NTO_REG_SYSTEM:
1130 default:
1131 return -1;
1132 }
1133 if (devctl (ctl_fd, dev_get, &buf, bufsize, regsize) != EOK)
1134 return -1;
1135
1136 return dev_set;
1137}
1138
1139void
1140procfs_store_registers (int regno)
1141{
1142 union
1143 {
1144 procfs_greg greg;
1145 procfs_fpreg fpreg;
1146 procfs_altreg altreg;
1147 }
1148 reg;
1149 unsigned off;
1150 int len, regset, regsize, dev_set, err;
1151 char *data;
1152
1153 if (ptid_equal (inferior_ptid, null_ptid))
1154 return;
1155 procfs_set_thread (inferior_ptid);
1156
1157 if (regno == -1)
1158 {
1159 for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
1160 {
1161 dev_set = get_regset (regset, (char *) &reg,
1162 sizeof (reg), &regsize);
1163 if (dev_set == -1)
1164 continue;
1165
1166 if (nto_regset_fill (regset, (char *) &reg) == -1)
1167 continue;
1168
1169 err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1170 if (err != EOK)
1171 fprintf_unfiltered (gdb_stderr,
1172 "Warning unable to write regset %d: %s\n",
dc5dd1eb 1173 regno, safe_strerror (err));
61bb466e
KW
1174 }
1175 }
1176 else
1177 {
1178 regset = nto_regset_id (regno);
1179 if (regset == -1)
1180 return;
1181
1182 dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
1183 if (dev_set == -1)
1184 return;
1185
1186 len = nto_register_area (regno, regset, &off);
1187
1188 if (len < 1)
1189 return;
1190
1191 regcache_collect (regno, (char *) &reg + off);
1192
1193 err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1194 if (err != EOK)
1195 fprintf_unfiltered (gdb_stderr,
1196 "Warning unable to write regset %d: %s\n", regno,
dc5dd1eb 1197 safe_strerror (err));
61bb466e
KW
1198 }
1199}
1200
1201static void
1202notice_signals (void)
1203{
1204 int signo;
1205
1206 for (signo = 1; signo < NSIG; signo++)
1207 {
1208 if (signal_stop_state (target_signal_from_host (signo)) == 0
1209 && signal_print_state (target_signal_from_host (signo)) == 0
1210 && signal_pass_state (target_signal_from_host (signo)) == 1)
1211 sigdelset (&run.trace, signo);
1212 else
1213 sigaddset (&run.trace, signo);
1214 }
1215}
1216
1217/* When the user changes the state of gdb's signal handling via the
1218 "handle" command, this function gets called to see if any change
1219 in the /proc interface is required. It is also called internally
1220 by other /proc interface functions to initialize the state of
1221 the traced signal set. */
1222static void
1223procfs_notice_signals (ptid_t ptid)
1224{
1225 sigemptyset (&run.trace);
1226 notice_signals ();
1227}
1228
1229static struct tidinfo *
1230procfs_thread_info (pid_t pid, short tid)
1231{
1232/* NYI */
1233 return NULL;
1234}
1235
1236char *
1237procfs_pid_to_str (ptid_t ptid)
1238{
1239 static char buf[1024];
1240 int pid, tid, n;
1241 struct tidinfo *tip;
1242
1243 pid = ptid_get_pid (ptid);
1244 tid = ptid_get_tid (ptid);
1245
dc5dd1eb 1246 n = snprintf (buf, 1023, "process %d", pid);
61bb466e
KW
1247
1248#if 0 /* NYI */
1249 tip = procfs_thread_info (pid, tid);
1250 if (tip != NULL)
dc5dd1eb 1251 snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
61bb466e
KW
1252#endif
1253
1254 return buf;
1255}
1256
1257static void
dc5dd1eb 1258init_procfs_ops (void)
61bb466e
KW
1259{
1260 procfs_ops.to_shortname = "procfs";
1261 procfs_ops.to_longname = "QNX Neutrino procfs child process";
1262 procfs_ops.to_doc =
1263 "QNX Neutrino procfs child process (started by the \"run\" command).\n\
1264 target procfs <node>";
1265 procfs_ops.to_open = procfs_open;
1266 procfs_ops.to_attach = procfs_attach;
1267 procfs_ops.to_post_attach = procfs_post_attach;
1268 procfs_ops.to_detach = procfs_detach;
1269 procfs_ops.to_resume = procfs_resume;
1270 procfs_ops.to_wait = procfs_wait;
1271 procfs_ops.to_fetch_registers = procfs_fetch_registers;
1272 procfs_ops.to_store_registers = procfs_store_registers;
1273 procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
1274 procfs_ops.to_xfer_memory = procfs_xfer_memory;
1275 procfs_ops.to_files_info = procfs_files_info;
1276 procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
1277 procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
1278 procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
1279 procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
1280 procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
1281 procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
1282 procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
1283 procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
1284 procfs_ops.to_terminal_init = terminal_init_inferior;
1285 procfs_ops.to_terminal_inferior = terminal_inferior;
1286 procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1287 procfs_ops.to_terminal_ours = terminal_ours;
1288 procfs_ops.to_terminal_info = child_terminal_info;
1289 procfs_ops.to_kill = procfs_kill_inferior;
1290 procfs_ops.to_create_inferior = procfs_create_inferior;
1291 procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
1292 procfs_ops.to_can_run = procfs_can_run;
1293 procfs_ops.to_notice_signals = procfs_notice_signals;
1294 procfs_ops.to_thread_alive = procfs_thread_alive;
1295 procfs_ops.to_find_new_threads = procfs_find_new_threads;
1296 procfs_ops.to_pid_to_str = procfs_pid_to_str;
1297 procfs_ops.to_stop = procfs_stop;
1298 procfs_ops.to_stratum = process_stratum;
1299 procfs_ops.to_has_all_memory = 1;
1300 procfs_ops.to_has_memory = 1;
1301 procfs_ops.to_has_stack = 1;
1302 procfs_ops.to_has_registers = 1;
1303 procfs_ops.to_has_execution = 1;
1304 procfs_ops.to_magic = OPS_MAGIC;
1305 procfs_ops.to_have_continuable_watchpoint = 1;
1306}
1307
1308#define OSTYPE_NTO 1
1309
1310void
dc5dd1eb 1311_initialize_procfs (void)
61bb466e
KW
1312{
1313 sigset_t set;
1314
1315 init_procfs_ops ();
1316 add_target (&procfs_ops);
1317
1318 /* We use SIGUSR1 to gain control after we block waiting for a process.
1319 We use sigwaitevent to wait. */
1320 sigemptyset (&set);
1321 sigaddset (&set, SIGUSR1);
1322 sigprocmask (SIG_BLOCK, &set, NULL);
1323
1324 /* Set up trace and fault sets, as gdb expects them. */
1325 sigemptyset (&run.trace);
1326 notice_signals ();
1327
1328 /* Stuff some information. */
1329 nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1330 nto_cpuinfo_valid = 1;
1331
1332 add_info ("pidlist", procfs_pidlist, "pidlist");
1333 add_info ("meminfo", procfs_meminfo, "memory information");
1334}
1335
1336
1337static int
1338procfs_hw_watchpoint (int addr, int len, int type)
1339{
1340 procfs_break brk;
1341
1342 switch (type)
1343 {
1344 case 1: /* Read. */
1345 brk.type = _DEBUG_BREAK_RD;
1346 break;
1347 case 2: /* Read/Write. */
1348 brk.type = _DEBUG_BREAK_RW;
1349 break;
1350 default: /* Modify. */
1351/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason. */
1352 brk.type = _DEBUG_BREAK_RW;
1353 }
1354 brk.type |= _DEBUG_BREAK_HW; /* Always ask for HW. */
1355 brk.addr = addr;
1356 brk.size = len;
1357
1358 errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
1359 if (errno != EOK)
1360 {
1361 perror ("Failed to set hardware watchpoint");
1362 return -1;
1363 }
1364 return 0;
1365}
1366
1367static int
1368procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1369{
1370 return 1;
1371}
1372
1373static int
1374procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1375{
1376 return procfs_hw_watchpoint (addr, -1, type);
1377}
1378
1379static int
1380procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1381{
1382 return procfs_hw_watchpoint (addr, len, type);
1383}
1384
1385static int
1386procfs_stopped_by_watchpoint (void)
1387{
1388 return 0;
1389}
This page took 0.150612 seconds and 4 git commands to generate.