Example #1
0
static int
dtrace_invop_start(struct trapframe *frame)
{
	register_t *sp;
	int16_t offs;
	int invop;

	invop = dtrace_invop(frame->pc, frame, frame->pc);
	offs = (invop & LDSD_DATA_MASK);
	sp = (register_t *)((uint8_t *)frame->sp + offs);

	switch (invop & LDSD_RA_SP_MASK) {
	case LD_RA_SP:
		frame->ra = *sp;
		frame->pc += INSN_SIZE;
		break;
	case SD_RA_SP:
		*(sp) = frame->ra;
		frame->pc += INSN_SIZE;
		break;
	default:
		printf("%s: 0x%x undefined\n", __func__, invop);
		return (-1);
	};

	return (0);
}
Example #2
0
static int
dtrace_invop_start(struct trapframe *frame)
{
	switch (dtrace_invop(frame->srr0, (uintptr_t *)frame, frame->fixreg[3])) {
	case DTRACE_INVOP_JUMP:
		break;
	case DTRACE_INVOP_BCTR:
		frame->srr0 = frame->ctr;
		break;
	case DTRACE_INVOP_BLR:
		frame->srr0 = frame->lr;
		break;
	case DTRACE_INVOP_MFLR_R0:
		frame->fixreg[0] = frame->lr ;
		break;
	default:
		return (-1);
		break;
	}

	return (0);
}
Example #3
0
static int
dtrace_invop_start(struct trapframe *frame)
{
	register_t *r0, *sp;
	int data, invop, reg, update_sp;

	invop = dtrace_invop(frame->tf_pc, frame, frame->tf_pc);
	switch (invop & DTRACE_INVOP_MASK) {
	case DTRACE_INVOP_PUSHM:
		sp = (register_t *)frame->tf_svc_sp;
		r0 = &frame->tf_r0;
		data = DTRACE_INVOP_DATA(invop);

		/*
		 * Store the pc, lr, and sp. These have their own
		 * entries in the struct.
		 */
		if (data & (1 << BIT_PC)) {
			sp--;
			*sp = frame->tf_pc;
		}
		if (data & (1 << BIT_LR)) {
			sp--;
			*sp = frame->tf_svc_lr;
		}
		if (data & (1 << BIT_SP)) {
			sp--;
			*sp = frame->tf_svc_sp;
		}

		/* Store the general registers */
		for (reg = 12; reg >= 0; reg--) {
			if (data & (1 << reg)) {
				sp--;
				*sp = r0[reg];
			}
		}

		/* Update the stack pointer and program counter to continue */
		frame->tf_svc_sp = (register_t)sp;
		frame->tf_pc += 4;
		break;
	case DTRACE_INVOP_POPM:
		sp = (register_t *)frame->tf_svc_sp;
		r0 = &frame->tf_r0;
		data = DTRACE_INVOP_DATA(invop);

		/* Read the general registers */
		for (reg = 0; reg <= 12; reg++) {
			if (data & (1 << reg)) {
				r0[reg] = *sp;
				sp++;
			}
		}

		/*
		 * Set the stack pointer. If we don't update it here we will
		 * need to update it at the end as the instruction would do
		 */
		update_sp = 1;
		if (data & (1 << BIT_SP)) {
			frame->tf_svc_sp = *sp;
			*sp++;
			update_sp = 0;
		}

		/* Update the link register, we need to use the correct copy */
		if (data & (1 << BIT_LR)) {
			frame->tf_svc_lr = *sp;
			*sp++;
		}
		/*
		 * And the program counter. If it's not in the list skip over
		 * it when we return so to not hit this again.
		 */
		if (data & (1 << BIT_PC)) {
			frame->tf_pc = *sp;
			*sp++;
		} else
			frame->tf_pc += 4;

		/* Update the stack pointer if we haven't already done so */
		if (update_sp)
			frame->tf_svc_sp = (register_t)sp;
		break;
	case DTRACE_INVOP_B:
		data = DTRACE_INVOP_DATA(invop) & 0x00ffffff;
		/* Sign extend the data */
		if ((data & (1 << 23)) != 0)
			data |= 0xff000000;
		/* The data is the number of 4-byte words to change the pc */
		data *= 4;
		data += 8;
		frame->tf_pc += data;
		break;
	default:
		return (-1);
		break;
	}

	return (0);
}