/* 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 fetched from buf.
*/
static char *
hex2mem(char *buf, char *mem, int count)
{
	int hexValue;
	char *tmp_raw, *tmp_hex;

	/*
	 * We use the upper half of buf as an intermediate buffer for the
	 * raw memory that is converted from hex.
	 */
	tmp_raw = buf + count * 2;
	tmp_hex = tmp_raw - 1;

	longjmp_on_fault = 1;
	while (tmp_hex >= buf) {
		tmp_raw--;
		hexValue = hex(*tmp_hex--);
		if (hexValue < 0)
			kgdb_error(KGDBERR_NOTHEXDIG);
		*tmp_raw = hexValue;
		hexValue = hex(*tmp_hex--);
		if (hexValue < 0)
			kgdb_error(KGDBERR_NOTHEXDIG);
		*tmp_raw |= hexValue << 4;

	}

	memcpy(mem, tmp_raw, count);

	kgdb_flush_cache_range((void *)mem, (void *)(mem+count));
	longjmp_on_fault = 0;

	return buf;
}
Exemple #2
0
void kgdb_putregs(struct pt_regs *regs, char *buf, int length)
{
	unsigned long *gdb_regs = (unsigned long *)buf;

	if (length < (GDB_MAX_REGS *sizeof(unsigned long)))
		kgdb_error(KGDBERR_NOSPACE);

	if ((unsigned long)gdb_regs & 3)
		kgdb_error(KGDBERR_ALIGNFAULT);

	regs->ARM_r0	= gdb_regs[_R0];
	regs->ARM_r1	= gdb_regs[_R1];
	regs->ARM_r2	= gdb_regs[_R2];
	regs->ARM_r3	= gdb_regs[_R3];
	regs->ARM_r4	= gdb_regs[_R4];
	regs->ARM_r5	= gdb_regs[_R5];
	regs->ARM_r6	= gdb_regs[_R6];
	regs->ARM_r7	= gdb_regs[_R7];
	regs->ARM_r8	= gdb_regs[_R8];
	regs->ARM_r9	= gdb_regs[_R9];
	regs->ARM_r10	= gdb_regs[_R10];
	regs->ARM_fp	= gdb_regs[_FP];
	regs->ARM_ip	= gdb_regs[_IP];
	regs->ARM_sp	= gdb_regs[_SPT];
	regs->ARM_lr	= gdb_regs[_LR];
	regs->ARM_pc	= gdb_regs[_PC];
	regs->ARM_cpsr	= gdb_regs[_CPSR];
}
Exemple #3
0
void kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
{
	unsigned long val, *ptr = (unsigned long *)buf;

	if (regno < 0 || GDB_MAX_REGS <= regno)
		kgdb_error(KGDBERR_BADPARAMS);
	else {
		if (length < 4)
			kgdb_error(KGDBERR_NOSPACE);
	}
	if ((unsigned long)ptr & 3)
		kgdb_error(KGDBERR_ALIGNFAULT);
	else
		val = *ptr;

	switch (regno) {
	case _R0:
		regs->ARM_r0 = val; break;
	case _R1:
		regs->ARM_r1 = val; break;
	case _R2:
		regs->ARM_r2 = val; break;
	case _R3:
		regs->ARM_r3 = val; break;
	case _R4:
		regs->ARM_r4 = val; break;
	case _R5:
		regs->ARM_r5 = val; break;
	case _R6:
		regs->ARM_r6 = val; break;
	case _R7:
		regs->ARM_r7 = val; break;
	case _R8:
		regs->ARM_r8 = val; break;
	case _R9:
		regs->ARM_r9 = val; break;
	case _R10:
		regs->ARM_r10 = val; break;
	case _FP:
		regs->ARM_fp = val; break;
	case _IP:
		regs->ARM_ip = val; break;
	case _SPT:
		regs->ARM_sp = val; break;
	case _LR:
		regs->ARM_lr = val; break;
	case _PC:
		regs->ARM_pc = val; break;
	case 0x19:
		regs->ARM_cpsr = val; break;
	default:
		kgdb_error(KGDBERR_BADPARAMS);
	}
}
Exemple #4
0
int kgdb_getregs(struct pt_regs *regs, char *buf, int max)
{
	int i;
	unsigned long *gdb_regs = (unsigned long *)buf;

	if (max < (GDB_MAX_REGS * sizeof(unsigned long)))
		kgdb_error(KGDBERR_NOSPACE);

	/* Initialize all to zero. */
	for (i = 0; i < GDB_MAX_REGS; i++)
		gdb_regs[i] = 0;

	gdb_regs[_R0]   = regs->ARM_r0;
	gdb_regs[_R1]   = regs->ARM_r1;
	gdb_regs[_R2]   = regs->ARM_r2;
	gdb_regs[_R3]   = regs->ARM_r3;
	gdb_regs[_R4]   = regs->ARM_r4;
	gdb_regs[_R5]   = regs->ARM_r5;
	gdb_regs[_R6]   = regs->ARM_r6;
	gdb_regs[_R7]   = regs->ARM_r7;
	gdb_regs[_R8]   = regs->ARM_r8;
	gdb_regs[_R9]   = regs->ARM_r9;
	gdb_regs[_R10]  = regs->ARM_r10;
	gdb_regs[_FP]   = regs->ARM_fp;
	gdb_regs[_IP]   = regs->ARM_ip;
	gdb_regs[_SPT]  = regs->ARM_sp;
	gdb_regs[_LR]   = regs->ARM_lr;
	gdb_regs[_PC]   = regs->ARM_pc;
	gdb_regs[_CPSR] = regs->ARM_cpsr;

	return GDB_MAX_REGS *sizeof(unsigned long);
}
/* 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 fetched from buf.
*/
static char *
hex2mem(char *buf, char *mem, int count)
{
	int i, hexValue;
	unsigned char ch;
	char *mem_start = mem;

	longjmp_on_fault = 1;
	for (i=0; i<count; i++) {
		if ((hexValue = hex(*buf++)) < 0)
			kgdb_error(KGDBERR_NOTHEXDIG);
		ch = hexValue << 4;
		if ((hexValue = hex(*buf++)) < 0)
			kgdb_error(KGDBERR_NOTHEXDIG);
		ch |= hexValue;
		*mem++ = ch;
	}
	kgdb_flush_cache_range((void *)mem_start, (void *)(mem - 1));
	longjmp_on_fault = 0;

	return buf;
}
/*
 * This function does all command processing for interfacing to gdb.
 */
