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

📄 gdb_stub.c

📁 微内核软实时操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
  unsigned char *buffer = &remcomInBuffer[0];  unsigned char checksum;  unsigned char xmitcsum;  int count;  char ch;  while (1)    {      /* wait around for the start character, ignore all other characters */      while ((ch = getDebugChar ()) != '$')	;    retry:      checksum = 0;      xmitcsum = -1;      count = 0;      /* now, read until a # or end of buffer is found */      while (count < BUFMAX)	{	  ch = getDebugChar ();	  if (ch == '$')	    goto retry;	  if (ch == '#')	    break;	  checksum = checksum + ch;	  buffer[count] = ch;	  count = count + 1;	}      buffer[count] = 0;      if (ch == '#')	{	  ch = getDebugChar ();	  xmitcsum = hex (ch) << 4;	  ch = getDebugChar ();	  xmitcsum += hex (ch);	  if (checksum != xmitcsum)	    {	      if (remote_debug)		{		  fprintf (stderr,			   "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",			   checksum, xmitcsum, buffer);		}	      putDebugChar ('-');	/* failed checksum */	    }	  else	    {	      putDebugChar ('+');	/* successful transfer */	      /* if a sequence char is present, reply the sequence ID */	      if (buffer[2] == ':')		{		  putDebugChar (buffer[0]);		  putDebugChar (buffer[1]);		  return &buffer[3];		}	      return &buffer[0];	    }	}    }}/* send the packet in buffer.  */voidputpacket (unsigned char *buffer){  unsigned char checksum;  int count;  char ch;  /*  $<packet info>#<checksum>. */  do    {      putDebugChar ('$');      checksum = 0;      count = 0;      while ((ch = buffer[count]) != 0)	{	  putDebugChar (ch);	  checksum += ch;	  count += 1;	}      putDebugChar ('#');      putDebugChar (hexchars[checksum >> 4]);      putDebugChar (hexchars[checksum % 16]);    }  while (getDebugChar () != '+');}voiddebug_error (format, parm)     char *format;     char *parm;{  if (remote_debug)    fprintf (stderr, format, parm);}/* Address of a routine to RTE to if we get a memory fault.  */static void (*volatile mem_fault_routine) () = NULL;/* Indicate to caller of mem2hex or hex2mem that there has been an   error.  */static volatile int mem_err = 0;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).  */intget_char (char *addr){  return *addr;}voidset_char (char *addr, int val){  *addr = val;}/* convert the memory pointed to by mem into hex, placing result in buf *//* return a pointer to the last char put in buf (null) *//* If MAY_FAULT is non-zero, then we should set mem_err in response to   a fault; if zero treat a fault like any other fault in the stub.  */char *mem2hex (mem, buf, count, may_fault)     char *mem;     char *buf;     int count;     int may_fault;{  int i;  unsigned char ch;  if (may_fault)    mem_fault_routine = set_mem_err;  for (i = 0; i < count; i++)    {      ch = get_char (mem++);      if (may_fault && mem_err)	return (buf);      *buf++ = hexchars[ch >> 4];      *buf++ = hexchars[ch % 16];    }  *buf = 0;  if (may_fault)    mem_fault_routine = NULL;  return (buf);}/* convert the hex array pointed to by buf into binary to be placed in mem *//* return a pointer to the character AFTER the last byte written */char *hex2mem (buf, mem, count, may_fault)     char *buf;     char *mem;     int count;     int may_fault;{  int i;  unsigned char ch;  if (may_fault)    mem_fault_routine = set_mem_err;  for (i = 0; i < count; i++)    {      ch = hex (*buf++) << 4;      ch = ch + hex (*buf++);      set_char (mem++, ch);      if (may_fault && mem_err)	return (mem);    }  if (may_fault)    mem_fault_routine = NULL;  return (mem);}/* this function takes the 386 exception vector and attempts to   translate this number into a unix compatible signal value */intcomputeSignal (int exceptionVector){  int sigval;  switch (exceptionVector)    {    case 0:      sigval = 8;      break;			/* divide by zero */    case 1:      sigval = 5;      break;			/* debug exception */    case 3:      sigval = 5;      break;			/* breakpoint */    case 4:      sigval = 16;      break;			/* into instruction (overflow) */    case 5:      sigval = 16;      break;			/* bound instruction */    case 6:      sigval = 4;      break;			/* Invalid opcode */    case 7:      sigval = 8;      break;			/* coprocessor not available */    case 8:      sigval = 7;      break;			/* double fault */    case 9:      sigval = 11;      break;			/* coprocessor segment overrun */    case 10:      sigval = 11;      break;			/* Invalid TSS */    case 11:      sigval = 11;      break;			/* Segment not present */    case 12:      sigval = 11;      break;			/* stack exception */    case 13:      sigval = 11;      break;			/* general protection */    case 14:      sigval = 11;      break;			/* page fault */    case 16:      sigval = 7;      break;			/* coprocessor error */    default:      sigval = 7;		/* "software generated" */    }  return (sigval);}/**********************************************//* WHILE WE FIND NICE HEX CHARS, BUILD AN INT *//* RETURN NUMBER OF CHARS PROCESSED           *//**********************************************/inthexToInt (char **ptr, int *intValue){  int numChars = 0;  int hexValue;  *intValue = 0;  while (**ptr)    {      hexValue = hex (**ptr);      if (hexValue >= 0)	{	  *intValue = (*intValue << 4) | hexValue;	  numChars++;	}      else	break;      (*ptr)++;    }  return (numChars);}/* * This function does all command procesing for interfacing to gdb. */voidhandle_exception (int exceptionVector){  int sigval, stepping;  int addr, length;  char *ptr;  int newPC;  gdb_i386vector = exceptionVector;  if (remote_debug)    {      printf ("vector=%d, sr=0x%x, pc=0x%x\n",	      exceptionVector, registers[PS], registers[PC]);    }  /* reply to host that an exception has occurred */  sigval = computeSignal (exceptionVector);  ptr = remcomOutBuffer;  *ptr++ = 'T';			/* notify gdb with signo, PC, FP and SP */  *ptr++ = hexchars[sigval >> 4];  *ptr++ = hexchars[sigval & 0xf];  *ptr++ = hexchars[ESP];   *ptr++ = ':';  ptr = mem2hex((char *)&registers[ESP], ptr, 4, 0);	/* SP */  *ptr++ = ';';  *ptr++ = hexchars[EBP];   *ptr++ = ':';  ptr = mem2hex((char *)&registers[EBP], ptr, 4, 0); 	/* FP */  *ptr++ = ';';  *ptr++ = hexchars[PC];   *ptr++ = ':';  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0); 	/* PC */  *ptr++ = ';';  *ptr = '\0';  putpacket (remcomOutBuffer);  stepping = 0;  while (1 == 1)    {      remcomOutBuffer[0] = 0;      ptr = getpacket ();      switch (*ptr++)	{	case '?':	  remcomOutBuffer[0] = 'S';	  remcomOutBuffer[1] = hexchars[sigval >> 4];	  remcomOutBuffer[2] = hexchars[sigval % 16];	  remcomOutBuffer[3] = 0;	  break;	case 'd':	  remote_debug = !(remote_debug);	/* toggle debug flag */	  break;	case 'g':		/* return the value of the CPU registers */	  mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);	  break;	case 'G':		/* set the value of the CPU registers - return OK */	  hex2mem (ptr, (char *) registers, NUMREGBYTES, 0);	  strcpy (remcomOutBuffer, "OK");	  break;	case 'P':		/* set the value of a single CPU register - return OK */	  {	    int regno;	    if (hexToInt (&ptr, &regno) && *ptr++ == '=')	      if (regno >= 0 && regno < NUMREGS)		{		  hex2mem (ptr, (char *) &registers[regno], 4, 0);		  strcpy (remcomOutBuffer, "OK");		  break;		}	    strcpy (remcomOutBuffer, "E01");	    break;	  }	  /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */	case 'm':	  /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */	  if (hexToInt (&ptr, &addr))	    if (*(ptr++) == ',')	      if (hexToInt (&ptr, &length))		{		  ptr = 0;		  mem_err = 0;		  mem2hex ((char *) addr, remcomOutBuffer, length, 1);		  if (mem_err)		    {		      strcpy (remcomOutBuffer, "E03");		      debug_error ("memory fault");		    }		}	  if (ptr)	    {	      strcpy (remcomOutBuffer, "E01");	    }	  break;	  /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */	case 'M':	  /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */	  if (hexToInt (&ptr, &addr))	    if (*(ptr++) == ',')	      if (hexToInt (&ptr, &length))		if (*(ptr++) == ':')		  {		    mem_err = 0;		    hex2mem (ptr, (char *) addr, length, 1);		    if (mem_err)		      {			strcpy (remcomOutBuffer, "E03");			debug_error ("memory fault");		      }		    else		      {			strcpy (remcomOutBuffer, "OK");		      }		    ptr = 0;		  }	  if (ptr)	    {	      strcpy (remcomOutBuffer, "E02");	    }	  break;	  /* cAA..AA    Continue at address AA..AA(optional) */	  /* sAA..AA   Step one instruction from AA..AA(optional) */	case 's':	  stepping = 1;	case 'c':	  /* try to read optional parameter, pc unchanged if no parm */	  if (hexToInt (&ptr, &addr))	    registers[PC] = addr;	  newPC = registers[PC];	  /* clear the trace bit */	  registers[PS] &= 0xfffffeff;	  /* set the trace bit if we're stepping */	  if (stepping)	    registers[PS] |= 0x100;	  _returnFromException ();	/* this is a jump */	  break;	  /* kill the program */	case 'k':		/* do nothing */#if 0	  /* Huh? This doesn't look like "nothing".	     m68k-stub.c and sparc-stub.c don't have it.  */	  BREAKPOINT ();#endif	  break;	}			/* switch */      /* reply to the request */      putpacket (remcomOutBuffer);    }}/* this function is used to set up exception handlers for tracing and   breakpoints */voidset_debug_traps (void){  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];  exceptionHandler (0, _catchException0);  exceptionHandler (1, _catchException1);  exceptionHandler (3, _catchException3);  exceptionHandler (4, _catchException4);  exceptionHandler (5, _catchException5);  exceptionHandler (6, _catchException6);  exceptionHandler (7, _catchException7);  exceptionHandler (8, _catchException8);  exceptionHandler (9, _catchException9);  exceptionHandler (10, _catchException10);  exceptionHandler (11, _catchException11);  exceptionHandler (12, _catchException12);  exceptionHandler (13, _catchException13);  exceptionHandler (14, _catchException14);  exceptionHandler (16, _catchException16);  initialized = 1;}/* This function will generate a breakpoint exception.  It is used at the   beginning of a program to sync up with a debugger and can be used   otherwise as a quick means to stop program execution and "break" into   the debugger. *//*voidbreakpoint (void){  if (initialized)    BREAKPOINT ();}*/void gdb_init(void){	if (serial_init())		return;	set_debug_traps();	printk("Waiting to connect remote gdb...\n");	BREAKPOINT();}#endif	/* CONFIG_GDB */

⌨️ 快捷键说明

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