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

📄 generic-stub.c

📁 ecos为实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
     char *mem;     int count;     int may_fault;{  hexMemSrc      = (unsigned char *) buf;  hexMemDst      = (unsigned char *) mem;  hexMemCount    = count;  may_fault_mode = may_fault;  if (may_fault)    {      if (__set_mem_fault_trap (__hex2mem_helper))        return 0;    }  else    __hex2mem_helper ();  return (char *) hexMemDst;}voidset_debug_traps (void){  __install_traps ();  initialized = 1;    /* FIXME: Change this to dbg_stub_initialized */}/* * While we find nice hex chars, build an int. * Return number of chars processed. */unsigned int__hexToInt (char **ptr, target_register_t *intValue){  int numChars = 0;  int hexValue;  *intValue = 0;  while (**ptr)    {      hexValue = stubhex (**ptr);      if (hexValue < 0)        break;      *intValue = (*intValue << 4) | hexValue;      numChars ++;      (*ptr)++;    }  return (numChars);}/*  * Complement of __hexToInt: take an int of size "numBits",  * convert it to a hex string.  Return length of (unterminated) output. */unsigned int__intToHex (char *ptr, target_register_t intValue, int numBits){  int numChars = 0;  if (intValue == 0)    {      *(ptr++) = '0';      *(ptr++) = '0';      return 2;    }  numBits = (numBits + 7) / 8;  while (numBits)    {      int v = (intValue >> ((numBits - 1) * 8));      if (v || (numBits == 1))        {          v = v & 255;          *(ptr++) = __tohex ((v / 16) & 15);          *(ptr++) = __tohex (v & 15);          numChars += 2;        }      numBits--;    }  return (numChars);}#if DEBUG_THREADS /* * Kernel Thread Control * * If the current thread is set to other than zero (or minus one), * then ask the kernel to lock it's scheduler so that only that thread * can run. */static unsigned char did_lock_scheduler = 0;static unsigned char did_disable_interrupts = 0;/* Pointer to "kernel call" for scheduler control */static int (*schedlock_fn) (int, int, long) = stub_lock_scheduler;/* Pointer to target stub call for disabling interrupts.   Target stub will initialize this if it can.  */int (*__disable_interrupts_hook) (int); /* don't initialize here! */#endifstatic voidlock_thread_scheduler (int kind)        /* "step" or "continue" */{#if DEBUG_THREADS   int ret = 0;  /* GDB will signal its desire to run a single thread     by setting _gdb_cont_thread to non-zero / non-negative.  */  if (_gdb_cont_thread <= 0)    return;  if (schedlock_fn)                     /* kernel call */    ret = (*schedlock_fn) (1, kind, _gdb_cont_thread);  if (ret == 1)    {      did_lock_scheduler = 1;      return;    }  if (schedlock_fn == 0 ||              /* no kernel scheduler call */      ret == -1)                        /* kernel asks stub to handle it */    if (__disable_interrupts_hook)      /* target stub has capability */      if ((*__disable_interrupts_hook) (1))        {          did_disable_interrupts = 1;          return;        }#endif /* DEBUG_THREADS */}static voidunlock_thread_scheduler (){#if DEBUG_THREADS  if (did_lock_scheduler)    if (schedlock_fn)                   /* kernel call */      {        (*schedlock_fn) (0, 0, _gdb_cont_thread);        /* I could check the return value, but            what would I do if it failed???  */        did_lock_scheduler = 0;      }  if (did_disable_interrupts)    if (__disable_interrupts_hook)      /* target stub call */      {        (*__disable_interrupts_hook) (0);        /* Again, I could check the return value, but            what would I do if it failed???  */        did_disable_interrupts = 0;      }#endif /* DEBUG_THREADS */}void__handle_exception (void){  int sigval;#ifdef TARGET_HAS_NEXT_STEP  if (! __next_step_done ())    {      __clear_breakpoints ();      __install_breakpoints ();      __single_step ();      return;    }#endif#ifdef __ECOS__  // We need to unpack the registers before they are accessed.  if (__cleanup_vec != NULL)    __cleanup_vec ();#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT  // Special case for GDB BREAKs. This flag is set by cyg_stub_cleanup.  if (cyg_hal_gdb_break) {      cyg_hal_gdb_break = 0;      sigval = SIGINT;  } else#endif      sigval = __computeSignal (__get_trap_number ());#else  // __ECOS__  /* reply to host that an exception has occurred */  sigval = __computeSignal (__get_trap_number ());#endif // __ECOS__  if (__is_breakpoint_function ())    __skipinst ();#ifndef __ECOS__  if (__cleanup_vec != NULL)    __cleanup_vec ();#endif // !__ECOS__  __clear_breakpoints ();   /* Undo effect of previous single step.  */  unlock_thread_scheduler ();  __clear_single_step ();#ifdef SIGSYSCALL  if (sigval == SIGSYSCALL)    {      int val;      /* Do the skipinst FIRST. */#ifndef SYSCALL_PC_AFTER_INST      __skipinst ();#endif      val =  __process_syscall_vec (__get_syscall_num ());      if (val < 0)        sigval = -val;      else        sigval = 0;    }#endif  /* Indirect function call to stub, cygmon monitor or other */  if (sigval != 0)    {      while (__process_exception_vec (sigval))        {          /* Empty! */        }    }  __install_breakpoints ();  if (__init_vec != NULL)    __init_vec ();}/* * _get_trace_register_hook: * This function pointer will be non-zero if the trace component * wants to intercept requests for register values. *  * FIXME: evidently I need a new hook for large registers... */int   (*_get_trace_register_hook) (regnames_t, target_register_t *);int__process_packet (char *packet){  int  is_binary = 0;  remcomOutBuffer[0] = 0;  switch (packet[0])    {    case '?':      {        int sigval = __computeSignal (__get_trap_number ());        remcomOutBuffer[0] = 'S';        remcomOutBuffer[1] = hexchars[(sigval >> 4) & 0xf];        remcomOutBuffer[2] = hexchars[sigval & 0xf];        remcomOutBuffer[3] = 0;        break;      }    case 'd':      /* toggle debug flag */      break;    case 'q':      /* general query packet */      process_query (&packet[1]);      break;    case 'Q':      /* general set packet */      process_set (&packet[1]);      break;    case 'g':           /* return the value of the CPU registers */      {        char *ptr = remcomOutBuffer;        int regnum;        for (regnum = 0; regnum < NUMREGS_GDB; regnum++)          {            /* We need to compensate for the value offset within the               register. */            char dummyDat[32];            target_register_t addr;            char *vptr;            int  reg_valid = 1;#ifdef TARGET_HAS_LARGE_REGISTERS            if (sizeof (target_register_t) < REGSIZE (regnum))              {                get_register_as_bytes (regnum, dummyDat);                vptr = dummyDat;              }            else#endif              {                if (_get_trace_register_hook)                  reg_valid = _get_trace_register_hook (regnum, &addr);                else                  addr = get_register (regnum);                vptr = ((char *) &addr) + sizeof (addr) - REGSIZE (regnum);                if (sizeof (addr) < REGSIZE (regnum))                  {                    int off = REGSIZE (regnum) - sizeof (addr);                    int x;                    for (x = 0; x < off; x++)                      dummyDat[x] = 0;                    memcpy (dummyDat + off, &addr, sizeof (addr));                    vptr = dummyDat;                  }              }            if (reg_valid)      /* we have a valid reg value */              {                ptr = __mem2hex (vptr, ptr, REGSIZE (regnum), 0);              }            else              {                /* Trace component returned a failure code.                   This means that the register value is not available.                   We'll fill it with 'x's, and GDB will understand.  */                memset (ptr, 'x', 2 * REGSIZE (regnum));                ptr += 2 * REGSIZE (regnum);              }          }        break;      }    case 'A': /* set program arguments */      {        if (packet[1] == '\0')          {            __free_program_args ();            strcpy (remcomOutBuffer, "OK");          }        else           {            target_register_t arglen, argnum;            char *ptr = &packet[1];            while (1)              {                if (__hexToInt (&ptr, &arglen)                    && (*ptr++ == ',')                    && __hexToInt (&ptr, &argnum)                    && (*ptr++ == ','))                  {                    if (arglen > 0)                      {                        char *s = __add_program_arg (argnum, arglen);                        if (s != NULL)                          {                            __hex2mem (ptr, s, arglen, 0);                          }                        ptr += arglen * 2;                      }                    if (*ptr == ',')                      ptr++;                    else                      break;                  }                else                  break;              }            if (*ptr == '\0')              strcpy (remcomOutBuffer, "OK");            else              strcpy (remcomOutBuffer, "E01");          }      }      break;    case 'P':    case 'G':      /* set the value of the CPU registers - return OK */      {        int x;        int sr = 0, er = NUMREGS_GDB;        char *ptr = &packet[1];        if (packet[0] == 'P')          {            target_register_t regno;            if (__hexToInt (&ptr, &regno)                && (*ptr++ == '='))              {                sr = regno;                er = regno + 1;              }            else              {                strcpy (remcomOutBuffer, "P01");                break;              }          }        for (x = sr; x < er; x++)          {            target_register_t value = 0;            char *vptr;#ifdef TARGET_HAS_LARGE_REGISTERS            if (sizeof (target_register_t) < REGSIZE (x))              {                char dummyDat [32];                __hex2mem (ptr, dummyDat, REGSIZE (x), 0);                put_register_as_bytes (x, dummyDat);              }            else#endif              {                vptr = ((char *) &value) + sizeof (value) - REGSIZE (x);                __hex2mem (ptr, vptr, REGSIZE (x), 0);                put_register (x, value);              }            ptr += REGSIZE (x) * 2;          }        strcpy (remcomOutBuffer, "OK");        break;      }    case 'm':     /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */      /* Try to read %x,%x.  */      {        target_register_t addr, length;        char *ptr = &packet[1];        if (__hexToInt (&ptr, &addr)            && *ptr++ == ','            && __hexToInt (&ptr, &length))          {            if (__mem2hex ((char *) addr, remcomOutBuffer, length, 1))              break;            strcpy (remcomOutBuffer, "E03");          }        else          strcpy (remcomOutBuffer, "E01");        break;      }    case 'X':      /* XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA */      is_binary = 1;      /* fall through */    case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */      /* Try to read '%x,%x:'.  */      {        target_register_t addr, length;        char *ptr = &packet[1], buf[128];        int  i;        if (__hexToInt (&ptr, &addr)            && *ptr++ == ','            && __hexToInt (&ptr, &length)            && *ptr++ == ':')          {            if (is_binary)              {                while (length > 0)                  {                    for (i = 0; i < sizeof(buf) && i < length; i++)                      if ((buf[i] = *ptr++) == 0x7d)                        buf[i] = 0x20 | (*ptr++ & 0xff);                    if (__write_mem_safe (buf, addr, i) != i)                      break;                    length -= i;                    addr += i;                  }                if (length <= 0)                  strcpy (remcomOutBuffer, "OK");                else                  strcpy (remcomOutBuffer, "E03");              }              else              {                if (__hex2mem (ptr, (char *) addr, length, 1) != NULL)                  strcpy (remcomOutBuffer, "OK");                else                  strcpy (remcomOutBuffer, "E03");              }          }        else          strcpy (remcomOutBuffer, "E02");        break;      }    case 'S':    case 's':    /* sAA..AA    Step from address AA..AA (optional) */    case 'C':    case 'c':    /* cAA..AA    Continue at address AA..AA (optional) */      /* try to read optional parameter, pc unchanged if no parm */      {        char *ptr = &packet[1];        target_register_t addr;        target_register_t sigval = 0;        if (packet[0] == 'C' || packet[0] == 'S')          {            __hexToInt (&ptr, &sigval);            if (*ptr == ';')              ptr++;          }

⌨️ 快捷键说明

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