static int
handle_exception (struct pt_regs *regs)
{
	int addr;
	int length;
	char *ptr;
	kgdb_data kd;
	int i;

	if (!initialized) {
		printf("kgdb: exception before kgdb is initialized! huh?\n");
		return (0);
	}

	/* probably should check which exception occured as well */
	if (longjmp_on_fault) {
		longjmp_on_fault = 0;
		kgdb_longjmp(error_jmp_buf, KGDBERR_MEMFAULT);
		panic("kgdb longjump failed!\n");
	}

	if (kgdb_active) {
		printf("kgdb: unexpected exception from within kgdb\n");
		return (0);
	}
	kgdb_active = 1;

	kgdb_interruptible(0);

	printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));

	if (kgdb_setjmp(error_jmp_buf) != 0)
		panic("kgdb: error or fault in entry init!\n");

	kgdb_enter(regs, &kd);

	if (first_entry) {
		/*
		 * the first time we enter kgdb, we save the processor
		 * state so that we can return to the monitor if the
		 * remote end quits gdb (or at least, tells us to quit
		 * with the 'k' packet)
		 */
		entry_regs = *regs;
		first_entry = 0;
	}

	ptr = remcomOutBuffer;

	*ptr++ = 'T';

	*ptr++ = hexchars[kd.sigval >> 4];
	*ptr++ = hexchars[kd.sigval & 0xf];

	for (i = 0; i < kd.nregs; i++) {
		kgdb_reg *rp = &kd.regs[i];

		*ptr++ = hexchars[rp->num >> 4];
		*ptr++ = hexchars[rp->num & 0xf];
		*ptr++ = ':';
		ptr = (char *)mem2hex((char *)&rp->val, ptr, 4);
		*ptr++ = ';';
	}

	*ptr = 0;

