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

📄 sparclet-stub.c

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 exception */  {0x3b, SIGSEGV},		/* instruction access error */  {2, SIGILL},			/* illegal    instruction */  {3, SIGILL},			/* privileged instruction */  {4, SIGEMT},			/* fp disabled */  {0x24, SIGEMT},		/* cp disabled */  {7, SIGBUS},			/* mem address not aligned */  {0x29, 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(0x29, fltr_set_mem_err);  else    exceptionHandler(0x29, trap_low);}asm ("	.text	.align 4_dummy_hw_breakpoint:	jmpl %l2, %g0	rett %l2+4	nop	nop");static voidset_hw_breakpoint_trap(enable)     int enable;{  extern void dummy_hw_breakpoint();  if (enable)    exceptionHandler(255, dummy_hw_breakpoint);  else    exceptionHandler(255, trap_low);}static voidget_in_break_mode(){#if 0  int x;  mesg("get_in_break_mode, sp = ");  phex(&x);#endif  set_hw_breakpoint_trap(1);  asm("        sethi   %hi(0xff10), %l4        or      %l4, %lo(0xff10), %l4	sta 	%g0, [%l4]0x1		nop	nop	nop      ");  set_hw_breakpoint_trap(0);}/* 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 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. */static voidhandle_exception (registers)     unsigned long *registers;{  int tt;			/* Trap type */  int sigval;  int addr;  int length;  char *ptr;  unsigned long *sp;  unsigned long dsr;/* First, we must force all of the windows to be spilled out */  asm("	! Ugh.  sparclet has broken save	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-64,%sp	!save %sp, -64, %sp	save	add %fp,-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':	  remote_debug = !(remote_debug);	/* 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 */	    ptr = mem2hex((char *)&registers[Y],		    ptr + 32 * 4 * 2,		    8 * 4,		    0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */	    ptr = mem2hex((char *)&registers[CCSR],		    ptr,		    8 * 4,		    0); /* CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR */	    ptr = mem2hex((char *)&registers[ASR1],		    ptr,		    8 * 4,		    0); /* ASR1,ASR15,ASR17,ASR18,ASR19,ASR20,ASR21,ASR22 */#if 0 /* not implemented */	    ptr = mem2hex((char *) &registers[AWR0], 		    ptr, 		    32 * 4, 		    0); /* Alternate Window Registers */#endif	  }	  break;	case 'G':	/* set value of all the CPU registers - return OK */	case 'P':	/* set value of one CPU register      - return OK */	  {	    unsigned long *newsp, psr;	    psr = registers[PSR];	    ptr = &remcomInBuffer[1];	    if (remcomInBuffer[0] == 'P')	/* do a single register */	      {		int regno;                 if (hexToInt (&ptr, &regno)                    && *ptr++ == '=')                  if (regno >= L0 && regno <= I7)                    hex2mem (ptr, sp + regno - L0, 4, 0);                  else                    hex2mem (ptr, (char *)&registers[regno], 4, 0);                else                  {                    strcpy (remcomOutBuffer, "P01");                    break;                  }	      }	    else	      {		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 */		hex2mem(ptr + 72 * 4 * 2, (char *)&registers[CCSR],			8 * 4, 0); /* CCSR,CCPR,CCCRCR,CCOR,CCOBR,CCIBR,CCIR */		hex2mem(ptr + 80 * 4 * 2, (char *)&registers[ASR1],			8 * 4, 0); /* ASR1 ... ASR22 */#if 0 /* not implemented */		hex2mem(ptr + 88 * 4 * 2, (char *)&registers[AWR0],			8 * 4, 0); /* Alternate Window Registers */#endif	      }	    /* 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      ");}static voidhw_breakpoint(){  asm("      ta 127      ");}#if 0 /* experimental and never finished, left here for reference */static voidsplet_temp(void){  asm("	sub	%sp,(16+1+6+1+121)*4,%sp ! Make room for input & locals 					! + hidden arg + arg spill					! + doubleword alignment					! + registers[121]! Leave a trail of breadcrumbs! (save register save area for debugging)	mov	%sp, %l0	add	%l0, 24*4, %l0	sethi	%hi(_debug_registers), %l1	st	%l0, [%lo(_debug_registers) + %l1]! Save the Alternate Register Set: (not implemented yet)!    To save the Alternate Register set, we must:!    1) Save the current SP in some global location.!    2) Swap the register sets.!    3) Save the Alternate SP in the Y register!    4) Fetch the SP that we saved in step 1.!    5) Use that to save the rest of the regs (not forgetting ASP in Y)!    6) Restore the Alternate SP from Y!    7) Swap the registers back.! 1) Copy the current stack pointer to global _SAVED_STACK_POINTER:	sethi	%hi(_saved_stack_pointer), %l0	st	%sp, [%lo(_saved_stack_pointer) + %l0]! 2) Swap the register sets:	mov	%psr, %l1	sethi	%hi(0x10000), %l2	xor	%l1, %l2, %l1	mov	%l1, %psr	nop			! 3 nops after write to %psr (needed?)	nop	nop! 3) Save Alternate L0 in Y	wr	%l0, 0, %y! 4) Load former SP into alternate SP, using L0	sethi	%hi(_saved_stack_pointer), %l0	or	%lo(_saved_stack_pointer), %l0, %l0	swap	[%l0], %sp! 4.5) Restore alternate L0	rd	%y, %l0! 5) Save the Alternate Window Registers	st	%r0, [%sp + (24 + 88) * 4]	! AWR0	st	%r1, [%sp + (24 + 89) * 4]	! AWR1	st	%r2, [%sp + (24 + 90) * 4]	! AWR2	st	%r3, [%sp + (24 + 91) * 4]	! AWR3	st	%r4, [%sp + (24 + 92) * 4]	! AWR4	st	%r5, [%sp + (24 + 93) * 4]	! AWR5	st	%r6, [%sp + (24 + 94) * 4]	! AWR6	st	%r7, [%sp + (24 + 95) * 4]	! AWR7	st	%r8, [%sp + (24 + 96) * 4]	! AWR8	st	%r9, [%sp + (24 + 97) * 4]	! AWR9	st	%r10, [%sp + (24 + 98) * 4]	! AWR10	st	%r11, [%sp + (24 + 99) * 4]	! AWR11	st	%r12, [%sp + (24 + 100) * 4]	! AWR12	st	%r13, [%sp + (24 + 101) * 4]	! AWR13!	st	%r14, [%sp + (24 + 102) * 4]	! AWR14	(SP)	st	%r15, [%sp + (24 + 103) * 4]	! AWR15	st	%r16, [%sp + (24 + 104) * 4]	! AWR16	st	%r17, [%sp + (24 + 105) * 4]	! AWR17	st	%r18, [%sp + (24 + 106) * 4]	! AWR18	st	%r19, [%sp + (24 + 107) * 4]	! AWR19	st	%r20, [%sp + (24 + 108) * 4]	! AWR20	st	%r21, [%sp + (24 + 109) * 4]	! AWR21	st	%r22, [%sp + (24 + 110) * 4]	! AWR22	st	%r23, [%sp + (24 + 111) * 4]	! AWR23	st	%r24, [%sp + (24 + 112) * 4]	! AWR24	st	%r25, [%sp + (24 + 113) * 4]	! AWR25	st	%r26, [%sp + (24 + 114) * 4]	! AWR26	st	%r27, [%sp + (24 + 115) * 4]	! AWR27	st	%r28, [%sp + (24 + 116) * 4]	! AWR28	st	%r29, [%sp + (24 + 117) * 4]	! AWR29	st	%r30, [%sp + (24 + 118) * 4]	! AWR30	st	%r31, [%sp + (24 + 119) * 4]	! AWR21! Get the Alternate PSR (I hope...)	rd	%psr, %l2	st	%l2, [%sp + (24 + 120) * 4]	! APSR! Don't forget the alternate stack pointer	rd	%y, %l3	st	%l3, [%sp + (24 + 102) * 4]	! AWR14 (SP)! 6) Restore the Alternate SP (saved in Y)	rd	%y, %o6! 7) Swap the registers back:	mov	%psr, %l1	sethi	%hi(0x10000), %l2	xor	%l1, %l2, %l1	mov	%l1, %psr	nop			! 3 nops after write to %psr (needed?)	nop	nop");}#endif

⌨️ 快捷键说明

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