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

📄 i386-stub.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* scan for the sequence $<data>#<checksum>     */void getpacket(buffer)char * buffer;{  unsigned char checksum;  unsigned char xmitcsum;  int  i;  int  count;  char ch;  do {    /* wait around for the start character, ignore all other characters */    while ((ch = getDebugChar()) != '$');    checksum = 0;    xmitcsum = -1;    count = 0;    /* now, read until a # or end of buffer is found */    while (count < BUFMAX) {      ch = getDebugChar();      if (ch == '#') break;      checksum = checksum + ch;      buffer[count] = ch;      count = count + 1;      }    buffer[count] = 0;    if (ch == '#') {      xmitcsum = hex(getDebugChar()) << 4;      xmitcsum += hex(getDebugChar());      if ((remote_debug ) && (checksum != xmitcsum)) {        fprintf(stderr,"bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",						     checksum,xmitcsum,buffer);      }      if (checksum != xmitcsum) 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] );	    /* remove sequence chars from buffer */	    count = strlen(buffer);	    for (i=3; i <= count; i++) buffer[i-3] = buffer[i];	 }      }    }  } while (checksum != xmitcsum);}/* send the packet in buffer.  */void putpacket(buffer)char * buffer;{  unsigned char checksum;  int  count;  char ch;  /*  $<packet info>#<checksum>. */  do {  putDebugChar('$');  checksum = 0;  count    = 0;  while (ch=buffer[count]) {    if (! putDebugChar(ch)) return;    checksum += ch;    count += 1;  }  putDebugChar('#');  putDebugChar(hexchars[checksum >> 4]);  putDebugChar(hexchars[checksum % 16]);  } while (getDebugChar() != '+');}char  remcomInBuffer[BUFMAX];char  remcomOutBuffer[BUFMAX];static short error;void debug_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 NORETURN void (*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 (){  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 (addr)     char *addr;{  return *addr;}voidset_char (addr, val)     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 */int computeSignal( exceptionVector )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           *//**********************************************/int hexToInt(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. */void handle_exception(int exceptionVector){  int    sigval;  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 );  remcomOutBuffer[0] = 'S';  remcomOutBuffer[1] =  hexchars[sigval >> 4];  remcomOutBuffer[2] =  hexchars[sigval % 16];  remcomOutBuffer[3] = 0;  putpacket(remcomOutBuffer);  while (1==1) {    error = 0;    remcomOutBuffer[0] = 0;    getpacket(remcomInBuffer);    switch (remcomInBuffer[0]) {      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(&remcomInBuffer[1], (char*) registers, NUMREGBYTES, 0);                strcpy(remcomOutBuffer,"OK");                break;      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */      case 'm' :		    /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */                    ptr = &remcomInBuffer[1];                    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");		      debug_error("malformed read memory command: %s",remcomInBuffer);		    }	          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 */                    ptr = &remcomInBuffer[1];                    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");		      debug_error("malformed write memory command: %s",remcomInBuffer);		    }                break;     /* cAA..AA    Continue at address AA..AA(optional) */     /* sAA..AA   Step one instruction from AA..AA(optional) */     case 'c' :     case 's' :          /* try to read optional parameter, pc unchanged if no parm */         ptr = &remcomInBuffer[1];         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 (remcomInBuffer[0] == 's') registers[ PS ] |= 0x100;          /*           * If we found a match for the PC AND we are not returning           * as a result of a breakpoint (33),           * trace exception (9), nmi (31), jmp to           * the old exception handler as if this code never ran.           */#if 0	  /* Don't really think we need this, except maybe for protection	     exceptions.  */                  /*                   * invoke the previous handler.                   */                  if (oldExceptionHook)                      (*oldExceptionHook) (frame->exceptionVector);                  newPC = registers[ PC ];    /* pc may have changed  */#endif /* 0 */	  _returnFromException(); /* this is a jump */          break;      /* kill the program */      case 'k' :  /* do nothing */		BREAKPOINT();                break;      } /* switch */    /* reply to the request */    putpacket(remcomOutBuffer);    }}/* this function is used to set up exception handlers for tracing and   breakpoints */void set_debug_traps(){extern void remcomHandler();int exception;  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);  if (exceptionHook != remcomHandler)  {      oldExceptionHook = exceptionHook;      exceptionHook    = remcomHandler;  }  /* In case GDB is started before us, ack any packets (presumably     "$?#xx") sitting there.  */  putDebugChar ('+');  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. */void breakpoint(){  if (initialized)#if 0    handle_exception(3);#else    BREAKPOINT();#endif  waitabit();}int waitlimit = 1000000;#if 0voidbogon(){  waitabit();}#endifvoidwaitabit(){  int i;  for (i = 0; i < waitlimit; i++) ;}

⌨️ 快捷键说明

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