#ifdef KGDB_DEBUG
	if (kdebug)
		printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
#endif

	putpacket((unsigned char *)&remcomOutBuffer);

	while (1) {
		volatile int errnum;

		remcomOutBuffer[0] = 0;

		getpacket(remcomInBuffer);
		ptr = &remcomInBuffer[1];

#ifdef KGDB_DEBUG
		if (kdebug)
			printf("kgdb:  remcomInBuffer: %s\n", remcomInBuffer);
#endif

		errnum = kgdb_setjmp(error_jmp_buf);

		if (errnum == 0) switch (remcomInBuffer[0]) {

		case '?':               /* report most recent signal */
			remcomOutBuffer[0] = 'S';
			remcomOutBuffer[1] = hexchars[kd.sigval >> 4];
			remcomOutBuffer[2] = hexchars[kd.sigval & 0xf];
			remcomOutBuffer[3] = 0;
			break;

#ifdef KGDB_DEBUG
		case 'd':
			/* toggle debug flag */
			kdebug ^= 1;
			break;
#endif

		case 'g':	/* return the value of the CPU registers. */
			length = kgdb_getregs(regs, remcomRegBuffer, BUFMAX);
			mem2hex(remcomRegBuffer, remcomOutBuffer, length);
			break;

		case 'G':   /* set the value of the CPU registers */
			length = strlen(ptr);
			if ((length & 1) != 0) kgdb_error(KGDBERR_BADPARAMS);
			hex2mem(ptr, remcomRegBuffer, length/2);
			kgdb_putregs(regs, remcomRegBuffer, length/2);
			strcpy(remcomOutBuffer,"OK");
			break;

		case 'm':	/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
				/* Try to read %x,%x.  */

			if (hexToInt(&ptr, &addr)
			    && *ptr++ == ','
			    && hexToInt(&ptr, &length))	{
				mem2hex((char *)addr, remcomOutBuffer, length);
			} else {
				kgdb_error(KGDBERR_BADPARAMS);
			}
			break;

		case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
			/* Try to read '%x,%x:'.  */

			if (hexToInt(&ptr, &addr)
			    && *ptr++ == ','
			    && hexToInt(&ptr, &length)
			    && *ptr++ == ':') {
				hex2mem(ptr, (char *)addr, length);
				strcpy(remcomOutBuffer, "OK");
			} else {
				kgdb_error(KGDBERR_BADPARAMS);
			}
			break;


		case 'k':    /* kill the program, actually return to monitor */
			kd.extype = KGDBEXIT_KILL;
			*regs = entry_regs;
			first_entry = 1;
			goto doexit;

		case 'C':    /* CSS  continue with signal SS */
			*ptr = '\0';	/* ignore the signal number for now */
			/* fall through */

		case 'c':    /* cAA..AA  Continue; address AA..AA optional */
			/* try to read optional parameter, pc unchanged if no parm */
			kd.extype = KGDBEXIT_CONTINUE;

			if (hexToInt(&ptr, &addr)) {
				kd.exaddr = addr;
				kd.extype |= KGDBEXIT_WITHADDR;
			}

			goto doexit;

		case 'S':    /* SSS  single step with signal SS */
			*ptr = '\0';	/* ignore the signal number for now */
			/* fall through */

		case 's':
			kd.extype = KGDBEXIT_SINGLE;

			if (hexToInt(&ptr, &addr)) {
				kd.exaddr = addr;
				kd.extype |= KGDBEXIT_WITHADDR;
			}

		doexit:
/* 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.
 */
			kgdb_flush_cache_all();
			kgdb_exit(regs, &kd);
			kgdb_active = 0;
			kgdb_interruptible(1);
			return (1);

		case 'r':		/* Reset (if user process..exit ???)*/
			panic("kgdb reset.");
			break;

		case 'P':    /* Pr=v  set reg r to value v (r and v are hex) */
			if (hexToInt(&ptr, &addr)
			    && *ptr++ == '='
			    && ((length = strlen(ptr)) & 1) == 0) {
				hex2mem(ptr, remcomRegBuffer, length/2);
				kgdb_putreg(regs, addr,
					remcomRegBuffer, length/2);
				strcpy(remcomOutBuffer,"OK");
			} else {
				kgdb_error(KGDBERR_BADPARAMS);
			}
			break;
		}			/* switch */

		if (errnum != 0)
			sprintf(remcomOutBuffer, "E%02d", errnum);

#ifdef KGDB_DEBUG
		if (kdebug)
			printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
#endif

		/* reply to the request */
		putpacket((unsigned char *)&remcomOutBuffer);

	} /* while(1) */
}
Exemple #7
0
void kgdb_putregs(struct pt_regs *regs, char *buf, int length)
{
    unsigned long *gdb_regs = (unsigned long *)buf;

    if (length != BFIN_NUM_REGS)
        kgdb_error(KGDBERR_NOSPACE);

    if ((unsigned long)gdb_regs & 3)
        kgdb_error(KGDBERR_ALIGNFAULT);

    regs->r0 = gdb_regs[BFIN_R0];
    regs->r1 = gdb_regs[BFIN_R1];
    regs->r2 = gdb_regs[BFIN_R2];
    regs->r3 = gdb_regs[BFIN_R3];
    regs->r4 = gdb_regs[BFIN_R4];
    regs->r5 = gdb_regs[BFIN_R5];
    regs->r6 = gdb_regs[BFIN_R6];
    regs->r7 = gdb_regs[BFIN_R7];
    regs->p0 = gdb_regs[BFIN_P0];
    regs->p1 = gdb_regs[BFIN_P1];
    regs->p2 = gdb_regs[BFIN_P2];
    regs->p3 = gdb_regs[BFIN_P3];
    regs->p4 = gdb_regs[BFIN_P4];
    regs->p5 = gdb_regs[BFIN_P5];
    regs->fp = gdb_regs[BFIN_FP];
    /*	regs->sp = gdb_regs[BFIN_ ]; */
    regs->i0 = gdb_regs[BFIN_I0];
    regs->i1 = gdb_regs[BFIN_I1];
    regs->i2 = gdb_regs[BFIN_I2];
    regs->i3 = gdb_regs[BFIN_I3];
    regs->m0 = gdb_regs[BFIN_M0];
    regs->m1 = gdb_regs[BFIN_M1];
    regs->m2 = gdb_regs[BFIN_M2];
    regs->m3 = gdb_regs[BFIN_M3];
    regs->b0 = gdb_regs[BFIN_B0];
    regs->b1 = gdb_regs[BFIN_B1];
    regs->b2 = gdb_regs[BFIN_B2];
    regs->b3 = gdb_regs[BFIN_B3];
    regs->l0 = gdb_regs[BFIN_L0];
    regs->l1 = gdb_regs[BFIN_L1];
    regs->l2 = gdb_regs[BFIN_L2];
    regs->l3 = gdb_regs[BFIN_L3];
    regs->a0x = gdb_regs[BFIN_A0_DOT_X];
    regs->a0w = gdb_regs[BFIN_A0_DOT_W];
    regs->a1x = gdb_regs[BFIN_A1_DOT_X];
    regs->a1w = gdb_regs[BFIN_A1_DOT_W];
    regs->rets = gdb_regs[BFIN_RETS];
    regs->lc0 = gdb_regs[BFIN_LC0];
    regs->lt0 = gdb_regs[BFIN_LT0];
    regs->lb0 = gdb_regs[BFIN_LB0];
    regs->lc1 = gdb_regs[BFIN_LC1];
    regs->lt1 = gdb_regs[BFIN_LT1];
    regs->lb1 = gdb_regs[BFIN_LB1];
    regs->usp = gdb_regs[BFIN_USP];
    regs->syscfg = gdb_regs[BFIN_SYSCFG];
    regs->retx = gdb_regs[BFIN_PC];
    regs->retn = gdb_regs[BFIN_RETN];
    regs->rete = gdb_regs[BFIN_RETE];
    regs->pc = gdb_regs[BFIN_PC];

#if 0	/* can't change these */
    regs->astat = gdb_regs[BFIN_ASTAT];
    regs->seqstat = gdb_regs[BFIN_SEQSTAT];
    regs->ipend = gdb_regs[BFIN_IPEND];
#endif

}
Exemple #8
0
/*
 * putreg - put kgdb's reg (regno) into the pt_regs
 */
void kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
{
    unsigned long *ptr = (unsigned long *)buf;

    if (regno < 0 || regno > BFIN_NUM_REGS)
        kgdb_error(KGDBERR_BADPARAMS);

    if (length < 4)
        kgdb_error(KGDBERR_NOSPACE);

    if ((unsigned long)ptr & 3)
        kgdb_error(KGDBERR_ALIGNFAULT);

    switch (regno) {
    case BFIN_R0:
        regs->r0 = *ptr;
        break;
    case BFIN_R1:
        regs->r1 = *ptr;
        break;
    case BFIN_R2:
        regs->r2 = *ptr;
        break;
    case BFIN_R3:
        regs->r3 = *ptr;
        break;
    case BFIN_R4:
        regs->r4 = *ptr;
        break;
    case BFIN_R5:
        regs->r5 = *ptr;
        break;
    case BFIN_R6:
        regs->r6 = *ptr;
        break;
    case BFIN_R7:
        regs->r7 = *ptr;
        break;
    case BFIN_P0:
        regs->p0 = *ptr;
        break;
    case BFIN_P1:
        regs->p1 = *ptr;
        break;
    case BFIN_P2:
        regs->p2 = *ptr;
        break;
    case BFIN_P3:
        regs->p3 = *ptr;
        break;
    case BFIN_P4:
        regs->p4 = *ptr;
        break;
    case BFIN_P5:
        regs->p5 = *ptr;
        break;
    case BFIN_SP:
        regs->reserved = *ptr;
        break;
    case BFIN_FP:
        regs->fp = *ptr;
        break;
    case BFIN_I0:
        regs->i0 = *ptr;
        break;
    case BFIN_I1:
        regs->i1 = *ptr;
        break;
    case BFIN_I2:
        regs->i2 = *ptr;
        break;
    case BFIN_I3:
        regs->i3 = *ptr;
        break;
    case BFIN_M0:
        regs->m0 = *ptr;
        break;
    case BFIN_M1:
        regs->m1 = *ptr;
        break;
    case BFIN_M2:
        regs->m2 = *ptr;
        break;
    case BFIN_M3:
        regs->m3 = *ptr;
        break;
    case BFIN_B0:
        regs->b0 = *ptr;
        break;
    case BFIN_B1:
        regs->b1 = *ptr;
        break;
    case BFIN_B2:
        regs->b2 = *ptr;
        break;
    case BFIN_B3:
        regs->b3 = *ptr;
        break;
    case BFIN_L0:
        regs->l0 = *ptr;
        break;
    case BFIN_L1:
        regs->l1 = *ptr;
        break;
    case BFIN_L2:
        regs->l2 = *ptr;
        break;
    case BFIN_L3:
        regs->l3 = *ptr;
        break;
    case BFIN_A0_DOT_X:
        regs->a0x = *ptr;
        break;
    case BFIN_A0_DOT_W:
        regs->a0w = *ptr;
        break;
    case BFIN_A1_DOT_X:
        regs->a1x = *ptr;
        break;
    case BFIN_A1_DOT_W:
        regs->a1w = *ptr;
        break;
    case BFIN_ASTAT:
        regs->astat = *ptr;
        break;
    case BFIN_RETS:
        regs->rets = *ptr;
        break;
    case BFIN_LC0:
        regs->lc0 = *ptr;
        break;
    case BFIN_LT0:
        regs->lt0 = *ptr;
        break;
    case BFIN_LB0:
        regs->lb0 = *ptr;
        break;
    case BFIN_LC1:
        regs->lc1 = *ptr;
        break;
    case BFIN_LT1:
        regs->lt1 = *ptr;
        break;
    case BFIN_LB1:
        regs->lb1 = *ptr;
        break;
    /*
      BFIN_CYCLES,
      BFIN_CYCLES2,
      BFIN_USP,
      BFIN_SEQSTAT,
      BFIN_SYSCFG,
    */
    case BFIN_RETX:
        regs->retx = *ptr;
        break;
    case BFIN_RETN:
        regs->retn = *ptr;
        break;
    case BFIN_RETE:
        regs->rete = *ptr;
        break;
    case BFIN_PC:
        regs->pc = *ptr;
        break;

    default:
        kgdb_error(KGDBERR_BADPARAMS);
    }
}
Exemple #9
0
/*
 * getregs - gets the pt_regs, and gives them to kgdb's buffer
 */
