⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servrpc.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
      out.addr.ptrace_addr_data_out_u.mem.dataNb = 0;    else {      int maxLen = sizeof(out.addr.ptrace_addr_data_out_u.mem.data) - 1;      data = strlen (plst->name);      if (data > maxLen)        data = maxLen;      out.addr.ptrace_addr_data_out_u.mem.dataNb = data + 1;      memcpy (out.addr.ptrace_addr_data_out_u.mem.data, plst->name, data + 1);      out.addr.ptrace_addr_data_out_u.mem.data[maxLen] = '\0';    }    req = 0;    break;  case RPT_CONTTO:    if (BreakSetAt (plst, conn_idx, (u_long) addr, BRKT_STEPEMUL) < 0) {      DPRINTF (("ptrace_2_svc: BreakSet failed at %x", addr));      break;    }    req = RPT_CONT;    /*     * data can contain a signal number, addr2 is unused      */    goto case_RPT_CONT;  case RPT_STEPRANGE:    /*     * convert to step      */    if (!data)      data = 1;                 /* should we give an error?? */    BreakStepRange (plst, addr, data);    if (getErrno ())      break;    req = RPT_SINGLESTEP;       /* do by stepping */    addr = (void *) 1;          /* start from current PC */    data = -2;                  /* want non-atomic stepping */    /*     * fall through to other exec cases      */  case RPT_CONT:  case_RPT_CONT:  case RPT_SINGLESTEP:    if (BreakStepOff (plst, &addr2)) {  /* need clear then step off break */      /*       * clear break, step, then do exec        */      if (addr == (void *) 1)        addr = (void *) plst->regs.REG_PC;  /* need for patch */      /*       * data is always 0, so atomic single-step        */    } else if (req == RPT_SINGLESTEP) {      data = -2;                /* want non-atomic stepping */    }    break;    /*     * now ones where addr points to an output area      */  case RPT_PGETTHREADREGS:    addr = (void *) out.addr.ptrace_addr_data_out_u.mem.data;    if (sizeof(out.addr.ptrace_addr_data_out_u.mem.data) < REG_COUNT * sizeof (int)) {      setErrno (EINVAL);      break;    }    if (data == plst->thread) {      out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;      out.addr.ptrace_addr_data_out_u.pregs.pregs_val =        (u_int *) & plst->regs;      req = 0;                  /* force exit */      break;    }    req = RPT_GETTHREADREGS;    break;  case RPT_GETTHREADREGS:    addr = (void *) &out.addr.ptrace_addr_data_out_u.regs;    break;  case RPT_GETTHREADNAME:    out.addr.ptrace_addr_data_out_u.name = local_buff.t_name;    addr = (void *) out.addr.ptrace_addr_data_out_u.name;    break;  case RPT_THREADLIST:    out.addr.ptrace_addr_data_out_u.threads.threads =      (ptThreadList) local_buff.t_list;    addr = (void *) out.addr.ptrace_addr_data_out_u.threads.threads;    break;  case RPT_READTEXT:  case RPT_READDATA:    if ((int) data < 0) {      setErrno (EINVAL);      break;    }    addr = (void *) in->addr.ptrace_addr_data_in_u.address;    addr2 = (void *) out.addr.ptrace_addr_data_out_u.mem.data;    out.addr.ptrace_addr_data_out_u.mem.dataNb = data;    break;  case RPT_DETACH:    /*     * Do not allow detaching if breakpoints still there      */    if (BreakGet (plst, 0, NULL)) { /* some bkpts still set */      setErrno (EINVAL);        /* cannot detach safely */      break;    }    /*     * fall through      */  case RPT_KILL:    /*     * in the event they are trying to detach or kill a terminated process,     * we just delete the entry.                       */    if (PROC_TERMINATED (plst)) {      TgtDelete (plst, -1, BMSG_KILLED);    /* just blow off */      req = 0;                  /* now exit */    }    break;  }  if (getErrno ()) {            /* failed in code above */    out.result = -1;    out.errNo = getErrno ();    DPRINTF (("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));    return (&out);  } else if (!req) {            /* bail out now */    DPRINTF (("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));    return (&out);  }  /*   * OK, make the call    */  out.result = TgtPtrace (req, pid, addr, data, addr2);  out.errNo = getErrno ();  /*   * if no error, cleanup afterwards    */  if (getErrno ()) {    /*     * Remove step-emul breakpoints if any      */    if (req == RPT_SINGLESTEP || req == RPT_CONT) {      BreakClear (plst, -1, -1);    }    DPRINTF (("ptrace_2_svc: result %d errNo %d\n", out.result, out.errNo));    return (&out);              /* return error */  }  switch (in->addr.req) {       /* handle some special calls that affect state */  case RPT_CONT:  case RPT_STEPRANGE:    /*     * change to running      */    if (in->addr.req == RPT_STEPRANGE)      plst->last_start = LAST_RANGE;    /* so range steps */    else if (addr2)      plst->last_start = LAST_STEPOFF;  /* now continue after wait */    else      plst->last_start = LAST_CONT;    plst->running = 1;          /* mark as running */    if (!rqstp)                 /* Called internally to restart bkpt, no msg to anybody */      break;    TgtNotifyAll (pid_idx, BMSG_WAIT, 0, 0, (in->flags & PTRFLG_NON_OWNER)                  ? -1 : conn_idx, True);    break;  case RPT_SINGLESTEP:    /*     * mark as step      */    plst->last_start = LAST_STEP;   /* so we know how started */    plst->running = 1;          /* mark as running (wait should catch fast) */    break;  case RPT_DETACH:             /* mark as disconnected */  case RPT_KILL:               /* mark as killed */    if (in->flags & PTRFLG_FREE)    /* notify and delete entry */      TgtDelete (plst, -1,                 (in->addr.req == RPT_KILL) ? BMSG_KILLED : BMSG_DETACH);    else {                      /* notify and mark */      plst->last_start = (in->addr.req == RPT_KILL) ?        LAST_KILLED : LAST_DETACHED;      plst->state = -1;      plst->running = False;      TgtNotifyAll (pid_idx, (in->addr.req == RPT_KILL) ?                    BMSG_KILLED : BMSG_DETACH, 0, 0, -1, True);    }    break;  case RPT_SETTHREADREGS:  case RPT_PSETTHREADREGS:    if (data != plst->thread)      break;    DPRINTF (("ptrace_2_svc: pid %d target thread regs changed!\n", pid));  case RPT_SETREGS:  case RPT_PSETREGS:    /*     * change our buffer as well      */    if (plst->regs.REG_PC != ((xdr_regs *) addr)->REG_PC)      BreakPcChanged (plst);    plst->regs = *(xdr_regs *) addr;    /* copy in */    break;    /*     * case RPT_PGETREGS has been handled locally above      */  case RPT_PGETTHREADREGS:    /*     * We need to update pointer so that XDR works on return      */    out.addr.ptrace_addr_data_out_u.pregs.pregs_len = REG_COUNT;    out.addr.ptrace_addr_data_out_u.pregs.pregs_val =      (void *) out.addr.ptrace_addr_data_out_u.mem.data;    break;  case RPT_PEEKTEXT:  case RPT_PEEKDATA:  case RPT_READDATA:  case RPT_READTEXT:    if (req < RPT_READDATA) {   /* peek */      /*       * addr is start        */      data = sizeof (int);      addr2 = &out.result;      /* data buffer */      /*       * Like read: addr is start, data is length, addr2 is buffer        */    }    BreakHide (plst, addr, data, addr2);    break;  case RPT_SETTARGETTHREAD:    DPRINTF (("ptrace_2_svc: pid %d new target thread %d\n", pid, data));    TgtPtrace (RPT_GETREGS, pid, (char *) &plst->regs, 0, NULL);    plst->thread = data;    if (plst->break_list) {     /* Forget we had to step off breakpoint */      BASE_BREAK *base = (BASE_BREAK *) plst->break_list;      DPRINTF (("ptrace_2_svc: clr_step %d last_break %d\n", base->clr_step,                base->last_break));      base->clr_step = 0;       /* Not stopped on break */      base->last_break = 0;    }    break;  case RPT_THREADLIST:    out.addr.ptrace_addr_data_out_u.threads.nbThread = out.result;    break;  default:    break;  }                             /* end switch */  DPRINTF (("ptrace_2_svc 2: result %d errNo %d\n", out.result, out.errNo));  return (&out);}/* -----------------------------------------------------------------------   wait_info_2_svc - non-blocking wait request to check status.   ----------------------------------------------------------------------- */  wait_out *RPCGENSRVNAME (wait_info_2_svc) (wait_in * in, struct svc_req *rqstp){  int conn_idx = TspConnGetIndex (rqstp);  static wait_out out;          /* output of pid and status */  int idx;  PID_LIST *plst;  memset (&out, 0, sizeof (out));   /* zero for safety */  out.reason = STOP_ERROR;      /* assume the worst */  if (conn_idx == -1) {         /* no connection, error */    DPRINTF (("wait_info_2_svc: msg from unknown debugger!\n"));    out.wait_return = -1;    out.errNo = ECHILD;         /* closest error */    return (&out);  } else {                      /* see if confirming message received */    if (conn_list[conn_idx].retry)      TspMessageReceive (conn_idx, in->pid);  }  if (!in->pid) {               /* warm test verify only */    /*     * this call (pid==0) is made to confirm that that connection is still     * active.           */    /*     * we let it fall through as an error since any use other than connection     * reset would be an error (there is no pid0).               */  } else {                      /* normal request */    idx = FindPidEntry (in->pid);    if (idx >= 0) {             /* found process they requested on */      plst = &pid_list[idx];      out.wait_return = plst->running ? 0 : in->pid;      /*       * return: 0 is running, pid is stopped/term        */      out.errNo = 0;      out.status = plst->state; /* last stopped reason if stopped */      out.thread = plst->thread;    /* current thread (or -1 if none) from stop */      if (!out.wait_return)        out.reason = STOP_NONE; /* running, no action */      else if (STS_SIGNALLED (out.status)) {    /* stopped on signal */        out.handle = STS_GETSIG (out.status);   /* signal number */        if (out.handle == SIGTRAP)          if (plst->is_step) {  /* single step with hitting a break */            out.reason = STOP_STEP;            out.handle = 0;     /* no information */          } else {              /* stopped on break */            out.reason = STOP_BREAK;            if (plst->break_list)              out.handle = ((BASE_BREAK *) plst->break_list)->last_break;            else              out.handle = 0;   /* no break */        } else          out.reason = STOP_SIGNAL;        out.PC = plst->regs.REG_PC; /* copy standard regs */        out.SP = plst->regs.REG_SP;        out.FP = plst->regs.REG_FP;      } else {                  /* terminated, so lower use count */        if (plst->last_start == LAST_KILLED)          out.reason = STOP_KILLED;        else if (plst->last_start == LAST_DETACHED)          out.reason = STOP_DETACHED;        else if (plst->last_start == LAST_START) {  /* failed in exec */          out.reason = STOP_SPAWN_FAILED;          out.handle = STS_GETCODE (out.status);    /* errno reason */        } else if (STS_TERMONSIG (out.status)) {    /* terminated on signal */          out.reason = STOP_TERM_SIG;          /*           * mask off the core-dumped bit 7            */          out.handle = (int) (unsigned) (u_char) STS_TERMGETSIG (out.status);        } else {                /* exit(2)ed */          out.reason = STOP_TERM_EXIT;          out.handle = STS_GETCODE (out.status);    /* code */        }      }      DPRINTF (("wait_info_2_svc: pid %d return %d status %x errNo %d"                " reason %d handle %d pc %x sp %x fp %x thread %d\n",                in->pid, out.wait_return, out.status, out.errNo, out.reason,                out.handle, out.PC, out.SP, out.FP, out.thread));      return (&out);    }  }  /*   * if not found in list, we return error: no such process    */  out.wait_return = -1;  out.errNo = ESRCH;            /* no process */  out.status = 0;  return (&out);}/* -----------------------------------------------------------------------   get_signal_names_2_svc - return names for signals   ----------------------------------------------------------------------- */static one_signal SignalNames[] = {  {SIGILL, "SIGILL/EVT_ILL"},  {SIGTRAP, "SIGTRAP/EVT_BKPT"},  {SIGFPE, "SIGFPE/EVT_FPE"},  {SIGKILL, "SIGKILL/EVT_AKILL"},  {SIGSEGV, "SIGSEGV/EVT_SEGV"},  {17, "SIGSTOP"},  {23, "SIGSTOP"}};  get_signal_names_out *RPCGENSRVNAME (get_signal_names_2_svc) (void * in, struct svc_req * rqstp){  static get_signal_names_out out;  out.signals.all_signals_len = sizeof (SignalNames) / sizeof (SignalNames[0]);  out.signals.all_signals_val = SignalNames;  return (&out);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -