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

📄 sparc-stub.c

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 */static char *hex2mem(buf, mem, count, may_fault)     unsigned char *buf;     unsigned char *mem;     int count;     int may_fault;{  int i;  unsigned char ch;  set_mem_fault_trap(may_fault);  for (i=0; i<count; i++)    {      ch = hex(*buf++) << 4;      ch |= hex(*buf++);      *mem++ = ch;      if (mem_err)	return 0;    }  set_mem_fault_trap(0);  return mem;}/* This table contains the mapping between SPARC hardware trap types, and   signals, which are primarily what GDB understands.  It also indicates   which hardware traps we need to commandeer when initializing the stub. */static struct hard_trap_info{  unsigned char tt;		/* Trap type code for SPARClite */  unsigned char signo;		/* Signal that we map this trap into */} hard_trap_info[] = {  {1, SIGSEGV},			/* instruction access error */  {2, SIGILL},			/* privileged instruction */  {3, SIGILL},			/* illegal instruction */  {4, SIGEMT},			/* fp disabled */  {36, SIGEMT},			/* cp disabled */  {7, SIGBUS},			/* mem address not aligned */  {9, SIGSEGV},			/* data access exception */  {10, SIGEMT},			/* tag overflow */  {128+1, SIGTRAP},		/* ta 1 - normal breakpoint instruction */  {0, 0}			/* Must be last */};/* Set up exception handlers for tracing and breakpoints */voidset_debug_traps(){  struct hard_trap_info *ht;  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)    exceptionHandler(ht->tt, trap_low);  /* In case GDB is started before us, ack any packets (presumably     "$?#xx") sitting there.  */  putDebugChar ('+');  initialized = 1;}asm ("! Trap handler for memory errors.  This just sets mem_err to be non-zero.  It! assumes that %l1 is non-zero.  This should be safe, as it is doubtful that! 0 would ever contain code that could mem fault.  This routine will skip! past the faulting instruction after setting mem_err.	.text	.align 4_fltr_set_mem_err:	sethi %hi(_mem_err), %l0	st %l1, [%l0 + %lo(_mem_err)]	jmpl %l2, %g0	rett %l2+4");static voidset_mem_fault_trap(enable)     int enable;{  extern void fltr_set_mem_err();  mem_err = 0;  if (enable)    exceptionHandler(9, fltr_set_mem_err);  else    exceptionHandler(9, trap_low);}/* Convert the SPARC hardware trap type code to a unix signal number. */static intcomputeSignal(tt)     int tt;{  struct hard_trap_info *ht;  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)    if (ht->tt == tt)      return ht->signo;  return SIGHUP;		/* default for things we don't know about */}/* * While we find nice hex chars, build an int. * Return number of chars processed. */static unsigned inthexToInt(char **ptr, int *intValue){  int numChars = 0;  int hexValue;  *intValue = 0;  while (**ptr)    {      hexValue = hex(**ptr);      if (hexValue < 0)	break;      *intValue = (*intValue << 4) | hexValue;      numChars ++;      (*ptr)++;    }  return (numChars);}/* * This function does all command procesing for interfacing to gdb.  It * returns 1 if you should skip the instruction at the trap address, 0 * otherwise. */extern void breakinst();static voidhandle_exception (registers)     unsigned long *registers;{  int tt;			/* Trap type */  int sigval;  unsigned int addr;  int length;  char *ptr;  unsigned long *sp;/* First, we must force all of the windows to be spilled out */  asm("	save %sp, -64, %sp	save %sp, -64, %sp	save %sp, -64, %sp	save %sp, -64, %sp	save %sp, -64, %sp	save %sp, -64, %sp	save %sp, -64, %sp	save %sp, -64, %sp	restore	restore	restore	restore	restore	restore	restore	restore");  if (registers[PC] == (unsigned long)breakinst)    {      registers[PC] = registers[NPC];      registers[NPC] += 4;    }  sp = (unsigned long *)registers[SP];  tt = (registers[TBR] >> 4) & 0xff;  /* reply to host that an exception has occurred */  sigval = computeSignal(tt);  ptr = remcomOutBuffer;  *ptr++ = 'T';  *ptr++ = hexchars[sigval >> 4];  *ptr++ = hexchars[sigval & 0xf];  *ptr++ = hexchars[PC >> 4];  *ptr++ = hexchars[PC & 0xf];  *ptr++ = ':';  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);  *ptr++ = ';';  *ptr++ = hexchars[FP >> 4];  *ptr++ = hexchars[FP & 0xf];  *ptr++ = ':';  ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */  *ptr++ = ';';  *ptr++ = hexchars[SP >> 4];  *ptr++ = hexchars[SP & 0xf];  *ptr++ = ':';  ptr = mem2hex((char *)&sp, ptr, 4, 0);  *ptr++ = ';';  *ptr++ = hexchars[NPC >> 4];  *ptr++ = hexchars[NPC & 0xf];  *ptr++ = ':';  ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);  *ptr++ = ';';  *ptr++ = hexchars[O7 >> 4];  *ptr++ = hexchars[O7 & 0xf];  *ptr++ = ':';  ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);  *ptr++ = ';';  *ptr++ = 0;  putpacket(remcomOutBuffer);  while (1)    {      remcomOutBuffer[0] = 0;      getpacket(remcomInBuffer);      switch (remcomInBuffer[0])	{	case '?':	  remcomOutBuffer[0] = 'S';	  remcomOutBuffer[1] = hexchars[sigval >> 4];	  remcomOutBuffer[2] = hexchars[sigval & 0xf];	  remcomOutBuffer[3] = 0;	  break;	case 'd':				/* toggle debug flag */	  break;	case 'g':		/* return the value of the CPU registers */	  {	    ptr = remcomOutBuffer;	    ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */	    ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */	    memset(ptr, '0', 32 * 8); /* Floating point */	    mem2hex((char *)&registers[Y],		    ptr + 32 * 4 * 2,		    8 * 4,		    0);		/* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */	  }	  break;	case 'G':	   /* set the value of the CPU registers - return OK */	  {	    unsigned long *newsp, psr;	    psr = registers[PSR];	    ptr = &remcomInBuffer[1];	    hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */	    hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */	    hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],		    8 * 4, 0);	/* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */	    /* See if the stack pointer has moved.  If so, then copy the saved	       locals and ins to the new location.  This keeps the window	       overflow and underflow routines happy.  */	    newsp = (unsigned long *)registers[SP];	    if (sp != newsp)	      sp = memcpy(newsp, sp, 16 * 4);	    /* Don't allow CWP to be modified. */	    if (psr != registers[PSR])	      registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);	    strcpy(remcomOutBuffer,"OK");	  }	  break;	case 'm':	  /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */	  /* Try to read %x,%x.  */	  ptr = &remcomInBuffer[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 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */	  /* Try to read '%x,%x:'.  */	  ptr = &remcomInBuffer[1];	  if (hexToInt(&ptr, &addr)	      && *ptr++ == ','	      && hexToInt(&ptr, &length)	      && *ptr++ == ':')	    {	      if (hex2mem(ptr, (char *)addr, length, 1))		strcpy(remcomOutBuffer, "OK");	      else		strcpy(remcomOutBuffer, "E03");	    }	  else	    strcpy(remcomOutBuffer, "E02");	  break;	case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */	  /* try to read optional parameter, pc unchanged if no parm */	  ptr = &remcomInBuffer[1];	  if (hexToInt(&ptr, &addr))	    {	      registers[PC] = addr;	      registers[NPC] = addr + 4;	    }/* 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. */	  flush_i_cache();	  return;	  /* kill the program */	case 'k' :		/* do nothing */	  break;#if 0	case 't':		/* Test feature */	  asm (" std %f30,[%sp]");	  break;#endif	case 'r':		/* Reset */	  asm ("call 0		nop ");	  break;#if 0Disabled until we can unscrew this properly	case 'b':	  /* bBB...  Set baud rate to BB... */	  {	    int baudrate;	    extern void set_timer_3();	    ptr = &remcomInBuffer[1];	    if (!hexToInt(&ptr, &baudrate))	      {		strcpy(remcomOutBuffer,"B01");		break;	      }	    /* Convert baud rate to uart clock divider */	    switch (baudrate)	      {	      case 38400:		baudrate = 16;		break;	      case 19200:		baudrate = 33;		break;	      case 9600:		baudrate = 65;		break;	      default:		strcpy(remcomOutBuffer,"B02");		goto x1;	      }	    putpacket("OK");	/* Ack before changing speed */	    set_timer_3(baudrate); /* Set it */	  }x1:	  break;#endif	}			/* switch */      /* reply to the request */      putpacket(remcomOutBuffer);    }}/* 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(){  if (!initialized)    return;  asm("	.globl _breakinst	_breakinst: ta 1      ");}

⌨️ 快捷键说明

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