int kgdb_getregs(struct pt_regs *regs, char *buf, int max)
{
    unsigned long *gdb_regs = (unsigned long *)buf;

    if (max < NUMREGBYTES)
        kgdb_error(KGDBERR_NOSPACE);

    if ((unsigned long)gdb_regs & 3)
        kgdb_error(KGDBERR_ALIGNFAULT);

    gdb_regs[BFIN_R0] = regs->r0;
    gdb_regs[BFIN_R1] = regs->r1;
    gdb_regs[BFIN_R2] = regs->r2;
    gdb_regs[BFIN_R3] = regs->r3;
    gdb_regs[BFIN_R4] = regs->r4;
    gdb_regs[BFIN_R5] = regs->r5;
    gdb_regs[BFIN_R6] = regs->r6;
    gdb_regs[BFIN_R7] = regs->r7;
    gdb_regs[BFIN_P0] = regs->p0;
    gdb_regs[BFIN_P1] = regs->p1;
    gdb_regs[BFIN_P2] = regs->p2;
    gdb_regs[BFIN_P3] = regs->p3;
    gdb_regs[BFIN_P4] = regs->p4;
    gdb_regs[BFIN_P5] = regs->p5;
    gdb_regs[BFIN_SP] = (unsigned long)regs;
    gdb_regs[BFIN_FP] = regs->fp;
    gdb_regs[BFIN_I0] = regs->i0;
    gdb_regs[BFIN_I1] = regs->i1;
    gdb_regs[BFIN_I2] = regs->i2;
    gdb_regs[BFIN_I3] = regs->i3;
    gdb_regs[BFIN_M0] = regs->m0;
    gdb_regs[BFIN_M1] = regs->m1;
    gdb_regs[BFIN_M2] = regs->m2;
    gdb_regs[BFIN_M3] = regs->m3;
    gdb_regs[BFIN_B0] = regs->b0;
    gdb_regs[BFIN_B1] = regs->b1;
    gdb_regs[BFIN_B2] = regs->b2;
    gdb_regs[BFIN_B3] = regs->b3;
    gdb_regs[BFIN_L0] = regs->l0;
    gdb_regs[BFIN_L1] = regs->l1;
    gdb_regs[BFIN_L2] = regs->l2;
    gdb_regs[BFIN_L3] = regs->l3;
    gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
    gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
    gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
    gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
    gdb_regs[BFIN_ASTAT] = regs->astat;
    gdb_regs[BFIN_RETS] = regs->rets;
    gdb_regs[BFIN_LC0] = regs->lc0;
    gdb_regs[BFIN_LT0] = regs->lt0;
    gdb_regs[BFIN_LB0] = regs->lb0;
    gdb_regs[BFIN_LC1] = regs->lc1;
    gdb_regs[BFIN_LT1] = regs->lt1;
    gdb_regs[BFIN_LB1] = regs->lb1;
    gdb_regs[BFIN_CYCLES] = 0;
    gdb_regs[BFIN_CYCLES2] = 0;
    gdb_regs[BFIN_USP] = regs->usp;
    gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
    gdb_regs[BFIN_SYSCFG] = regs->syscfg;
    gdb_regs[BFIN_RETI] = regs->pc;
    gdb_regs[BFIN_RETX] = regs->retx;
    gdb_regs[BFIN_RETN] = regs->retn;
    gdb_regs[BFIN_RETE] = regs->rete;
    gdb_regs[BFIN_PC] = regs->pc;
    gdb_regs[BFIN_CC] = 0;
    gdb_regs[BFIN_EXTRA1] = 0;
    gdb_regs[BFIN_EXTRA2] = 0;
    gdb_regs[BFIN_EXTRA3] = 0;
    gdb_regs[BFIN_IPEND] = regs->ipend;

    return NUMREGBYTES;
}