// doVsyscall is the entry point for a vsyscall invocation of syscall sysno, as
// indicated by an execution fault at address addr. doVsyscall returns the
// task's next run state.
doVsyscall is the entry point for a vsyscall invocation of syscall sysno, as
indicated by an execution fault at address addr. doVsyscall returns the
task's next run state.
// doVsyscall is the entry point for a vsyscall invocation of syscall sysno as // indicated by an execution fault at address addr . doVsyscall returns the // task ' s next run state .
func (t *Task) doVsyscall(addr hostarch.Addr, sysno uintptr) taskRunState {
	metric.WeirdnessMetric.Increment("vsyscall_count")
	caller := t.Arch().Native(uintptr(0))
	if _, err := caller.CopyIn(t, hostarch.Addr(t.Arch().Stack())); err != nil {
		t.Debugf("vsyscall %d: error reading return address from stack: %v", sysno, err)
		t.forceSignal(linux.SIGSEGV, false )
		t.SendSignal(SignalInfoPriv(linux.SIGSEGV))
		return (*runApp)(nil)
	}
	args := t.Arch().SyscallArgs()
	if t.syscallFilters.Load() != nil {
		switch r := t.checkSeccompSyscall(int32(sysno), args, addr); r {
		case linux.SECCOMP_RET_ERRNO, linux.SECCOMP_RET_TRAP:
			t.Debugf("vsyscall %d, caller %x: denied by seccomp", sysno, t.Arch().Value(caller))
			return (*runApp)(nil)
		case linux.SECCOMP_RET_ALLOW:
		case linux.SECCOMP_RET_TRACE:
			t.Debugf("vsyscall %d, caller %x: stopping for PTRACE_EVENT_SECCOMP", sysno, t.Arch().Value(caller))
			return &runVsyscallAfterPtraceEventSeccomp{addr, sysno, caller}
		case linux.SECCOMP_RET_KILL_THREAD:
			t.Debugf("vsyscall %d: killed by seccomp", sysno)
			t.PrepareExit(ExitStatus{Signo: int(linux.SIGSYS)})
			return (*runExit)(nil)
		default:
			panic(fmt.Sprintf("Unknown seccomp result %d", r))
		}
	}
	return t.doVsyscallInvoke(sysno, args, caller)
}
func ( t * Task ) doVsyscall ( addr hostarch . Addr , sysno uintptr ) taskRunState { metric . WeirdnessMetric . Increment ( " " ) caller := t . Arch ( ) . Native ( uintptr ( 0 ) ) if _ , err := caller . CopyIn ( t , hostarch . Addr ( t . Arch ( ) . Stack ( ) ) ) ; err != nil { t . Debugf ( " " , sysno , err ) t . forceSignal ( linux . SIGSEGV , false ) t . SendSignal ( SignalInfoPriv ( linux . SIGSEGV ) ) return ( * runApp ) ( nil ) } args := t . Arch ( ) . SyscallArgs ( ) if t . syscallFilters . Load ( ) != nil { switch r := t . checkSeccompSyscall ( int32 ( sysno ) , args , addr ) ; r { case linux . SECCOMP_RET_ERRNO , linux . SECCOMP_RET_TRAP : t . Debugf ( " " , sysno , t . Arch ( ) . Value ( caller ) ) return ( * runApp ) ( nil ) case linux . SECCOMP_RET_ALLOW : case linux . SECCOMP_RET_TRACE : t . Debugf ( " " , sysno , t . Arch ( ) . Value ( caller ) ) return & runVsyscallAfterPtraceEventSeccomp { addr , sysno , caller } case linux . SECCOMP_RET_KILL_THREAD : t . Debugf ( " " , sysno ) t . PrepareExit ( ExitStatus { Signo : int ( linux . SIGSYS ) } ) return ( * runExit ) ( nil ) default : panic ( fmt . Sprintf ( " " , r ) ) } } return t . doVsyscallInvoke ( sysno , args , caller ) }
doVsyscall is the entry point for a vsyscall invocation of syscall sysno, as
indicated by an execution fault at address addr.
doVsyscall is the entry point for a vsyscall invocation of syscall sysno as indicated by an execution fault at address addr .
// Grab the caller up front, to make sure there's a sensible stack. /* unconditional */ // For _vsyscalls_, there is no need to translate System V calling convention // to syscall ABI because they both use RDI, RSI, and RDX for the first three // arguments and none of the vsyscalls uses more than two arguments. // ok