1 /* QNX Neutrino specific low level interface, for the remote server
3 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 #include <sys/procfs.h>
30 #include <sys/iomgr.h>
31 #include <sys/neutrino.h>
34 extern int using_threads;
35 int using_threads = 1;
38 nto_trace (const char *fmt, ...)
42 if (debug_threads == 0)
44 fprintf (stderr, "nto:");
45 va_start (arg_list, fmt);
46 vfprintf (stderr, fmt, arg_list);
50 #define TRACE nto_trace
52 /* Structure holding neutrino specific information about
57 char nto_procfs_path[PATH_MAX];
60 int exit_signo; /* For tracking exit status. */
63 static struct nto_inferior nto_inferior;
66 init_nto_inferior (struct nto_inferior *nto_inferior)
68 memset (nto_inferior, 0, sizeof (struct nto_inferior));
69 nto_inferior->ctl_fd = -1;
70 nto_inferior->pid = -1;
76 if (nto_inferior.ctl_fd != -1)
78 nto_trace ("Closing fd\n");
79 close (nto_inferior.ctl_fd);
80 init_nto_inferior (&nto_inferior);
84 /* Set current thread. Return 1 on success, 0 otherwise. */
87 nto_set_thread (ptid_t ptid)
91 TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid),
93 if (nto_inferior.ctl_fd != -1
94 && !ptid_equal (ptid, null_ptid)
95 && !ptid_equal (ptid, minus_one_ptid))
97 pthread_t tid = ptid_get_lwp (ptid);
99 if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid,
103 TRACE ("%s: Error: failed to set current thread\n", __func__);
108 /* This function will determine all alive threads. Note that we do not list
109 dead but unjoined threads even though they are still in the process' thread
112 NTO_INFERIOR must not be NULL. */
115 nto_find_new_threads (struct nto_inferior *nto_inferior)
119 TRACE ("%s pid:%d\n", __func__, nto_inferior->pid);
121 if (nto_inferior->ctl_fd == -1)
124 for (tid = 1;; ++tid)
126 procfs_status status;
131 err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status,
134 if (err != EOK || status.tid == 0)
137 /* All threads in between are gone. */
138 while (tid != status.tid || status.state == STATE_DEAD)
140 struct thread_info *ti;
142 ptid = ptid_build (nto_inferior->pid, tid, 0);
143 ti = find_thread_ptid (ptid);
146 TRACE ("Removing thread %d\n", tid);
149 if (tid == status.tid)
154 if (status.state != STATE_DEAD)
156 TRACE ("Adding thread %d\n", tid);
157 ptid = ptid_build (nto_inferior->pid, tid, 0);
158 if (!find_thread_ptid (ptid))
159 add_thread (ptid, NULL);
164 /* Given pid, open procfs path. */
167 do_attach (pid_t pid)
169 procfs_status status;
170 struct sigevent event;
172 if (nto_inferior.ctl_fd != -1)
174 close (nto_inferior.ctl_fd);
175 init_nto_inferior (&nto_inferior);
177 snprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid);
178 nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR);
179 if (nto_inferior.ctl_fd == -1)
181 TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path);
182 init_nto_inferior (&nto_inferior);
185 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0)
191 nto_inferior.pid = pid;
192 /* Define a sigevent for process stopped notification. */
193 event.sigev_notify = SIGEV_SIGNAL_THREAD;
194 event.sigev_signo = SIGUSR1;
195 event.sigev_code = 0;
196 event.sigev_value.sival_ptr = NULL;
197 event.sigev_priority = -1;
198 devctl (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
200 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
202 && (status.flags & _DEBUG_FLAG_STOPPED))
207 ptid = ptid_build (status.pid, status.tid, 0);
208 the_low_target.arch_setup ();
209 add_process (status.pid, 1);
210 TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
211 ptid_get_lwp (ptid));
212 nto_find_new_threads (&nto_inferior);
223 /* Read or write LEN bytes from/to inferior's MEMADDR memory address
224 into gdbservers's MYADDR buffer. Return number of bytes actually
228 nto_xfer_memory (off_t memaddr, unsigned char *myaddr, int len,
233 if (lseek (nto_inferior.ctl_fd, memaddr, SEEK_SET) == memaddr)
236 nbytes = write (nto_inferior.ctl_fd, myaddr, len);
238 nbytes = read (nto_inferior.ctl_fd, myaddr, len);
245 TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, strerror (e));
250 /* Insert or remove breakpoint or watchpoint at address ADDR.
251 TYPE can be one of Neutrino breakpoint types. SIZE must be 0 for
252 inserting the point, -1 for removing it.
254 Return 0 on success, 1 otherwise. */
257 nto_breakpoint (CORE_ADDR addr, int type, int size)
264 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)
270 /* Read auxiliary vector from inferior's initial stack into gdbserver's
271 MYADDR buffer, up to LEN bytes.
273 Return number of bytes read. */
276 nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack,
277 unsigned char *myaddr,
282 unsigned int len_read = 0;
284 /* Skip over argc, argv and envp... Comment from ldd.c:
286 The startup frame is set-up so that we have:
291 envp1 <----- void *frame + (argc + 2) * sizeof(char *)
296 argc <------ void * frame
298 On entry to ldd, frame gives the address of argc on the stack. */
299 if (nto_xfer_memory (initial_stack, (unsigned char *)&anint,
300 sizeof (anint), 0) != sizeof (anint))
303 /* Size of pointer is assumed to be 4 bytes (32 bit arch. ) */
304 data_ofs += (anint + 2) * sizeof (void *); /* + 2 comes from argc itself and
305 NULL terminating pointer in
308 /* Now loop over env table: */
309 while (nto_xfer_memory (initial_stack + data_ofs,
310 (unsigned char *)&anint, sizeof (anint), 0)
313 data_ofs += sizeof (anint);
317 initial_stack += data_ofs;
319 memset (myaddr, 0, len);
320 while (len_read <= len - sizeof (auxv_t))
322 auxv_t *auxv = (auxv_t *)myaddr;
324 /* Search backwards until we have read AT_PHDR (num. 3),
325 AT_PHENT (num 4), AT_PHNUM (num 5) */
326 if (nto_xfer_memory (initial_stack, (unsigned char *)auxv,
327 sizeof (auxv_t), 0) == sizeof (auxv_t))
329 if (auxv->a_type != AT_NULL)
332 len_read += sizeof (auxv_t);
334 if (auxv->a_type == AT_PHNUM) /* That's all we need. */
336 initial_stack += sizeof (auxv_t);
341 TRACE ("auxv: len_read: %d\n", len_read);
345 /* Start inferior specified by PROGRAM passing arguments ALLARGS. */
348 nto_create_inferior (char *program, char **allargs)
350 struct inheritance inherit;
354 TRACE ("%s %s\n", __func__, program);
355 /* Clear any pending SIGUSR1's but keep the behavior the same. */
356 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
359 sigaddset (&set, SIGUSR1);
360 sigprocmask (SIG_UNBLOCK, &set, NULL);
362 memset (&inherit, 0, sizeof (inherit));
363 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
364 inherit.pgroup = SPAWN_NEWPGROUP;
365 pid = spawnp (program, 0, NULL, &inherit, allargs, 0);
366 sigprocmask (SIG_BLOCK, &set, NULL);
371 if (do_attach (pid) != pid)
377 /* Attach to process PID. */
380 nto_attach (unsigned long pid)
382 TRACE ("%s %ld\n", __func__, pid);
383 if (do_attach (pid) != pid)
384 error ("Unable to attach to %ld\n", pid);
388 /* Send signal to process PID. */
393 TRACE ("%s %d\n", __func__, pid);
399 /* Detach from process PID. */
404 TRACE ("%s %d\n", __func__, pid);
409 /* Check if the given thread is alive.
411 Return 1 if alive, 0 otherwise. */
414 nto_thread_alive (ptid_t ptid)
418 TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid),
419 ptid_get_lwp (ptid));
420 if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid),
425 TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
429 /* Resume inferior's execution. */
432 nto_resume (struct thread_resume *resume_info, size_t n)
434 /* We can only work in all-stop mode. */
435 procfs_status status;
439 TRACE ("%s\n", __func__);
440 /* Workaround for aliasing rules violation. */
441 sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
443 nto_set_thread (resume_info->thread);
445 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
446 if (resume_info->kind == resume_step)
447 run.flags |= _DEBUG_RUN_STEP;
448 run.flags |= _DEBUG_RUN_ARM;
450 sigemptyset (run_fault);
451 sigaddset (run_fault, FLTBPT);
452 sigaddset (run_fault, FLTTRACE);
453 sigaddset (run_fault, FLTILL);
454 sigaddset (run_fault, FLTPRIV);
455 sigaddset (run_fault, FLTBOUNDS);
456 sigaddset (run_fault, FLTIOVF);
457 sigaddset (run_fault, FLTIZDIV);
458 sigaddset (run_fault, FLTFPE);
459 sigaddset (run_fault, FLTPAGE);
460 sigaddset (run_fault, FLTSTACK);
461 sigaddset (run_fault, FLTACCESS);
463 sigemptyset (&run.trace);
464 if (resume_info->sig)
468 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
470 signal_to_pass = resume_info->sig;
471 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
473 if (signal_to_pass != status.info.si_signo)
475 kill (status.pid, signal_to_pass);
476 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
478 else /* Let it kill the program without telling us. */
479 sigdelset (&run.trace, signal_to_pass);
483 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
485 sigfillset (&run.trace);
487 regcache_invalidate ();
489 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
491 TRACE ("Error: %d \"%s\"\n", err, strerror (err));
494 /* Wait for inferior's event.
496 Return ptid of thread that caused the event. */
499 nto_wait (ptid_t ptid,
500 struct target_waitstatus *ourstatus, int target_options)
504 procfs_status status;
505 const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
506 | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
508 TRACE ("%s\n", __func__);
510 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
513 sigaddset (&set, SIGUSR1);
515 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
516 while (!(status.flags & _DEBUG_FLAG_ISTOP))
518 sigwaitinfo (&set, &info);
519 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
522 nto_find_new_threads (&nto_inferior);
524 if (status.flags & _DEBUG_FLAG_SSTEP)
527 ourstatus->kind = TARGET_WAITKIND_STOPPED;
528 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
530 /* Was it a breakpoint? */
531 else if (status.flags & trace_mask)
534 ourstatus->kind = TARGET_WAITKIND_STOPPED;
535 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
537 else if (status.flags & _DEBUG_FLAG_ISTOP)
542 case _DEBUG_WHY_SIGNALLED:
543 TRACE (" SIGNALLED\n");
544 ourstatus->kind = TARGET_WAITKIND_STOPPED;
545 ourstatus->value.sig =
546 target_signal_from_host (status.info.si_signo);
547 nto_inferior.exit_signo = ourstatus->value.sig;
549 case _DEBUG_WHY_FAULTED:
550 TRACE (" FAULTED\n");
551 ourstatus->kind = TARGET_WAITKIND_STOPPED;
552 if (status.info.si_signo == SIGTRAP)
554 ourstatus->value.sig = 0;
555 nto_inferior.exit_signo = 0;
559 ourstatus->value.sig =
560 target_signal_from_host (status.info.si_signo);
561 nto_inferior.exit_signo = ourstatus->value.sig;
565 case _DEBUG_WHY_TERMINATED:
569 TRACE (" TERMINATED\n");
570 waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
571 if (nto_inferior.exit_signo)
573 /* Abnormal death. */
574 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
575 ourstatus->value.sig = nto_inferior.exit_signo;
580 ourstatus->kind = TARGET_WAITKIND_EXITED;
581 ourstatus->value.integer = WEXITSTATUS (waitval);
583 nto_inferior.exit_signo = 0;
587 case _DEBUG_WHY_REQUESTED:
588 TRACE ("REQUESTED\n");
589 /* We are assuming a requested stop is due to a SIGINT. */
590 ourstatus->kind = TARGET_WAITKIND_STOPPED;
591 ourstatus->value.sig = TARGET_SIGNAL_INT;
592 nto_inferior.exit_signo = 0;
597 return ptid_build (status.pid, status.tid, 0);
600 /* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
601 If REGNO is -1, fetch all registers, or REGNO register only otherwise. */
604 nto_fetch_registers (int regno)
610 TRACE ("%s (regno=%d)\n", __func__, regno);
611 if (regno >= the_low_target.num_regs)
614 if (current_inferior == NULL)
616 TRACE ("current_inferior is NULL\n");
619 ptid = thread_to_gdb_id (current_inferior);
620 if (!nto_set_thread (ptid))
623 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
626 if (regno == -1) /* All registers. */
628 for (regno = 0; regno != the_low_target.num_regs; ++regno)
630 const unsigned int registeroffset
631 = the_low_target.register_offset (regno);
632 supply_register (regno, ((char *)&greg) + registeroffset);
637 const unsigned int registeroffset
638 = the_low_target.register_offset (regno);
639 if (registeroffset == -1)
641 supply_register (regno, ((char *)&greg) + registeroffset);
645 TRACE ("ERROR reading registers from inferior.\n");
648 /* Store registers for currently selected thread (CURRENT_INFERIOR).
649 We always store all registers, regardless of REGNO. */
652 nto_store_registers (int regno)
658 TRACE ("%s (regno:%d)\n", __func__, regno);
660 if (current_inferior == NULL)
662 TRACE ("current_inferior is NULL\n");
665 ptid = thread_to_gdb_id (current_inferior);
666 if (!nto_set_thread (ptid))
669 memset (&greg, 0, sizeof (greg));
670 for (regno = 0; regno != the_low_target.num_regs; ++regno)
672 const unsigned int regoffset
673 = the_low_target.register_offset (regno);
674 collect_register (regno, ((char *)&greg) + regoffset);
676 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
679 TRACE ("Error: setting registers.\n");
682 /* Read LEN bytes from inferior's memory address MEMADDR into
683 gdbserver's MYADDR buffer.
685 Return 0 on success -1 otherwise. */
688 nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
690 TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
692 if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
694 TRACE ("Failed to read memory\n");
701 /* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
702 memory at address MEMADDR.
704 Return 0 on success -1 otherwise. */
707 nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
711 TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
712 if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
716 TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
723 /* Stop inferior. We always stop all threads. */
726 nto_request_interrupt (void)
728 TRACE ("%s\n", __func__);
729 nto_set_thread (ptid_build (nto_inferior.pid, 1, 0));
730 if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
731 TRACE ("Error stopping inferior.\n");
734 /* Read auxiliary vector from inferior's memory into gdbserver's buffer
735 MYADDR. We always read whole auxv.
737 Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
741 nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
744 CORE_ADDR initial_stack;
745 procfs_info procinfo;
747 TRACE ("%s\n", __func__);
751 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
756 initial_stack = procinfo.initial_stack;
758 return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
761 /* Insert {break/watch}point at address ADDR.
762 TYPE must be in '0'..'4' range. LEN is not used. */
765 nto_insert_point (char type, CORE_ADDR addr, int len)
767 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
769 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
772 case '0': /* software-breakpoint */
773 wtype = _DEBUG_BREAK_EXEC;
775 case '1': /* hardware-breakpoint */
776 wtype |= _DEBUG_BREAK_EXEC;
778 case '2': /* write watchpoint */
779 wtype |= _DEBUG_BREAK_RW;
781 case '3': /* read watchpoint */
782 wtype |= _DEBUG_BREAK_RD;
784 case '4': /* access watchpoint */
785 wtype |= _DEBUG_BREAK_RW;
788 return 1; /* Not supported. */
790 return nto_breakpoint (addr, wtype, 0);
793 /* Remove {break/watch}point at address ADDR.
794 TYPE must be in '0'..'4' range. LEN is not used. */
797 nto_remove_point (char type, CORE_ADDR addr, int len)
799 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
801 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
804 case '0': /* software-breakpoint */
805 wtype = _DEBUG_BREAK_EXEC;
807 case '1': /* hardware-breakpoint */
808 wtype |= _DEBUG_BREAK_EXEC;
810 case '2': /* write watchpoint */
811 wtype |= _DEBUG_BREAK_RW;
813 case '3': /* read watchpoint */
814 wtype |= _DEBUG_BREAK_RD;
816 case '4': /* access watchpoint */
817 wtype |= _DEBUG_BREAK_RW;
820 return 1; /* Not supported. */
822 return nto_breakpoint (addr, wtype, -1);
825 /* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
828 Return 1 if stopped by watchpoint, 0 otherwise. */
831 nto_stopped_by_watchpoint (void)
835 TRACE ("%s\n", __func__);
836 if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
840 ptid = thread_to_gdb_id (current_inferior);
841 if (nto_set_thread (ptid))
843 const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
844 | _DEBUG_FLAG_TRACE_MODIFY;
845 procfs_status status;
848 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
850 if (err == EOK && (status.flags & watchmask))
854 TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
858 /* Get instruction pointer for CURRENT_INFERIOR thread.
860 Return inferior's instruction pointer value, or 0 on error. */
863 nto_stopped_data_address (void)
865 CORE_ADDR ret = (CORE_ADDR)0;
867 TRACE ("%s\n", __func__);
868 if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
872 ptid = thread_to_gdb_id (current_inferior);
874 if (nto_set_thread (ptid))
876 procfs_status status;
878 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
879 sizeof (status), 0) == EOK)
883 TRACE ("%s: 0x%08lx\n", __func__, ret);
887 /* We do not currently support non-stop. */
890 nto_supports_non_stop (void)
892 TRACE ("%s\n", __func__);
898 static struct target_ops nto_target_ops = {
911 NULL, /* nto_look_up_symbols */
912 nto_request_interrupt,
916 nto_stopped_by_watchpoint,
917 nto_stopped_data_address,
918 NULL, /* nto_read_offsets */
919 NULL, /* thread_db_set_tls_address */
921 hostio_last_error_from_errno,
922 NULL, /* nto_qxfer_osdata */
923 NULL, /* xfer_siginfo */
924 nto_supports_non_stop,
926 NULL /* start_non_stop */
930 /* Global function called by server.c. Initializes QNX Neutrino
934 initialize_low (void)
938 TRACE ("%s\n", __func__);
939 set_target_ops (&nto_target_ops);
940 set_breakpoint_data (the_low_target.breakpoint,
941 the_low_target.breakpoint_len);
943 /* We use SIGUSR1 to gain control after we block waiting for a process.
944 We use sigwaitevent to wait. */
946 sigaddset (&set, SIGUSR1);
947 sigprocmask (SIG_BLOCK, &set, NULL);