mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
gVisor: Turn arch.Context interface references to struct pointers.
Since `arch.Context64` is the only concrete implementation of `arch.Context`, this does not functionally change anything. While `arch.Context64` *can* mean multiple things in the codebase, since the `arch` module uses conditional compilation to create different builds for AMD64 vs ARM64, the `Context64` type is still singular within each possible version this can compile to. This avoids the overhead involved in calling interface functions in Go: https://github.com/teh-cmc/go-internals/blob/master/chapter2_interfaces/README.md#dynamic-dispatch This overhead is particularly painful for functions like `SyscallSaveOrig` which is a no-op on AMD64. On KVM, this reduces syscall latency by 4~5%: ``` name old wall_ns/op new wall_ns/op delta Getpid 602 ± 4% 579 ± 3% -3.94% (p=0.000 n=66+195) GetpidOpt 604 ± 3% 573 ± 3% -5.10% (p=0.000 n=71+194) name old cpu_ns/op new cpu_ns/op delta Getpid 604 ± 5% 581 ± 0% -3.81% (p=0.000 n=75+130) GetpidOpt 604 ± 2% 574 ± 3% -4.95% (p=0.000 n=71+196) ``` PiperOrigin-RevId: 461742893
This commit is contained in:
committed by
gVisor bot
parent
cb935d7512
commit
93ea5d17be
+14
-3
@@ -50,14 +50,22 @@ func (a Arch) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides architecture-dependent information for a specific thread.
|
||||
// contextInterface provides architecture-dependent information for a thread.
|
||||
// This is currently not referenced, because there exists only one concrete
|
||||
// implementation of this interface (*Context64), which we reference directly
|
||||
// wherever this interface could otherwise be used in order to avoid the
|
||||
// overhead involved in calling functions on interfaces in Go.
|
||||
// This interface is still useful in order to see the entire
|
||||
// architecture-dependent call surface it must support, as this is difficult
|
||||
// to follow across the rest of this module due to the conditional compilation
|
||||
// of the files that make it up.
|
||||
//
|
||||
// NOTE(b/34169503): Currently we use uintptr here to refer to a generic native
|
||||
// register value. While this will work for the foreseeable future, it isn't
|
||||
// strictly correct. We may want to create some abstraction that makes this
|
||||
// more clear or enables us to store values of arbitrary widths. This is
|
||||
// particularly true for RegisterMap().
|
||||
type Context interface {
|
||||
type contextInterface interface {
|
||||
// Arch returns the architecture for this Context.
|
||||
Arch() Arch
|
||||
|
||||
@@ -78,7 +86,7 @@ type Context interface {
|
||||
Width() uint
|
||||
|
||||
// Fork creates a clone of the context.
|
||||
Fork() Context
|
||||
Fork() *Context64
|
||||
|
||||
// SyscallNo returns the syscall number.
|
||||
SyscallNo() uintptr
|
||||
@@ -228,6 +236,9 @@ type Context interface {
|
||||
FullRestore() bool
|
||||
}
|
||||
|
||||
// Compile-time assertion that Context64 implements contextInterface.
|
||||
var _ = (contextInterface)((*Context64)(nil))
|
||||
|
||||
// MmapDirection is a search direction for mmaps.
|
||||
type MmapDirection int
|
||||
|
||||
|
||||
@@ -251,10 +251,10 @@ func (s *State) FullRestore() bool {
|
||||
}
|
||||
|
||||
// New returns a new architecture context.
|
||||
func New(arch Arch) Context {
|
||||
func New(arch Arch) *Context64 {
|
||||
switch arch {
|
||||
case ARM64:
|
||||
return &context64{
|
||||
return &Context64{
|
||||
State{
|
||||
fpState: fpu.NewState(),
|
||||
},
|
||||
|
||||
@@ -101,66 +101,67 @@ const (
|
||||
minMmapRand64 = (1 << 26) * hostarch.PageSize
|
||||
)
|
||||
|
||||
// context64 represents an AMD64 context.
|
||||
// Context64 represents an AMD64 context.
|
||||
//
|
||||
// +stateify savable
|
||||
type context64 struct {
|
||||
type Context64 struct {
|
||||
State
|
||||
}
|
||||
|
||||
// Arch implements Context.Arch.
|
||||
func (c *context64) Arch() Arch {
|
||||
func (c *Context64) Arch() Arch {
|
||||
return AMD64
|
||||
}
|
||||
|
||||
func (c *context64) FloatingPointData() *fpu.State {
|
||||
// FloatingPointData returns the state of the floating-point unit.
|
||||
func (c *Context64) FloatingPointData() *fpu.State {
|
||||
return &c.State.fpState
|
||||
}
|
||||
|
||||
// Fork returns an exact copy of this context.
|
||||
func (c *context64) Fork() Context {
|
||||
return &context64{
|
||||
func (c *Context64) Fork() *Context64 {
|
||||
return &Context64{
|
||||
State: c.State.Fork(),
|
||||
}
|
||||
}
|
||||
|
||||
// Return returns the current syscall return value.
|
||||
func (c *context64) Return() uintptr {
|
||||
func (c *Context64) Return() uintptr {
|
||||
return uintptr(c.Regs.Rax)
|
||||
}
|
||||
|
||||
// SetReturn sets the syscall return value.
|
||||
func (c *context64) SetReturn(value uintptr) {
|
||||
func (c *Context64) SetReturn(value uintptr) {
|
||||
c.Regs.Rax = uint64(value)
|
||||
}
|
||||
|
||||
// IP returns the current instruction pointer.
|
||||
func (c *context64) IP() uintptr {
|
||||
func (c *Context64) IP() uintptr {
|
||||
return uintptr(c.Regs.Rip)
|
||||
}
|
||||
|
||||
// SetIP sets the current instruction pointer.
|
||||
func (c *context64) SetIP(value uintptr) {
|
||||
func (c *Context64) SetIP(value uintptr) {
|
||||
c.Regs.Rip = uint64(value)
|
||||
}
|
||||
|
||||
// Stack returns the current stack pointer.
|
||||
func (c *context64) Stack() uintptr {
|
||||
func (c *Context64) Stack() uintptr {
|
||||
return uintptr(c.Regs.Rsp)
|
||||
}
|
||||
|
||||
// SetStack sets the current stack pointer.
|
||||
func (c *context64) SetStack(value uintptr) {
|
||||
func (c *Context64) SetStack(value uintptr) {
|
||||
c.Regs.Rsp = uint64(value)
|
||||
}
|
||||
|
||||
// TLS returns the current TLS pointer.
|
||||
func (c *context64) TLS() uintptr {
|
||||
func (c *Context64) TLS() uintptr {
|
||||
return uintptr(c.Regs.Fs_base)
|
||||
}
|
||||
|
||||
// SetTLS sets the current TLS pointer. Returns false if value is invalid.
|
||||
func (c *context64) SetTLS(value uintptr) bool {
|
||||
func (c *Context64) SetTLS(value uintptr) bool {
|
||||
if !isValidSegmentBase(uint64(value)) {
|
||||
return false
|
||||
}
|
||||
@@ -171,23 +172,23 @@ func (c *context64) SetTLS(value uintptr) bool {
|
||||
}
|
||||
|
||||
// SetOldRSeqInterruptedIP implements Context.SetOldRSeqInterruptedIP.
|
||||
func (c *context64) SetOldRSeqInterruptedIP(value uintptr) {
|
||||
func (c *Context64) SetOldRSeqInterruptedIP(value uintptr) {
|
||||
c.Regs.R10 = uint64(value)
|
||||
}
|
||||
|
||||
// Native returns the native type for the given val.
|
||||
func (c *context64) Native(val uintptr) marshal.Marshallable {
|
||||
func (c *Context64) Native(val uintptr) marshal.Marshallable {
|
||||
v := primitive.Uint64(val)
|
||||
return &v
|
||||
}
|
||||
|
||||
// Value returns the generic val for the given native type.
|
||||
func (c *context64) Value(val marshal.Marshallable) uintptr {
|
||||
func (c *Context64) Value(val marshal.Marshallable) uintptr {
|
||||
return uintptr(*val.(*primitive.Uint64))
|
||||
}
|
||||
|
||||
// Width returns the byte width of this architecture.
|
||||
func (c *context64) Width() uint {
|
||||
func (c *Context64) Width() uint {
|
||||
return 8
|
||||
}
|
||||
|
||||
@@ -197,7 +198,7 @@ func mmapRand(max uint64) hostarch.Addr {
|
||||
}
|
||||
|
||||
// NewMmapLayout implements Context.NewMmapLayout consistently with Linux.
|
||||
func (c *context64) NewMmapLayout(min, max hostarch.Addr, r *limits.LimitSet) (MmapLayout, error) {
|
||||
func (c *Context64) NewMmapLayout(min, max hostarch.Addr, r *limits.LimitSet) (MmapLayout, error) {
|
||||
min, ok := min.RoundUp()
|
||||
if !ok {
|
||||
return MmapLayout{}, unix.EINVAL
|
||||
@@ -263,7 +264,7 @@ func (c *context64) NewMmapLayout(min, max hostarch.Addr, r *limits.LimitSet) (M
|
||||
}
|
||||
|
||||
// PIELoadAddress implements Context.PIELoadAddress.
|
||||
func (c *context64) PIELoadAddress(l MmapLayout) hostarch.Addr {
|
||||
func (c *Context64) PIELoadAddress(l MmapLayout) hostarch.Addr {
|
||||
base := preferredPIELoadAddr
|
||||
max, ok := base.AddLength(maxMmapRand64)
|
||||
if !ok {
|
||||
@@ -285,7 +286,7 @@ func (c *context64) PIELoadAddress(l MmapLayout) hostarch.Addr {
|
||||
const userStructSize = 928
|
||||
|
||||
// PtracePeekUser implements Context.PtracePeekUser.
|
||||
func (c *context64) PtracePeekUser(addr uintptr) (marshal.Marshallable, error) {
|
||||
func (c *Context64) PtracePeekUser(addr uintptr) (marshal.Marshallable, error) {
|
||||
if addr&7 != 0 || addr >= userStructSize {
|
||||
return nil, unix.EIO
|
||||
}
|
||||
@@ -303,7 +304,7 @@ func (c *context64) PtracePeekUser(addr uintptr) (marshal.Marshallable, error) {
|
||||
}
|
||||
|
||||
// PtracePokeUser implements Context.PtracePokeUser.
|
||||
func (c *context64) PtracePokeUser(addr, data uintptr) error {
|
||||
func (c *Context64) PtracePokeUser(addr, data uintptr) error {
|
||||
if addr&7 != 0 || addr >= userStructSize {
|
||||
return unix.EIO
|
||||
}
|
||||
|
||||
@@ -75,20 +75,20 @@ const (
|
||||
minMmapRand64 = (1 << 18) * hostarch.PageSize
|
||||
)
|
||||
|
||||
// context64 represents an ARM64 context.
|
||||
// Context64 represents an ARM64 context.
|
||||
//
|
||||
// +stateify savable
|
||||
type context64 struct {
|
||||
type Context64 struct {
|
||||
State
|
||||
sigFPState []fpu.State // fpstate to be restored on sigreturn.
|
||||
}
|
||||
|
||||
// Arch implements Context.Arch.
|
||||
func (c *context64) Arch() Arch {
|
||||
func (c *Context64) Arch() Arch {
|
||||
return ARM64
|
||||
}
|
||||
|
||||
func (c *context64) copySigFPState() []fpu.State {
|
||||
func (c *Context64) copySigFPState() []fpu.State {
|
||||
var sigfps []fpu.State
|
||||
for _, s := range c.sigFPState {
|
||||
sigfps = append(sigfps, s.Fork())
|
||||
@@ -97,8 +97,8 @@ func (c *context64) copySigFPState() []fpu.State {
|
||||
}
|
||||
|
||||
// Fork returns an exact copy of this context.
|
||||
func (c *context64) Fork() Context {
|
||||
return &context64{
|
||||
func (c *Context64) Fork() *Context64 {
|
||||
return &Context64{
|
||||
State: c.State.Fork(),
|
||||
sigFPState: c.copySigFPState(),
|
||||
}
|
||||
@@ -116,42 +116,42 @@ func (c *context64) Fork() Context {
|
||||
// R30: the link register.
|
||||
|
||||
// Return returns the current syscall return value.
|
||||
func (c *context64) Return() uintptr {
|
||||
func (c *Context64) Return() uintptr {
|
||||
return uintptr(c.Regs.Regs[0])
|
||||
}
|
||||
|
||||
// SetReturn sets the syscall return value.
|
||||
func (c *context64) SetReturn(value uintptr) {
|
||||
func (c *Context64) SetReturn(value uintptr) {
|
||||
c.Regs.Regs[0] = uint64(value)
|
||||
}
|
||||
|
||||
// IP returns the current instruction pointer.
|
||||
func (c *context64) IP() uintptr {
|
||||
func (c *Context64) IP() uintptr {
|
||||
return uintptr(c.Regs.Pc)
|
||||
}
|
||||
|
||||
// SetIP sets the current instruction pointer.
|
||||
func (c *context64) SetIP(value uintptr) {
|
||||
func (c *Context64) SetIP(value uintptr) {
|
||||
c.Regs.Pc = uint64(value)
|
||||
}
|
||||
|
||||
// Stack returns the current stack pointer.
|
||||
func (c *context64) Stack() uintptr {
|
||||
func (c *Context64) Stack() uintptr {
|
||||
return uintptr(c.Regs.Sp)
|
||||
}
|
||||
|
||||
// SetStack sets the current stack pointer.
|
||||
func (c *context64) SetStack(value uintptr) {
|
||||
func (c *Context64) SetStack(value uintptr) {
|
||||
c.Regs.Sp = uint64(value)
|
||||
}
|
||||
|
||||
// TLS returns the current TLS pointer.
|
||||
func (c *context64) TLS() uintptr {
|
||||
func (c *Context64) TLS() uintptr {
|
||||
return uintptr(c.Regs.TPIDR_EL0)
|
||||
}
|
||||
|
||||
// SetTLS sets the current TLS pointer. Returns false if value is invalid.
|
||||
func (c *context64) SetTLS(value uintptr) bool {
|
||||
func (c *Context64) SetTLS(value uintptr) bool {
|
||||
if value >= uintptr(maxAddr64) {
|
||||
return false
|
||||
}
|
||||
@@ -161,23 +161,23 @@ func (c *context64) SetTLS(value uintptr) bool {
|
||||
}
|
||||
|
||||
// SetOldRSeqInterruptedIP implements Context.SetOldRSeqInterruptedIP.
|
||||
func (c *context64) SetOldRSeqInterruptedIP(value uintptr) {
|
||||
func (c *Context64) SetOldRSeqInterruptedIP(value uintptr) {
|
||||
c.Regs.Regs[3] = uint64(value)
|
||||
}
|
||||
|
||||
// Native returns the native type for the given val.
|
||||
func (c *context64) Native(val uintptr) marshal.Marshallable {
|
||||
func (c *Context64) Native(val uintptr) marshal.Marshallable {
|
||||
v := primitive.Uint64(val)
|
||||
return &v
|
||||
}
|
||||
|
||||
// Value returns the generic val for the given native type.
|
||||
func (c *context64) Value(val marshal.Marshallable) uintptr {
|
||||
func (c *Context64) Value(val marshal.Marshallable) uintptr {
|
||||
return uintptr(*val.(*primitive.Uint64))
|
||||
}
|
||||
|
||||
// Width returns the byte width of this architecture.
|
||||
func (c *context64) Width() uint {
|
||||
func (c *Context64) Width() uint {
|
||||
return 8
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ func mmapRand(max uint64) hostarch.Addr {
|
||||
}
|
||||
|
||||
// NewMmapLayout implements Context.NewMmapLayout consistently with Linux.
|
||||
func (c *context64) NewMmapLayout(min, max hostarch.Addr, r *limits.LimitSet) (MmapLayout, error) {
|
||||
func (c *Context64) NewMmapLayout(min, max hostarch.Addr, r *limits.LimitSet) (MmapLayout, error) {
|
||||
min, ok := min.RoundUp()
|
||||
if !ok {
|
||||
return MmapLayout{}, unix.EINVAL
|
||||
@@ -253,7 +253,7 @@ func (c *context64) NewMmapLayout(min, max hostarch.Addr, r *limits.LimitSet) (M
|
||||
}
|
||||
|
||||
// PIELoadAddress implements Context.PIELoadAddress.
|
||||
func (c *context64) PIELoadAddress(l MmapLayout) hostarch.Addr {
|
||||
func (c *Context64) PIELoadAddress(l MmapLayout) hostarch.Addr {
|
||||
base := preferredPIELoadAddr
|
||||
max, ok := base.AddLength(maxMmapRand64)
|
||||
if !ok {
|
||||
@@ -272,17 +272,18 @@ func (c *context64) PIELoadAddress(l MmapLayout) hostarch.Addr {
|
||||
}
|
||||
|
||||
// PtracePeekUser implements Context.PtracePeekUser.
|
||||
func (c *context64) PtracePeekUser(addr uintptr) (marshal.Marshallable, error) {
|
||||
func (c *Context64) PtracePeekUser(addr uintptr) (marshal.Marshallable, error) {
|
||||
// TODO(gvisor.dev/issue/1239): Full ptrace supporting for Arm64.
|
||||
return c.Native(0), nil
|
||||
}
|
||||
|
||||
// PtracePokeUser implements Context.PtracePokeUser.
|
||||
func (c *context64) PtracePokeUser(addr, data uintptr) error {
|
||||
func (c *Context64) PtracePokeUser(addr, data uintptr) error {
|
||||
// TODO(gvisor.dev/issue/1239): Full ptrace supporting for Arm64.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context64) FloatingPointData() *fpu.State {
|
||||
// FloatingPointData returns the state of the floating-point unit.
|
||||
func (c *Context64) FloatingPointData() *fpu.State {
|
||||
return &c.State.fpState
|
||||
}
|
||||
|
||||
@@ -390,10 +390,10 @@ func (s *State) FullRestore() bool {
|
||||
}
|
||||
|
||||
// New returns a new architecture context.
|
||||
func New(arch Arch) Context {
|
||||
func New(arch Arch) *Context64 {
|
||||
switch arch {
|
||||
case AMD64:
|
||||
return &context64{
|
||||
return &Context64{
|
||||
State{
|
||||
fpState: fpu.NewState(),
|
||||
},
|
||||
|
||||
@@ -114,7 +114,7 @@ const (
|
||||
|
||||
// SignalSetup implements Context.SignalSetup. (Compare to Linux's
|
||||
// arch/x86/kernel/signal.c:__setup_rt_frame().)
|
||||
func (c *context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.SignalInfo, alt *linux.SignalStack, sigset linux.SignalSet, featureSet cpuid.FeatureSet) error {
|
||||
func (c *Context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.SignalInfo, alt *linux.SignalStack, sigset linux.SignalSet, featureSet cpuid.FeatureSet) error {
|
||||
// "The 128-byte area beyond the location pointed to by %rsp is considered
|
||||
// to be reserved and shall not be modified by signal or interrupt
|
||||
// handlers. ... leaf functions may use this area for their entire stack
|
||||
@@ -265,7 +265,7 @@ func (c *context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.Sig
|
||||
|
||||
// SignalRestore implements Context.SignalRestore. (Compare to Linux's
|
||||
// arch/x86/kernel/signal.c:sys_rt_sigreturn().)
|
||||
func (c *context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSet) (linux.SignalSet, linux.SignalStack, error) {
|
||||
func (c *Context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSet) (linux.SignalSet, linux.SignalStack, error) {
|
||||
// Copy out the stack frame.
|
||||
var uc UContext64
|
||||
if _, err := uc.CopyIn(st, StackBottomMagic); err != nil {
|
||||
|
||||
@@ -74,7 +74,7 @@ type UContext64 struct {
|
||||
}
|
||||
|
||||
// SignalSetup implements Context.SignalSetup.
|
||||
func (c *context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.SignalInfo, alt *linux.SignalStack, sigset linux.SignalSet, featureSet cpuid.FeatureSet) error {
|
||||
func (c *Context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.SignalInfo, alt *linux.SignalStack, sigset linux.SignalSet, featureSet cpuid.FeatureSet) error {
|
||||
sp := st.Bottom
|
||||
|
||||
// Construct the UContext64 now since we need its size.
|
||||
@@ -139,7 +139,7 @@ func (c *context64) SignalSetup(st *Stack, act *linux.SigAction, info *linux.Sig
|
||||
}
|
||||
|
||||
// SignalRestore implements Context.SignalRestore.
|
||||
func (c *context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSet) (linux.SignalSet, linux.SignalStack, error) {
|
||||
func (c *Context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSet) (linux.SignalSet, linux.SignalStack, error) {
|
||||
// Copy out the stack frame.
|
||||
var uc UContext64
|
||||
if _, err := uc.CopyIn(st, StackBottomMagic); err != nil {
|
||||
|
||||
@@ -31,7 +31,7 @@ type Stack struct {
|
||||
// Our arch info.
|
||||
// We use this for automatic Native conversion of hostarch.Addrs during
|
||||
// Push() and Pop().
|
||||
Arch Context
|
||||
Arch *Context64
|
||||
|
||||
// The interface used to actually copy user memory.
|
||||
IO usermem.IO
|
||||
|
||||
@@ -23,11 +23,11 @@ const restartSyscallNr = uintptr(219)
|
||||
// syscall handler(doSyscall()).
|
||||
//
|
||||
// Noop on x86.
|
||||
func (c *context64) SyscallSaveOrig() {
|
||||
func (c *Context64) SyscallSaveOrig() {
|
||||
}
|
||||
|
||||
// SyscallNo returns the syscall number according to the 64-bit convention.
|
||||
func (c *context64) SyscallNo() uintptr {
|
||||
func (c *Context64) SyscallNo() uintptr {
|
||||
return uintptr(c.Regs.Orig_rax)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (c *context64) SyscallNo() uintptr {
|
||||
// Due to the way addresses are mapped for the sentry this binary *must* be
|
||||
// built in 64-bit mode. So we can just assume the syscall numbers that come
|
||||
// back match the expected host system call numbers.
|
||||
func (c *context64) SyscallArgs() SyscallArguments {
|
||||
func (c *Context64) SyscallArgs() SyscallArguments {
|
||||
return SyscallArguments{
|
||||
SyscallArgument{Value: uintptr(c.Regs.Rdi)},
|
||||
SyscallArgument{Value: uintptr(c.Regs.Rsi)},
|
||||
@@ -48,13 +48,13 @@ func (c *context64) SyscallArgs() SyscallArguments {
|
||||
}
|
||||
|
||||
// RestartSyscall implements Context.RestartSyscall.
|
||||
func (c *context64) RestartSyscall() {
|
||||
func (c *Context64) RestartSyscall() {
|
||||
c.Regs.Rip -= SyscallWidth
|
||||
c.Regs.Rax = c.Regs.Orig_rax
|
||||
}
|
||||
|
||||
// RestartSyscallWithRestartBlock implements Context.RestartSyscallWithRestartBlock.
|
||||
func (c *context64) RestartSyscallWithRestartBlock() {
|
||||
func (c *Context64) RestartSyscallWithRestartBlock() {
|
||||
c.Regs.Rip -= SyscallWidth
|
||||
c.Regs.Rax = uint64(restartSyscallNr)
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ const restartSyscallNr = uintptr(128)
|
||||
// is saved to the pt_regs.orig_x0 in kernel code. But currently, the orig_x0
|
||||
// was not accessible to the userspace application, so we have to do the same
|
||||
// operation in the sentry code to save the R0 value into the App context.
|
||||
func (c *context64) SyscallSaveOrig() {
|
||||
func (c *Context64) SyscallSaveOrig() {
|
||||
c.OrigR0 = c.Regs.Regs[0]
|
||||
}
|
||||
|
||||
// SyscallNo returns the syscall number according to the 64-bit convention.
|
||||
func (c *context64) SyscallNo() uintptr {
|
||||
func (c *Context64) SyscallNo() uintptr {
|
||||
return uintptr(c.Regs.Regs[8])
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func (c *context64) SyscallNo() uintptr {
|
||||
// R19...R28: callee-saved registers.
|
||||
// R29: the frame pointer.
|
||||
// R30: the link register.
|
||||
func (c *context64) SyscallArgs() SyscallArguments {
|
||||
func (c *Context64) SyscallArgs() SyscallArguments {
|
||||
return SyscallArguments{
|
||||
SyscallArgument{Value: uintptr(c.OrigR0)},
|
||||
SyscallArgument{Value: uintptr(c.Regs.Regs[1])},
|
||||
@@ -65,7 +65,7 @@ func (c *context64) SyscallArgs() SyscallArguments {
|
||||
// Prepare for system call restart, OrigR0 will be restored to R0.
|
||||
// Please see the linux code as reference:
|
||||
// arch/arm64/kernel/signal.c:do_signal()
|
||||
func (c *context64) RestartSyscall() {
|
||||
func (c *Context64) RestartSyscall() {
|
||||
c.Regs.Pc -= SyscallWidth
|
||||
// R0 will be backed up into OrigR0 when entering doSyscall().
|
||||
// Please see the linux code as reference:
|
||||
@@ -75,7 +75,7 @@ func (c *context64) RestartSyscall() {
|
||||
}
|
||||
|
||||
// RestartSyscallWithRestartBlock implements Context.RestartSyscallWithRestartBlock.
|
||||
func (c *context64) RestartSyscallWithRestartBlock() {
|
||||
func (c *Context64) RestartSyscallWithRestartBlock() {
|
||||
c.Regs.Pc -= SyscallWidth
|
||||
c.Regs.Regs[0] = uint64(c.OrigR0)
|
||||
c.Regs.Regs[8] = uint64(restartSyscallNr)
|
||||
|
||||
Reference in New Issue
Block a user