Пример #1
0
void
cpu_set_syscall_retval(struct thread *td, int error)
{

	switch (error) {
	case 0:
		td->td_frame->tf_out[0] = td->td_retval[0];
		td->td_frame->tf_out[1] = td->td_retval[1];
		td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
		break;

	case ERESTART:
		/*
		 * Undo the tpc advancement we have done on syscall
		 * enter, we want to reexecute the system call.
		 */
		td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
		td->td_frame->tf_tnpc -= 4;
		break;

	case EJUSTRETURN:
		break;

	default:
		td->td_frame->tf_out[0] = SV_ABI_ERRNO(td->td_proc, error);
		td->td_frame->tf_tstate |= TSTATE_XCC_C;
		break;
	}
}
Пример #2
0
void
cpu_set_syscall_retval(struct thread *td, int error)
{

	switch (error) {
	case 0:
		td->td_frame->tf_rax = td->td_retval[0];
		td->td_frame->tf_rdx = td->td_retval[1];
		td->td_frame->tf_rflags &= ~PSL_C;
		break;

	case ERESTART:
		/*
		 * Reconstruct pc, we know that 'syscall' is 2 bytes,
		 * lcall $X,y is 7 bytes, int 0x80 is 2 bytes.
		 * We saved this in tf_err.
		 * %r10 (which was holding the value of %rcx) is restored
		 * for the next iteration.
		 * %r10 restore is only required for freebsd/amd64 processes,
		 * but shall be innocent for any ia32 ABI.
		 *
		 * Require full context restore to get the arguments
		 * in the registers reloaded at return to usermode.
		 */
		td->td_frame->tf_rip -= td->td_frame->tf_err;
		td->td_frame->tf_r10 = td->td_frame->tf_rcx;
		set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
		break;

	case EJUSTRETURN:
		break;

	default:
		td->td_frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
		td->td_frame->tf_rflags |= PSL_C;
		break;
	}
}
Пример #3
0
void
cpu_set_syscall_retval(struct thread *td, int error)
{
	struct trapframe *frame;

	frame = td->td_frame;

	switch (error) {
	case 0:
		frame->tf_x[0] = td->td_retval[0];
		frame->tf_x[1] = td->td_retval[1];
		frame->tf_spsr &= ~PSR_C;	/* carry bit */
		break;
	case ERESTART:
		frame->tf_elr -= 4;
		break;
	case EJUSTRETURN:
		break;
	default:
		frame->tf_spsr |= PSR_C;	/* carry bit */
		frame->tf_x[0] = SV_ABI_ERRNO(td->td_proc, error);
		break;
	}
}