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

📄 generic-stub.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	     strcpy (ptr, "INVALID");	     return;	   }      }    for (regnum = sr; regnum < er; 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);#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING                reg_valid = get_register_valid (regnum);#endif            }            vptr = ((char *) &addr);            if (sizeof (addr) > REGSIZE(regnum)) {                /* May need to cope with endian-ness */#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN)                vptr += sizeof (addr) - REGSIZE (regnum);#endif            } else if (sizeof (addr) < REGSIZE (regnum)) {                int off = REGSIZE (regnum) - sizeof (addr);                int x;                char extend_val = 0;#ifdef CYGARC_SIGN_EXTEND_REGISTERS                {                    unsigned long bits_in_addr = (sizeof(addr) << 3);  // ie Size in bytes * 8                    target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));                    if ((addr & sign_bit_mask) == sign_bit_mask)                        extend_val = ~0;                }#endif#if defined(__LITTLE_ENDIAN__) || defined(_LITTLE_ENDIAN)                for (x = 0; x < off; x++)                    dummyDat[x + sizeof(addr)] = extend_val;                _memcpy (dummyDat, &addr, sizeof (addr));#else                for (x = 0; x < off; x++)                    dummyDat[x] = extend_val;                _memcpy (dummyDat + off, &addr, sizeof (addr));#endif                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);        }    }}voidstub_update_registers(char *in_ptr, char *out_ptr){    char *ptr = &in_ptr[1];    int x;    int sr = 0, er = NUMREGS_GDB;    if (*in_ptr == 'P') {        target_register_t regno;        if (__hexToInt (&ptr, &regno) && (*ptr++ == '=')) {            sr = regno;            er = regno + 1;        } else {            strcpy (out_ptr, "P01");            return;        }    }    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);#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN)            vptr += sizeof (value) - REGSIZE (x);#endif            __hex2mem (ptr, vptr, REGSIZE (x), 0);            put_register (x, value);        }        ptr += REGSIZE (x) * 2;    }    strcpy (out_ptr, "OK");}int__process_packet (char *packet){  int  is_binary = 0;#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE)  int is_Z = 0;#endif  __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;      }#ifdef __ECOS__#if !defined(CYG_HAL_STARTUP_RAM)    // Only for ROM based stubs#if 0 // Disable to avoid conflict with stub-breakpoint z/Z-packets    case 'z':        /* report IO buffer sizes so download can achieve optimal           download speed */    {        int i;        i = __intToHex (__remcomOutBuffer, BUFMAX, 32);        __remcomOutBuffer[i] = 0;        break;    }#endif    case 'd':      /* toggle debug flag */      strcpy(__remcomOutBuffer, GDB_stubs_version);      break;#endif#endif // __ECOS__    case 'q':      /* general query packet */      process_query (&packet[1]);      break;    case 'Q':      /* general set packet */      process_set (&packet[1]);      break;    case 'p':		/* return the value of  a single CPU register */    case 'g':           /* return the value of the CPU registers */      {        stub_format_registers(&packet[0], __remcomOutBuffer);        break;      }    case 'A': /* set program arguments */      {#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS        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");          }#else        strcpy (__remcomOutBuffer, "E01");#endif      }      break;    case 'P':    case 'G':      /* set the value of the CPU registers - return OK */      {        char *in_ptr = &packet[0];        char *out_ptr = __remcomOutBuffer;        stub_update_registers(in_ptr, out_ptr);        break;      }    case 'm':     /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */      /* Try to read %x,%x.  */      {        target_register_t length;        char *ptr = &packet[1];        target_addr_t addr;        if (__hexToAddr (&ptr, &addr)            && *ptr++ == ','            && __hexToInt (&ptr, &length))          {	    if (__mem2hex_safe (addr, __remcomOutBuffer, length))              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 length;        char *ptr = &packet[1], buf[128];        int  i;        target_addr_t addr;        if (__hexToAddr (&ptr, &addr)	    && *ptr++ == ','            && __hexToInt (&ptr, &length)            && *ptr++ == ':')          {            /* GDB sometimes sends an impossible length */            if (length < 0 || length >= BUFMAX)              strcpy (__remcomOutBuffer, "E01");                            else 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);#ifdef TARGET_HAS_HARVARD_MEMORY		    if (TARGET_ADDR_IS_PROGMEM(addr)) {		      if (__write_progmem_safe (buf, (void *)TARGET_ADDR_TO_PTR(addr), i) != i)                        break;		    } else#endif		      if (__write_mem_safe (buf, (void *)TARGET_ADDR_TO_PTR(addr), i) != i)			break;                    length -= i;                    addr += i;                  }                if (length <= 0)                  strcpy (__remcomOutBuffer, "OK");                else                  strcpy (__remcomOutBuffer, "E03");              }            else              {                if (__hex2mem_safe (ptr, addr, length) != 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_addr_t addr;        target_register_t sigval = 0;        if (packet[0] == 'C' || packet[0] == 'S')          {            __hexToInt (&ptr, &sigval);            if (*ptr == ';')              ptr++;          }        if (__hexToAddr (&ptr, &addr))          set_pc ((target_register_t)TARGET_ADDR_TO_PTR(addr));      /* Need to flush the instruction cache here, as we may have         deposited a breakpoint, and the icache probably has no way of         knowing that a data ref to some location may have changed         something that is in the instruction cache.  */#ifdef __ECOS__        __data_cache (CACHE_FLUSH) ;#endif        __instruction_cache (CACHE_FLUSH) ;        /* If we have a function to handle signals, call it. */        if (sigval != 0 && __process_signal_vec != NULL)          {            /* If 0 is returned, we either ignored the signal or invoked a user               handler. Otherwise, the user program should die. */            if (! __process_signal_vec (sigval))              sigval = 0;          }        if (sigval != 0)          {            sigval = SIGKILL; /* Always nuke the program */            __kill_program (sigval);            return 0;          }#ifdef __ECOS__        // CASE 102327 - watchpoints fight with output, so do not step        // through $O packet output routines.#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT        if ( cyg_hal_gdb_break_is_set() ) {            packet[0] = 'c'; // Force it to be a "continue" instead of step.            cyg_hal_gdb_running_step = 1; // And tell the hal_stub...        }#endif#endif        /* Set machine state to force a single step.  */        if (packet[0] == 's' || packet[0] == 'S')          {            lock_thread_scheduler (0);  /* 0 == single-step */#ifdef __ECOS__            // PR 19845 workaround:            // Make sure the single-step magic affects the correct registers.            _registers = &registers[0];#endif            __single_step ();          }        else          {            lock_thread_scheduler (1);  /* 1 == continue */          }#ifdef __ECOS__      /* Need to flush the data and instruction cache here, as we may have         deposited a breakpoint in __single_step. */        __data_cache (CACHE_FLUSH) ;        __instruction_cache (CACHE_FLUSH) ;	hal_flush_output();#endif        return -1;      }    case 'D' :     /* detach */      __putpacket (__remcomOutBuffer);      /* fall through */    case 'k' :      /* kill the program */#ifdef __ECOS__      hal_flush_output();#endif      __process_exit_vec ();      return -1;    case 'r':           /* Reset */      /* With the next 'k' packet, reset the board */      __process_exit_vec = &__reset;      break;    case 'H':      STUB_PKT_CHANGETHREAD (packet+1, __remcomOutBuffer, 300) ;      break ;    case 'T' :      STUB_PKT_THREAD_ALIVE (packet+1, __remcomOutBuffer, 300) ;      break ;    case 'B':      /* breakpoint */      {        target_register_t addr;        char mode;        char *ptr = &packet[1];        if (__hexToInt (&ptr, &addr) && *(ptr++) == ',')          {            mode = *(ptr++);            if (mode == 'C')              __remove_breakpoint (addr,0);            else              __set_breakpoint (addr,0);            strcpy (__remcomOutBuffer, "OK");          }        else          {            strcpy (__remcomOutBuffer, "E01");          }        break;      }      case 'b':   /* bBB...  Set baud rate to BB... */      {        target_register_t baudrate;        char *ptr = &packet[1];        if (!__hexToInt (&ptr, &baudrate))          {            strcpy (__remcomOutBuffer, "B01");            break;          }        __putpacket ("OK");     /* Ack before changing speed */        __set_baud_rate (baudrate);        break;      }#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)    case 'Z':      is_Z = 1;    case 'z':      {	char *ptr = &packet[1];	target_register_t ztype, addr, length;	int err;	target_addr_t taddr;	if (__hexToInt (&ptr, &ztype) && *(ptr++) == ',')	  {	    if (__hexToAddr (&ptr, &taddr))	      {		if (*(ptr++) == ',')		  {		      /* When there is a comma, there must be a length */		      if  (!__hexToInt (&ptr, &length))			{			  strcpy (__remcomOutBuffer, "E02");			  break;			}		  }		else		  length = 0;		addr = (target_register_t)TARGET_ADDR_TO_PTR(taddr);		switch (ztype)		  {		    case ZTYPE_SW_BREAKPOINT:		      /* sw breakpoint */		      if (is_Z)			err = __set_breakpoint(addr,length);		      else			err = __remove_breakpoint(addr,length);		      if (!err)			strcpy (__remcomOutBuffer, "OK");		      else			strcpy (__remcomOutBuffer, "E02");		      break;		    case ZTYPE_HW_BREAKPOINT:#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)		      if (is_Z)			err = __set_hw_breakpoint(addr, length);		      else			err = __remove_hw_breakpoint(addr, length);		      if (!err)			strcpy (__remcomOutBuffer, "OK");		      else#endif			strcpy (__remcomOutBuffer, "E02");

⌨️ 快捷键说明

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