static int nto_stopped_by_watchpoint (void) { int ret = 0; TRACE ("%s\n", __func__); if (nto_inferior.ctl_fd != -1 && current_inferior != NULL) { ptid_t ptid; ptid = thread_to_gdb_id (current_inferior); if (nto_set_thread (ptid)) { const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY; procfs_status status; int err; err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); if (err == EOK && (status.flags & watchmask)) ret = 1; } } TRACE ("%s: %s\n", __func__, ret ? "yes" : "no"); return ret; }
static void nto_store_registers (struct regcache *regcache, int regno) { procfs_greg greg; int err; ptid_t ptid; TRACE ("%s (regno:%d)\n", __func__, regno); if (current_inferior == NULL) { TRACE ("current_inferior is NULL\n"); return; } ptid = thread_to_gdb_id (current_inferior); if (!nto_set_thread (ptid)) return; memset (&greg, 0, sizeof (greg)); for (regno = 0; regno != the_low_target.num_regs; ++regno) { const unsigned int regoffset = the_low_target.register_offset (regno); collect_register (regcache, regno, ((char *)&greg) + regoffset); } err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg), 0); if (err != EOK) TRACE ("Error: setting registers.\n"); }
static void nto_request_interrupt (void) { TRACE ("%s\n", __func__); nto_set_thread (ptid_build (nto_inferior.pid, 1, 0)); if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0)) TRACE ("Error stopping inferior.\n"); }
static void nto_fetch_registers (struct regcache *regcache, int regno) { int regsize; procfs_greg greg; ptid_t ptid; TRACE ("%s (regno=%d)\n", __func__, regno); if (regno >= the_low_target.num_regs) return; if (current_inferior == NULL) { TRACE ("current_inferior is NULL\n"); return; } ptid = thread_to_gdb_id (current_inferior); if (!nto_set_thread (ptid)) return; if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg), ®size) == EOK) { if (regno == -1) /* All registers. */ { for (regno = 0; regno != the_low_target.num_regs; ++regno) { const unsigned int registeroffset = the_low_target.register_offset (regno); supply_register (regcache, regno, ((char *)&greg) + registeroffset); } } else { const unsigned int registeroffset = the_low_target.register_offset (regno); if (registeroffset == -1) return; supply_register (regcache, regno, ((char *)&greg) + registeroffset); } } else TRACE ("ERROR reading registers from inferior.\n"); }
static CORE_ADDR nto_stopped_data_address (void) { CORE_ADDR ret = (CORE_ADDR)0; TRACE ("%s\n", __func__); if (nto_inferior.ctl_fd != -1 && current_inferior != NULL) { ptid_t ptid; ptid = thread_to_gdb_id (current_inferior); if (nto_set_thread (ptid)) { procfs_status status; if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK) ret = status.ip; } } TRACE ("%s: 0x%08lx\n", __func__, ret); return ret; }
static void nto_resume (struct thread_resume *resume_info, size_t n) { /* We can only work in all-stop mode. */ procfs_status status; procfs_run run; int err; TRACE ("%s\n", __func__); /* Workaround for aliasing rules violation. */ sigset_t *run_fault = (sigset_t *) (void *) &run.fault; nto_set_thread (resume_info->thread); run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; if (resume_info->kind == resume_step) run.flags |= _DEBUG_RUN_STEP; run.flags |= _DEBUG_RUN_ARM; sigemptyset (run_fault); sigaddset (run_fault, FLTBPT); sigaddset (run_fault, FLTTRACE); sigaddset (run_fault, FLTILL); sigaddset (run_fault, FLTPRIV); sigaddset (run_fault, FLTBOUNDS); sigaddset (run_fault, FLTIOVF); sigaddset (run_fault, FLTIZDIV); sigaddset (run_fault, FLTFPE); sigaddset (run_fault, FLTPAGE); sigaddset (run_fault, FLTSTACK); sigaddset (run_fault, FLTACCESS); sigemptyset (&run.trace); if (resume_info->sig) { int signal_to_pass; devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); signal_to_pass = resume_info->sig; if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) { if (signal_to_pass != status.info.si_signo) { kill (status.pid, signal_to_pass); run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; } else /* Let it kill the program without telling us. */ sigdelset (&run.trace, signal_to_pass); } } else run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; sigfillset (&run.trace); regcache_invalidate (); err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); if (err != EOK) TRACE ("Error: %d \"%s\"\n", err, strerror (err)); }