コード例 #1
0
ファイル: nto-low.c プロジェクト: Drakey83/steamlink-sdk
static pid_t
do_attach (pid_t pid)
{
  procfs_status status;
  struct sigevent event;

  if (nto_inferior.ctl_fd != -1)
    {
      close (nto_inferior.ctl_fd);
      init_nto_inferior (&nto_inferior);
    }
  xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid);
  nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR);
  if (nto_inferior.ctl_fd == -1)
    {
      TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path);
      init_nto_inferior (&nto_inferior);
      return -1;
    }
  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0)
      != EOK)
    {
      do_detach ();
      return -1;
    }
  nto_inferior.pid = pid;
  /* Define a sigevent for process stopped notification.  */
  event.sigev_notify = SIGEV_SIGNAL_THREAD;
  event.sigev_signo = SIGUSR1;
  event.sigev_code = 0;
  event.sigev_value.sival_ptr = NULL;
  event.sigev_priority = -1;
  devctl (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);

  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
	      0) == EOK
      && (status.flags & _DEBUG_FLAG_STOPPED))
    {
      ptid_t ptid;
      struct process_info *proc;

      kill (pid, SIGCONT);
      ptid = ptid_build (status.pid, status.tid, 0);
      the_low_target.arch_setup ();
      proc = add_process (status.pid, 1);
      proc->tdesc = nto_tdesc;
      TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
	     ptid_get_lwp (ptid));
      nto_find_new_threads (&nto_inferior);
    }
  else
    {
      do_detach ();
      return -1;
    }

  return pid;
}
コード例 #2
0
static ptid_t
nto_wait (ptid_t ptid,
	  struct target_waitstatus *ourstatus, int target_options)
{
  sigset_t set;
  siginfo_t info;
  procfs_status status;
  const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
			  | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);

  TRACE ("%s\n", __func__);

  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;

  sigemptyset (&set);
  sigaddset (&set, SIGUSR1);

  devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
  while (!(status.flags & _DEBUG_FLAG_ISTOP))
    {
      sigwaitinfo (&set, &info);
      devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
	      0);
    }
  nto_find_new_threads (&nto_inferior);

  if (status.flags & _DEBUG_FLAG_SSTEP)
    {
      TRACE ("SSTEP\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
    }
  /* Was it a breakpoint?  */
  else if (status.flags & trace_mask)
    {
      TRACE ("STOPPED\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
    }
  else if (status.flags & _DEBUG_FLAG_ISTOP)
    {
      TRACE ("ISTOP\n");
      switch (status.why)
	{
	case _DEBUG_WHY_SIGNALLED:
	  TRACE ("  SIGNALLED\n");
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  ourstatus->value.sig =
	    target_signal_from_host (status.info.si_signo);
	  nto_inferior.exit_signo = ourstatus->value.sig;
	  break;
	case _DEBUG_WHY_FAULTED:
	  TRACE ("  FAULTED\n");
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  if (status.info.si_signo == SIGTRAP)
	    {
	      ourstatus->value.sig = 0;
	      nto_inferior.exit_signo = 0;
	    }
	  else
	    {
	      ourstatus->value.sig =
		target_signal_from_host (status.info.si_signo);
	      nto_inferior.exit_signo = ourstatus->value.sig;
	    }
	  break;

	case _DEBUG_WHY_TERMINATED:
	  {
	    int waitval = 0;

	    TRACE ("  TERMINATED\n");
	    waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
	    if (nto_inferior.exit_signo)
	      {
		/* Abnormal death.  */
		ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
		ourstatus->value.sig = nto_inferior.exit_signo;
	      }
	    else
	      {
		/* Normal death.  */
		ourstatus->kind = TARGET_WAITKIND_EXITED;
		ourstatus->value.integer = WEXITSTATUS (waitval);
	      }
	    nto_inferior.exit_signo = 0;
	    break;
	  }

	case _DEBUG_WHY_REQUESTED:
	  TRACE ("REQUESTED\n");
	  /* We are assuming a requested stop is due to a SIGINT.  */
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  ourstatus->value.sig = TARGET_SIGNAL_INT;
	  nto_inferior.exit_signo = 0;
	  break;
	}
    }

  return ptid_build (status.pid, status.tid, 0);
}