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

📄 rtems-stub-glue.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
    case 'L':      /* Thread list query */      if (!do_threads) {        break;      }      {        int ret, athread, first, max_cnt, i, done, rthread;        ret = parse_ql(inbuffer, &first, &max_cnt, &athread);        if (!ret) {          strcpy(outbuffer, "E02");          break;        }        if (max_cnt == 0) {          strcpy(outbuffer, "E02");          break;        }        if (max_cnt > QM_MAX_THREADS) {          /* Limit max count by buffer size */          max_cnt = QM_MAX_THREADS;        }        /* Reserve place for output header */        optr = reserve_qm_header(outbuffer);        if (first) {          rthread = 0;        } else {          rthread = athread;        }        done = 0;        for (i=0; i<max_cnt; i++) {          rthread = rtems_gdb_stub_get_next_thread(rthread);          if (rthread <= 0) {            done = 1; /* Set done flag */            break;          }          optr = pack_qm_thread(optr, rthread);        }        *optr = 0;        ASSERT((optr - outbuffer) < BUFMAX);        /* Fill header */        pack_qm_header(outbuffer, i, done, athread);      }      break;    default:      if (memcmp(inbuffer, "qOffsets", 8) == 0) {        unsigned char *t, *d, *b;        char *out;        if (!rtems_gdb_stub_get_offsets(&t, &d, &b)) {          break;        }        out = outbuffer;        *out++ = 'T';        *out++ = 'e';        *out++ = 'x';        *out++ = 't';        *out++ = '=';        out = int2vhstr(out, (int)t);        *out++ = ';';        *out++ = 'D';        *out++ = 'a';        *out++ = 't';        *out++ = 'a';        *out++ = '=';        out = int2vhstr(out, (int)d);        *out++ = ';';        *out++ = 'B';        *out++ = 's';        *out++ = 's';        *out++ = '=';        out = int2vhstr(out, (int)b);        *out++ = ';';        *out++ = 0;        break;      }      /*  qCRC, qRcmd, qu and qz will be added here */      break;    }}/* Present thread in the variable length string format */char*thread2vhstr(char *buf, int thread){  int i, nibble, shift;  ASSERT(buf != NULL);  for(i=0, shift=28; i<8; i++, shift-=4)    {      nibble = (thread >> shift) & 0x0f;            if (nibble != 0)	{	  break;	}    }  if (i == 8)    {      *buf++ = '0';      return buf;    }  *buf++ = gdb_hexchars[nibble];  for(i++, shift-=4; i<8; i++, shift-=4, buf++)    {      nibble = (thread >> shift) & 0x0f;      *buf   = gdb_hexchars[nibble];    }  return buf;}/* Present thread in fixed length string format */char*thread2fhstr(char *buf, int thread){  int i, nibble, shift;  ASSERT(buf != NULL);  for(i=0; i<8; i++, buf++)    {      *buf = '0';    }  for(i=0, shift=28; i<8; i++, shift-=4, buf++)    {      nibble = (thread >> shift) & 0x0f;      *buf   = gdb_hexchars[nibble];    }  return buf;}/* Parse thread presented in fixed length format */const char*fhstr2thread(const char *buf, int *thread){  int i, val, nibble;  ASSERT(buf != NULL);  ASSERT(thread != NULL);  for(i=0; i<8; i++, buf++)    {      if (*buf != '0')	{	  return NULL;	}    }  val = 0;  for(i=0; i<8; i++, buf++)    {      if (!hstr2nibble(buf, &nibble))	{	  return NULL;	}      ASSERT(nibble >=0 && nibble < 16);      val = (val << 4) | nibble;    }  *thread = val;  return buf;}/* Parse thread presented in variable length format */const char*vhstr2thread(const char *buf, int *thread){  int i, val, nibble;  int found_zero, lim;  ASSERT(buf != NULL);  ASSERT(thread != NULL);  /* If we have leading zeros, skip them */  found_zero = 0;  for(i=0; i<16; i++, buf++)    {      if (*buf != '0')	{	  break;	}      found_zero = 1;    }  /* Process non-zeros */  lim = 16 - i;  val = 0;  for(i=0; i<lim; i++, buf++)    {      if (!hstr2nibble(buf, &nibble))	{	  if (i == 0 && !found_zero)	    {	      /* Empty value */	      return NULL;	    }	  *thread = val;	  return buf;	}	        ASSERT(nibble >= 0 && nibble < 16);      val = (val << 4) | nibble;    }  if (hstr2nibble(buf, &nibble))    {      /* Value is too long */      return NULL;    }    *thread = val;  return buf;}/* Present integer in the variable length string format */char*int2vhstr(char *buf, int val){  int i, nibble, shift;  ASSERT(buf != NULL);  for(i=0, shift=28; i<8; i++, shift-=4)    {      nibble = (val >> shift) & 0x0f;            if (nibble != 0)	{	  break;	}    }  if (i == 8)    {      *buf++ = '0';      return buf;    }  *buf++ = gdb_hexchars[nibble];  for(i++, shift-=4; i<8; i++, shift-=4, buf++)    {      nibble = (val >> shift) & 0x0f;      *buf   = gdb_hexchars[nibble];    }  return buf;}/* Present int in fixed length string format */char*int2fhstr(char *buf, int val){  int i, nibble, shift;  ASSERT(buf != NULL);  for(i=0, shift=28; i<8; i++, shift-=4, buf++)    {      nibble = (val >> shift) & 0x0f;      *buf   = gdb_hexchars[nibble];    }  return buf;}/* Parse int presented in fixed length format */const char*fhstr2int(const char *buf, int *ival){  int i, val, nibble;  ASSERT(buf != NULL);  ASSERT(ival != NULL);  val = 0;  for(i=0; i<8; i++, buf++)    {      if (!hstr2nibble(buf, &nibble))	{	  return NULL;	}      ASSERT(nibble >=0 && nibble < 16);      val = (val << 4) | nibble;    }  *ival = val;  return buf;}/* Parse int presented in variable length format */const char*vhstr2int(const char *buf, int *ival){  int i, val, nibble;  int found_zero, lim;  ASSERT(buf != NULL);  ASSERT(ival != NULL);  /* If we have leading zeros, skip them */  found_zero = 0;  for(i=0; i<8; i++, buf++)    {      if (*buf != '0')	{	  break;	}      found_zero = 1;    }  /* Process non-zeros */  lim = 8 - i;  val = 0;  for(i=0; i<lim; i++, buf++)    {      if (!hstr2nibble(buf, &nibble))	{	  if (i == 0 && !found_zero)	    {	      /* Empty value */	      return NULL;	    }	  *ival = val;	  return buf;	}	        ASSERT(nibble >= 0 && nibble < 16);      val = (val << 4) | nibble;    }  if (hstr2nibble(buf, &nibble))    {      /* Value is too long */      return NULL;    }  *ival = val;  return buf;}inthstr2byte(const char *buf, int *bval){  int hnib, lnib;  ASSERT(buf != NULL);  ASSERT(bval != NULL);  if (!hstr2nibble(buf, &hnib) || !hstr2nibble(buf+1, &lnib))    {      return 0;    }  *bval = (hnib << 4) | lnib;  return 1;}int hstr2nibble(const char *buf, int *nibble){  int ch;  ASSERT(buf != NULL);  ASSERT(nibble != NULL);  ch = *buf;  if (ch >= '0' && ch <= '9')    {      *nibble = ch  - '0';      return 1;    }  if (ch >= 'a' && ch <= 'f')    {      *nibble = ch - 'a' + 10;      return 1;    }  if (ch >= 'A' && ch <= 'F')    {      *nibble = ch - 'A' + 10;      return 1;    }  return 0;}static volatile char mem_err = 0;void  set_mem_err(void);static void (*volatile mem_fault_routine) (void) = NULL;/* convert count bytes of the memory pointed to by mem into hex string,    placing result in buf, return pointer to next location in hex strng   in case of success or NULL otherwise */char*mem2hstr(char *buf, const unsigned char *mem, int count){  int i;  unsigned char ch;  mem_err = 0;  mem_fault_routine = set_mem_err;   for (i = 0; i<count; i++, mem++)    {      ch = get_byte (mem);      if (mem_err)	{	  mem_fault_routine = NULL;	  return NULL;	}           *buf++ = gdb_hexchars[ch >> 4];      *buf++ = gdb_hexchars[ch & 0x0f];    }    *buf = 0;  mem_fault_routine = NULL;  return buf;}/* convert the hex string to into count bytes of binary to be placed in mem   return 1 in case of success and  0 otherwise */inthstr2mem (unsigned char *mem, const char *buf, int count){  int i;  int bval;  mem_err = 0;  mem_fault_routine = set_mem_err;  for (i = 0; i < count; i++, mem++, buf+=2)    {      if (!hstr2byte(buf, &bval))	{	  mem_fault_routine = NULL;	  return 0;	}	        ASSERT(bval >=0 && bval < 256);      set_byte (mem, bval);      if (mem_err)	{	  mem_fault_routine = NULL;	  return 0;	}    }  mem_fault_routine = NULL;  return 1;}voidset_mem_err (void){  mem_err = 1;}/* These are separate functions so that they are so short and sweet   that the compiler won't save any registers (if there is a fault   to mem_fault, they won't get restored, so there better not be any   saved).  */unsigned char get_byte (const unsigned char *addr){  return *addr;}voidset_byte (unsigned char *addr, int val){  *addr = val;}/* *  From here down, the code is CPU model specific and generally maps *  the RTEMS thread context format to gdb's. */#if defined(__i386__)#include "i386-stub.h"/* Packing order of registers */enum i386_stub_regnames {  I386_STUB_REG_EAX, I386_STUB_REG_ECX, I386_STUB_REG_EDX, I386_STUB_REG_EBX,  I386_STUB_REG_ESP, I386_STUB_REG_EBP, I386_STUB_REG_ESI, I386_STUB_REG_EDI,  I386_STUB_REG_PC /* also known as eip */ ,  I386_STUB_REG_PS /* also known as eflags */ ,  I386_STUB_REG_CS, I386_STUB_REG_SS, I386_STUB_REG_DS, I386_STUB_REG_ES,  I386_STUB_REG_FS, I386_STUB_REG_GS};void rtems_gdb_stub_get_registers_from_context(   int            *registers,  Thread_Control *th){  registers[I386_STUB_REG_EAX] = 0;  registers[I386_STUB_REG_ECX] = 0;  registers[I386_STUB_REG_EDX] = 0;  registers[I386_STUB_REG_EBX] = (int)th->Registers.ebx;  registers[I386_STUB_REG_ESP] = (int)th->Registers.esp;  registers[I386_STUB_REG_EBP] = (int)th->Registers.ebp;  registers[I386_STUB_REG_ESI] = (int)th->Registers.esi;  registers[I386_STUB_REG_EDI] = (int)th->Registers.edi;  registers[I386_STUB_REG_PC]  = *(int *)th->Registers.esp;  registers[I386_STUB_REG_PS]  = (int)th->Registers.eflags;  /* RTEMS never changes base registers (especially once      threads are running) */  registers[I386_STUB_REG_CS]  = 0x8; /* We just know these values */  registers[I386_STUB_REG_SS]  = 0x10;  registers[I386_STUB_REG_DS]  = 0x10;  registers[I386_STUB_REG_ES]  = 0x10;  registers[I386_STUB_REG_FS]  = 0x10;  registers[I386_STUB_REG_GS]  = 0x10;}int rtems_gdb_stub_get_offsets(  unsigned char **text_addr,  unsigned char **data_addr,   unsigned char **bss_addr){  extern unsigned char _text_start;  extern unsigned char _data_start;  extern unsigned char _bss_start;  *text_addr = &_text_start;  *data_addr = &_data_start;  *bss_addr  = &_bss_start;  return 1;}#elif defined(__mips__)void rtems_gdb_stub_get_registers_from_context(   int            *registers,  Thread_Control *th){   registers[S0] = (unsigned)th->Registers.s0;   registers[S1] = (unsigned)th->Registers.s1;   registers[S2] = (unsigned)th->Registers.s2;   registers[S3] = (unsigned)th->Registers.s3;   registers[S4] = (unsigned)th->Registers.s4;   registers[S5] = (unsigned)th->Registers.s5;   registers[S6] = (unsigned)th->Registers.s6;   registers[S7] = (unsigned)th->Registers.s7;   registers[SP] = (unsigned)th->Registers.sp;   registers[RA] = (unsigned)th->Registers.ra;   registers[SR] = (unsigned)th->Registers.c0_sr;   registers[PC] = (unsigned)th->Registers.c0_epc;}int rtems_gdb_stub_get_offsets(  unsigned char **text_addr,  unsigned char **data_addr,   unsigned char **bss_addr){ /*  extern unsigned32 _ftext;  extern unsigned32 _fdata;  extern unsigned32 _bss_start;  *text_addr = &_ftext;  *data_addr = &_fdata;  *bss_addr  = &_bss_start;*/  *text_addr = 0;  *data_addr = 0;  *bss_addr  = 0;  return 1;}#elif defined(__mc68000__)void rtems_gdb_stub_get_registers_from_context(   int            *registers,  Thread_Control *th){  /*   * how about register D0/D1/A0/A1   * they are located on thread stack ...   * -> they are not needed for context switch   */  registers[D0] = 0;   registers[D1] = 0;  registers[D2] = (unsigned32)th->Registers.d2;  registers[D3] = (unsigned32)th->Registers.d3;  registers[D4] = (unsigned32)th->Registers.d4;  registers[D5] = (unsigned32)th->Registers.d5;  registers[D6] = (unsigned32)th->Registers.d6;  registers[D7] = (unsigned32)th->Registers.d7;  registers[A0] = 0;  registers[A1] = 0;  registers[A2] = (unsigned32)th->Registers.a2;  registers[A3] = (unsigned32)th->Registers.a3;  registers[A4] = (unsigned32)th->Registers.a4;  registers[A5] = (unsigned32)th->Registers.a5;  registers[A6] = (unsigned32)th->Registers.a6;  registers[A7] = (unsigned32)th->Registers.a7_msp;    registers[PS] = (unsigned32)th->Registers.sr;#if 0  registers[PC] = *(unsigned32 *)th->Registers.a7_msp; /* *SP = ret adr */#else  registers[PC] = (unsigned32)_CPU_Context_switch;#endif}int rtems_gdb_stub_get_offsets(  unsigned char **text_addr,  unsigned char **data_addr,   unsigned char **bss_addr){ /*  extern unsigned32 _ftext;  extern unsigned32 _fdata;  extern unsigned32 _bss_start;  *text_addr = &_ftext;  *data_addr = &_fdata;  *bss_addr  = &_bss_start;*/  *text_addr = 0;  *data_addr = 0;  *bss_addr  = 0;  return 1;}#else#error "rtems-gdb-stub.c: Unsupported CPU!"#endif

⌨️ 快捷键说明

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