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

📄 gdb.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 3 页
字号:
	strcpy( out_buf, "S05" );	break;      case 'G' :	/* 	 *  write 32 bit regs  GXX..XX	Each byte of register data	 *				is described by two hex digits.	 *  reply	       OK	for success	 *		       ENN	for an error	 */	rc = write_regs( in_buf, sizeof(UINT32) );	if( rc != GDB_OK )	    return rc;		strcpy( out_buf, "OK" );	break;      case 'H' :	/* 	 *  Set Thread (Hg | Hc) or "Write 64 bit regs" command.	 *	 *  Set Thread request is ignored.	 *	 *  Write 64 bit regs  HXX..XX	Each byte of register data	 *				is described by two hex digits.	 *  reply	       OK	for success	 *		       ENN	for an error	 */	if( (*in_buf == 'g') || (*in_buf == 'c') )	{	    /* Possibly "set thread" command */	    if( strlen( in_buf ) <= 18 )	    {	        *out_buf = '\0';		break;	    }        }	/* Write 64 bit regs command */	rc = write_regs( in_buf, sizeof(UINT64) );	if( rc != GDB_OK )	    return rc;		strcpy( out_buf, "OK" );	break;      case 'g' :	/* 	 *  read registers  g[S]	Registers of size S	 *  reply	    XX....X	Each byte of register data	 *				is described by two hex digits.	 *				Registers are in the internal order	 *				for GDB, and the bytes in a register	 *				are in the same order the machine uses.	 *		    or ENN	for an error.	 */	if( *in_buf != '\0' )	{	    size = gethex( in_buf, &ptr, &rc, FALSE );	    if( (rc != GDB_OK) || (*ptr != '\0') )            {	        return GDB_ERROR_GENERAL;            }	    if( (size != sizeof(UINT32)) &&		(size != sizeof(UINT64)) )	    {		return GDB_ERROR_GENERAL;	    }        }	else	    size = sizeof(UINT32);	read_regs( out_buf, size );	break;      case 'r' :              /*	 *  Read single register (SDE extension)   rNN[:S]    Register NN 	 *						       of size S  	 */	reg = gethex( in_buf, &ptr, &rc, FALSE );	if( (rc != GDB_OK) || ( (*ptr != '\0') && (*ptr != ':') ) )        {	    return GDB_ERROR_GENERAL;        }	else        {	    if( *ptr == ':' )	    {	        ptr++;	        size = gethex( ptr, &ptr, &rc, FALSE );		if( (rc != GDB_OK) || (*ptr != '\0') )		{		    return GDB_ERROR_GENERAL;		}		if( (size != sizeof(UINT32)) &&		    (size != sizeof(UINT64)) )		{		    return GDB_ERROR_GENERAL;		}            }	    else		        size = sizeof(UINT32);        }	setval( &out_buf, SYS_CPUREG(&appl_context, reg), size, TRUE );	*out_buf = '\0';	break;      case 'R' :         /*	  *  Command depends on whether we are running extended          *  protocol (due to '!' command) or not.	  *          *  Normal   : Identical to 'P', see below.	  *  Extended : Restart (reinitialise registers)	  */         if(extended && (*in_buf == '\0') ) 	 {	     init_data();	     strcpy( out_buf, "OK" );	     break;         }          /* Fallthrough !! */      case 'P' :        /*	 *  Write single register (SDE extension)   PNN[:S]=XX    Register NN 	 *						          of size S  	 */	reg = gethex( in_buf, &ptr, &rc, FALSE );	if( rc != GDB_OK )	    return GDB_ERROR_GENERAL;	size = sizeof(UINT32);  /* Default */        switch( *ptr )	{	  case ':' :	    ptr++;	    	    size = gethex( ptr, &ptr, &rc, FALSE );   	    if( (rc != GDB_OK)           ||		(size != sizeof(UINT32)) ||		(*ptr != '=') )            {		return GDB_ERROR_GENERAL;	    }	    if( (size != sizeof(UINT32)) &&		(size != sizeof(UINT64)) )	    {		return GDB_ERROR_GENERAL;	    }  	    /* FALL THROUGH ! */	  case '=' :	    ptr++;	    val = gethex( ptr, &ptr, &rc, TRUE );	    if( size == sizeof(UINT32) )	    {	        /* Sign extend */		val = (INT64)((INT32)((UINT32)val));	    }	    if( (rc != GDB_OK) || (*ptr != '\0') )	    {	        return GDB_ERROR_GENERAL;	    }	    break;	  default  :	    return GDB_ERROR_GENERAL;        }        SYS_CPUREG(&appl_context, reg) = val;	strcpy( out_buf, "OK" );	break;      case 'm' :        /*	 *  read mem	mAA..AA,LLLL	AA..AA is address, LLLL is length.	 *  reply	XX..XX		XX..XX is mem contents	 *				Can be fewer bytes than requested	 *				if able to read only part of the data.	 *		or ENN		NN is errno         */	 /**** Fall through !! ****/      case 'M' :	/* 	 *  write mem	MAA..AA,LLLL:XX..XX	 *				AA..AA is address,	 *				LLLL is number of bytes,	 *				XX..XX is data	 *  reply	OK		for success	 *		ENN		for an error (this includes the case	 *				where only part of the data was	 *				written).	 */	/* Find the ',' */	ptr = strchr( in_buf, ',' );	if( ptr )	{	    *ptr = '\0';	    ptr++;	    	    /* Get address */	    address = gethex( in_buf, NULL, &rc, FALSE );	    if( rc != GDB_OK )	        return GDB_ERROR_GENERAL;	    /* Get count */	    count = gethex( ptr, NULL, &rc, FALSE );	    if( rc != GDB_OK )	        return GDB_ERROR_GENERAL;	}	if( !ptr )	    return GDB_ERROR_GENERAL;	else	{  	    /* Validate range */	    if( sys_validate_range( address,				    count,				    sizeof(UINT8),				    FALSE ) != OK )	    {	        return GDB_ERROR_ADDRESS;	    }	    if( ch == 'm' )	    {	        /* Read */		for( i=0; i<count; i++ )		{		    setval( &out_buf, (UINT64)REG8(address),			    sizeof(UINT8), FALSE );		    address++;		}	    }	    else	    {	        /* Write (M command) */	        		/* Find the ':' */		ptr = strchr( ptr, ':' );		if( !ptr )		    return GDB_ERROR_GENERAL;		else		    ptr++;				for( i=0; i<count; i++ )		{		    rc = getval( &ptr, &val, 2*sizeof(UINT8), FALSE, FALSE );		    if( rc != GDB_OK )		        return rc;		    /* Convert to KSEG0 */		    if( !sys_kseg0( address, &addr_kseg0 ) )		        return GDB_ERROR_ADDRESS;		    REG8(addr_kseg0) = (UINT8)val;		    /*  Flush D-cache in order to store data in		     *  physical memory.		     *  Invalidate I-cache since new instructions may		     *  have been stored;		     */		    sys_flush_cache_line( (void *)addr_kseg0 );		    address++;		}   		strcpy( out_buf, "OK" );		out_buf += 2;	    }	    *out_buf = '\0';	}	break;      case 'C' :	/*	 *  continue with	Csig;AA..AA	Continue with signal sig (hex signal	 *  signal				number).  If ;AA..AA is omitted, 	 *					resume at same address.	 */      case 'S' :	/* 	 *  step with		Ssig;AA..AA	Like 'C' but step not continue.	 *  signal	 */	 /* skip sig; sequence */	 ptr = strchr( in_buf, ';' );	 if( ptr )	     in_buf = ptr + 1;	 /**** Fall through !! ****/      case 'c' :		/* 	 *  continue	cAA..AA  	AA..AA is address to resume	 *				If AA..AA is omitted,	 *				resume at same address.         */      case 's' :        /* 	 *  step	sAA..AA		AA..AA is address to resume	 *				If AA..AA is omitted,	 *				resume at same address.	 */	if( *in_buf != '\0' )	{	    /* Get address */            address = gethex( in_buf, NULL, &rc, FALSE );	    if( rc != GDB_OK )	        return GDB_ERROR_GENERAL;	    else	    {	        /* Store address in epc */	        appl_context.cp0_epc = (INT64)((INT32)address);	        /* Clear ERL and set EXL so that EPC will be used upon eret */	        appl_context.cp0_status &= ~(UINT64)M_StatusERL;	        appl_context.cp0_status |= (UINT64)M_StatusEXL;	    }	}	if( (ch == 's') || (ch =='S') )	{   	    if( !setup_single_step() )	        return GDB_ERROR_ADDRESS;	    *ss = TRUE;	}	return GDB_CONTINUE;      case 'D' :	/* detach         D               Reply OK. */      case 'k' :	/* kill request	k */	strcpy( out_buf, "OK" );	/* Reply ignored by GBD for kill */	return GDB_KILL;      default  : /* Other */	*out_buf = '\0';	break;    }    return GDB_OK;}/************************************************************************ *                          put_packet ************************************************************************/static voidput_packet(    char *buf ){    UINT8 csum      = 0;    bool  calc_csum = FALSE;    char  ch[2];    char  *s = buf;    while( *buf != '\0' )    {        PUTCHAR( gdb_port, *buf );	if( calc_csum )		    csum += (UINT8)(*buf);	if( *buf == '$' )	    calc_csum = TRUE;	buf++;    }    if( calc_csum )    {        ch[0] = hex2char( csum >> 4 );	ch[1] = hex2char( csum & 0xF );        PUTCHAR( gdb_port, '#' );        PUTCHAR( gdb_port, ch[0] );        PUTCHAR( gdb_port, ch[1] );        if( verbose )        {            printf( "(To Host : %s#%c%c)", s, ch[0], ch[1] );        }    }    else    {        if( verbose )        {            printf( "(To Host : %s)", s );        }    }}/************************************************************************ *				shell_get_epc ************************************************************************/static UINT64*shell_get_epc(    t_gdb_regs *regs ){    return        ( (UINT32)regs->cp0_status & M_StatusERL ) ?	    &regs->cp0_errorepc :	    &regs->cp0_epc;}/************************************************************************ *                          setup_single_step ************************************************************************/static boolsetup_single_step( void ){    UINT32 epc, instruction, opcode;    UINT32 addr_kseg0;    UINT32 i;    bool   branch;    INT32  offset;    UINT32 target;    bool   mips16e;    bool   extend;    bool   jump;    UINT32 size;    UINT32 reg;        /* Read EPC (only support for 32 bit) */    epc	= (UINT32)*shell_get_epc(&appl_context);    /* Determine mips16e, then clear lsb */    mips16e =  (epc & 1);    epc	    &= ~1;    size    =  mips16e ? sizeof(UINT16) : sizeof(UINT32);    if( mips16e && !sys_mips16e )        return FALSE;        /* Validate address */    if( sys_validate_range( epc,			    size,			    size,			    FALSE ) != OK )    {        return FALSE;    }    /* Convert to KSEG0 */    if( !sys_kseg0( epc, &addr_kseg0 ) )        return FALSE;    /* Read next instruction */    instruction = mips16e ? REG16( addr_kseg0 ) : REG32( addr_kseg0 );    /* Defaults */    branch     = FALSE;    extend     = FALSE;    ss_count   = 1;    ss_addr[0] = epc + size;    /* Determine where to set BREAK(s) */    if( mips16e )    {        opcode = MIPS16E_OPCODE(instruction);	if( (opcode == MIPS16E_OPC_EXTEND) ||	    (opcode == MIPS16E_OPC_JAL_X) )	{	    extend = TRUE;	    epc        += sizeof(UINT16);            ss_addr[0] += sizeof(UINT16);            /* Validate address of second half of instruction */            if( sys_validate_range( epc,			            sizeof(UINT16),			            sizeof(UINT16),			            FALSE ) != OK )            {                return FALSE;            }	    /* Convert to KSEG0 */	    if( !sys_kseg0( epc, &addr_kseg0 ) )	        return FALSE;	    /* Read next instruction */	    instruction = (instruction << 16) | REG16( addr_kseg0 );	    if( opcode == MIPS16E_OPC_EXTEND )                opcode = MIPS16E_OPCODE(instruction);        }	/* Default break must be MIPS16e */        ss_addr[0] |= 1;	switch( opcode )	{	  case MIPS16E_OPC_B :	    if( extend )	    { 	        offset = (((instruction >> 16) & 0x1f) << 11) |		         (((instruction >> 21) & 0x3f) <<  5) |			 (((instruction >>  0) & 0x1f) <<  0);		offset <<= 1;		/* Sign extend */		if( offset & 0x10000 ) 		    offset |= 0xffff0000;	    }	    else	    {	        offset = (instruction & 0x7ff) << 1;		/* Sign extend */		if( offset & 0x800 )		    offset |= 0xfffff000;  	    }	    ss_addr[0] =  (UINT32)(offset + (INT32)(epc + 2));	    ss_addr[0] |= 1;	    break;	  case MIPS16E_OPC_BEQZ :	  case MIPS16E_OPC_BNEZ :	    branch = TRUE;	    break;	  case MIPS16E_OPC_I8 :	    switch( MIPS16E_I8_FUNCTION( instruction ) )	    {	      case MIPS16E_I8_FUNC_BTEQZ :	      case MIPS16E_I8_FUNC_BTNEZ :	        branch = TRUE;		break;	    }	    break;	  case MIPS16E_OPC_JAL_X : 	    /* JAL/JALX */	    target = (((instruction >> 16) & 0x001f) << 21) |		     (((instruction >> 21) & 0x001f) << 16) |		     (((instruction >>  0) & 0xffff) <<  0);	    target <<= 2;	    ss_addr[0] = ((epc + 2) & 0xf0000000) | target;	    if( MIPS16E_X( instruction ) != MIPS16E_X_JALX )	        ss_addr[0] |= 1;	    break;	  case MIPS16E_OPC_RR :	    if( MIPS16E_RR_FUNCTION( instruction ) ==	            MIPS16E_RR_FUNC_JALRC )	    {

⌨️ 快捷键说明

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