diff options
Diffstat (limited to 'pkg/abi/linux')
-rw-r--r-- | pkg/abi/linux/BUILD | 81 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/epoll_amd64.go | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/epoll_arm64.go | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/file_amd64.go | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/file_arm64.go | 0 | ||||
-rwxr-xr-x | pkg/abi/linux/linux_abi_autogen_unsafe.go | 240 | ||||
-rwxr-xr-x | pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go | 215 | ||||
-rwxr-xr-x | pkg/abi/linux/linux_amd64_state_autogen.go | 5 | ||||
-rwxr-xr-x | pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go | 219 | ||||
-rwxr-xr-x | pkg/abi/linux/linux_arm64_state_autogen.go | 5 | ||||
-rwxr-xr-x | pkg/abi/linux/linux_state_autogen.go | 68 | ||||
-rw-r--r-- | pkg/abi/linux/netfilter_test.go | 45 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/rseq.go | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/signalfd.go | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | pkg/abi/linux/xattr.go | 0 |
15 files changed, 752 insertions, 126 deletions
diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD deleted file mode 100644 index a89f34d4b..000000000 --- a/pkg/abi/linux/BUILD +++ /dev/null @@ -1,81 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -# Package linux contains the constants and types needed to interface with a -# Linux kernel. It should be used instead of syscall or golang.org/x/sys/unix -# when the host OS may not be Linux. - -package(licenses = ["notice"]) - -go_library( - name = "linux", - srcs = [ - "aio.go", - "audit.go", - "bpf.go", - "capability.go", - "clone.go", - "dev.go", - "elf.go", - "epoll.go", - "epoll_amd64.go", - "epoll_arm64.go", - "errors.go", - "eventfd.go", - "exec.go", - "fcntl.go", - "file.go", - "file_amd64.go", - "file_arm64.go", - "fs.go", - "futex.go", - "inotify.go", - "ioctl.go", - "ip.go", - "ipc.go", - "limits.go", - "linux.go", - "mm.go", - "netdevice.go", - "netfilter.go", - "netlink.go", - "netlink_route.go", - "poll.go", - "prctl.go", - "ptrace.go", - "rseq.go", - "rusage.go", - "sched.go", - "seccomp.go", - "sem.go", - "shm.go", - "signal.go", - "signalfd.go", - "socket.go", - "splice.go", - "tcp.go", - "time.go", - "timer.go", - "tty.go", - "uio.go", - "utsname.go", - "wait.go", - "xattr.go", - ], - marshal = True, - visibility = ["//visibility:public"], - deps = [ - "//pkg/abi", - "//pkg/binary", - "//pkg/bits", - ], -) - -go_test( - name = "linux_test", - size = "small", - srcs = ["netfilter_test.go"], - library = ":linux", - deps = [ - "//pkg/binary", - ], -) diff --git a/pkg/abi/linux/epoll_amd64.go b/pkg/abi/linux/epoll_amd64.go index 57041491c..57041491c 100644..100755 --- a/pkg/abi/linux/epoll_amd64.go +++ b/pkg/abi/linux/epoll_amd64.go diff --git a/pkg/abi/linux/epoll_arm64.go b/pkg/abi/linux/epoll_arm64.go index 62ef5821e..62ef5821e 100644..100755 --- a/pkg/abi/linux/epoll_arm64.go +++ b/pkg/abi/linux/epoll_arm64.go diff --git a/pkg/abi/linux/file_amd64.go b/pkg/abi/linux/file_amd64.go index 6b72364ea..6b72364ea 100644..100755 --- a/pkg/abi/linux/file_amd64.go +++ b/pkg/abi/linux/file_amd64.go diff --git a/pkg/abi/linux/file_arm64.go b/pkg/abi/linux/file_arm64.go index 6492c9038..6492c9038 100644..100755 --- a/pkg/abi/linux/file_arm64.go +++ b/pkg/abi/linux/file_arm64.go diff --git a/pkg/abi/linux/linux_abi_autogen_unsafe.go b/pkg/abi/linux/linux_abi_autogen_unsafe.go new file mode 100755 index 000000000..59290f5a0 --- /dev/null +++ b/pkg/abi/linux/linux_abi_autogen_unsafe.go @@ -0,0 +1,240 @@ +// Automatically generated marshal implementation. See tools/go_marshal. + +package linux + +import ( + "gvisor.dev/gvisor/pkg/safecopy" + "gvisor.dev/gvisor/pkg/usermem" + "gvisor.dev/gvisor/tools/go_marshal/marshal" + "io" + "reflect" + "runtime" + "unsafe" +) + +// Marshallable types used by this file. +var _ marshal.Marshallable = (*RSeqCriticalSection)(nil) +var _ marshal.Marshallable = (*Timespec)(nil) + +// SizeBytes implements marshal.Marshallable.SizeBytes. +func (r *RSeqCriticalSection) SizeBytes() int { + return 32 +} + +// MarshalBytes implements marshal.Marshallable.MarshalBytes. +func (r *RSeqCriticalSection) MarshalBytes(dst []byte) { + usermem.ByteOrder.PutUint32(dst[:4], uint32(r.Version)) + dst = dst[4:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(r.Flags)) + dst = dst[4:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(r.Start)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(r.PostCommitOffset)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(r.Abort)) + dst = dst[8:] +} + +// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. +func (r *RSeqCriticalSection) UnmarshalBytes(src []byte) { + r.Version = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + r.Flags = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + r.Start = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + r.PostCommitOffset = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + r.Abort = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] +} + +// Packed implements marshal.Marshallable.Packed. +func (r *RSeqCriticalSection) Packed() bool { + return true +} + +// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe. +func (r *RSeqCriticalSection) MarshalUnsafe(dst []byte) { + safecopy.CopyIn(dst, unsafe.Pointer(r)) +} + +// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe. +func (r *RSeqCriticalSection) UnmarshalUnsafe(src []byte) { + safecopy.CopyOut(unsafe.Pointer(r), src) +} + +// CopyOut implements marshal.Marshallable.CopyOut. +func (r *RSeqCriticalSection) CopyOut(task marshal.Task, addr usermem.Addr) error { + // Bypass escape analysis on r. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on r. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(r) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by r's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = r.SizeBytes() + hdr.Cap = r.SizeBytes() + + _, err := task.CopyOutBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that r + // must live until after the CopyOutBytes. + runtime.KeepAlive(r) + return err +} + +// CopyIn implements marshal.Marshallable.CopyIn. +func (r *RSeqCriticalSection) CopyIn(task marshal.Task, addr usermem.Addr) error { + // Bypass escape analysis on r. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on r. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(r) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by r's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = r.SizeBytes() + hdr.Cap = r.SizeBytes() + + _, err := task.CopyInBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that r + // must live until after the CopyInBytes. + runtime.KeepAlive(r) + return err +} + +// WriteTo implements io.WriterTo.WriteTo. +func (r *RSeqCriticalSection) WriteTo(w io.Writer) (int64, error) { + // Bypass escape analysis on r. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on r. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(r) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by r's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = r.SizeBytes() + hdr.Cap = r.SizeBytes() + + len, err := w.Write(buf) + // Since we bypassed the compiler's escape analysis, indicate that r + // must live until after the Write. + runtime.KeepAlive(r) + return int64(len), err +} + +// SizeBytes implements marshal.Marshallable.SizeBytes. +func (t *Timespec) SizeBytes() int { + return 16 +} + +// MarshalBytes implements marshal.Marshallable.MarshalBytes. +func (t *Timespec) MarshalBytes(dst []byte) { + usermem.ByteOrder.PutUint64(dst[:8], uint64(t.Sec)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(t.Nsec)) + dst = dst[8:] +} + +// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. +func (t *Timespec) UnmarshalBytes(src []byte) { + t.Sec = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + t.Nsec = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] +} + +// Packed implements marshal.Marshallable.Packed. +func (t *Timespec) Packed() bool { + return true +} + +// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe. +func (t *Timespec) MarshalUnsafe(dst []byte) { + safecopy.CopyIn(dst, unsafe.Pointer(t)) +} + +// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe. +func (t *Timespec) UnmarshalUnsafe(src []byte) { + safecopy.CopyOut(unsafe.Pointer(t), src) +} + +// CopyOut implements marshal.Marshallable.CopyOut. +func (t *Timespec) CopyOut(task marshal.Task, addr usermem.Addr) error { + // Bypass escape analysis on t. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on t. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(t) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by t's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = t.SizeBytes() + hdr.Cap = t.SizeBytes() + + _, err := task.CopyOutBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that t + // must live until after the CopyOutBytes. + runtime.KeepAlive(t) + return err +} + +// CopyIn implements marshal.Marshallable.CopyIn. +func (t *Timespec) CopyIn(task marshal.Task, addr usermem.Addr) error { + // Bypass escape analysis on t. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on t. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(t) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by t's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = t.SizeBytes() + hdr.Cap = t.SizeBytes() + + _, err := task.CopyInBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that t + // must live until after the CopyInBytes. + runtime.KeepAlive(t) + return err +} + +// WriteTo implements io.WriterTo.WriteTo. +func (t *Timespec) WriteTo(w io.Writer) (int64, error) { + // Bypass escape analysis on t. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on t. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(t) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by t's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = t.SizeBytes() + hdr.Cap = t.SizeBytes() + + len, err := w.Write(buf) + // Since we bypassed the compiler's escape analysis, indicate that t + // must live until after the Write. + runtime.KeepAlive(t) + return int64(len), err +} + diff --git a/pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go b/pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go new file mode 100755 index 000000000..6abfea58c --- /dev/null +++ b/pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go @@ -0,0 +1,215 @@ +// Automatically generated marshal implementation. See tools/go_marshal. + +// +build amd64 + +package linux + +import ( + "gvisor.dev/gvisor/pkg/safecopy" + "gvisor.dev/gvisor/pkg/usermem" + "gvisor.dev/gvisor/tools/go_marshal/marshal" + "io" + "reflect" + "runtime" + "unsafe" +) + +// Marshallable types used by this file. +var _ marshal.Marshallable = (*Stat)(nil) +var _ marshal.Marshallable = (*Timespec)(nil) + +// SizeBytes implements marshal.Marshallable.SizeBytes. +func (s *Stat) SizeBytes() int { + return 96 + + (*Timespec)(nil).SizeBytes() + + (*Timespec)(nil).SizeBytes() + + (*Timespec)(nil).SizeBytes() +} + +// MarshalBytes implements marshal.Marshallable.MarshalBytes. +func (s *Stat) MarshalBytes(dst []byte) { + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Dev)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Ino)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Nlink)) + dst = dst[8:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.Mode)) + dst = dst[4:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.UID)) + dst = dst[4:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.GID)) + dst = dst[4:] + // Padding: dst[:sizeof(int32)] ~= int32(0) + dst = dst[4:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Size)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Blksize)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks)) + dst = dst[8:] + s.ATime.MarshalBytes(dst[:s.ATime.SizeBytes()]) + dst = dst[s.ATime.SizeBytes():] + s.MTime.MarshalBytes(dst[:s.MTime.SizeBytes()]) + dst = dst[s.MTime.SizeBytes():] + s.CTime.MarshalBytes(dst[:s.CTime.SizeBytes()]) + dst = dst[s.CTime.SizeBytes():] + // Padding: dst[:sizeof(int64)*3] ~= [3]int64{0} + dst = dst[24:] +} + +// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. +func (s *Stat) UnmarshalBytes(src []byte) { + s.Dev = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Ino = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Nlink = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Mode = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + s.UID = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + s.GID = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + // Padding: var _ int32 ~= src[:sizeof(int32)] + src = src[4:] + s.Rdev = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Size = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Blksize = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Blocks = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.ATime.UnmarshalBytes(src[:s.ATime.SizeBytes()]) + src = src[s.ATime.SizeBytes():] + s.MTime.UnmarshalBytes(src[:s.MTime.SizeBytes()]) + src = src[s.MTime.SizeBytes():] + s.CTime.UnmarshalBytes(src[:s.CTime.SizeBytes()]) + src = src[s.CTime.SizeBytes():] + // Padding: ~ copy([3]int64(s._), src[:sizeof(int64)*3]) + src = src[24:] +} + +// Packed implements marshal.Marshallable.Packed. +func (s *Stat) Packed() bool { + return s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() +} + +// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe. +func (s *Stat) MarshalUnsafe(dst []byte) { + if s.MTime.Packed() && s.CTime.Packed() && s.ATime.Packed() { + safecopy.CopyIn(dst, unsafe.Pointer(s)) + } else { + s.MarshalBytes(dst) + } +} + +// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe. +func (s *Stat) UnmarshalUnsafe(src []byte) { + if s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() { + safecopy.CopyOut(unsafe.Pointer(s), src) + } else { + s.UnmarshalBytes(src) + } +} + +// CopyOut implements marshal.Marshallable.CopyOut. +func (s *Stat) CopyOut(task marshal.Task, addr usermem.Addr) error { + if !s.CTime.Packed() && s.ATime.Packed() && s.MTime.Packed() { + // Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes. + buf := task.CopyScratchBuffer(s.SizeBytes()) + s.MarshalBytes(buf) + _, err := task.CopyOutBytes(addr, buf) + return err + } + + // Bypass escape analysis on s. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on s. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(s) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by s's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = s.SizeBytes() + hdr.Cap = s.SizeBytes() + + _, err := task.CopyOutBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that s + // must live until after the CopyOutBytes. + runtime.KeepAlive(s) + return err +} + +// CopyIn implements marshal.Marshallable.CopyIn. +func (s *Stat) CopyIn(task marshal.Task, addr usermem.Addr) error { + if !s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() { + // Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes. + buf := task.CopyScratchBuffer(s.SizeBytes()) + _, err := task.CopyInBytes(addr, buf) + if err != nil { + return err + } + s.UnmarshalBytes(buf) + return nil + } + + // Bypass escape analysis on s. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on s. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(s) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by s's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = s.SizeBytes() + hdr.Cap = s.SizeBytes() + + _, err := task.CopyInBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that s + // must live until after the CopyInBytes. + runtime.KeepAlive(s) + return err +} + +// WriteTo implements io.WriterTo.WriteTo. +func (s *Stat) WriteTo(w io.Writer) (int64, error) { + if !s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() { + // Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes. + buf := make([]byte, s.SizeBytes()) + s.MarshalBytes(buf) + n, err := w.Write(buf) + return int64(n), err + } + + // Bypass escape analysis on s. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on s. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(s) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by s's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = s.SizeBytes() + hdr.Cap = s.SizeBytes() + + len, err := w.Write(buf) + // Since we bypassed the compiler's escape analysis, indicate that s + // must live until after the Write. + runtime.KeepAlive(s) + return int64(len), err +} + diff --git a/pkg/abi/linux/linux_amd64_state_autogen.go b/pkg/abi/linux/linux_amd64_state_autogen.go new file mode 100755 index 000000000..a5f55a80b --- /dev/null +++ b/pkg/abi/linux/linux_amd64_state_autogen.go @@ -0,0 +1,5 @@ +// automatically generated by stateify. + +// +build amd64 + +package linux diff --git a/pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go b/pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go new file mode 100755 index 000000000..d57e8e48d --- /dev/null +++ b/pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go @@ -0,0 +1,219 @@ +// Automatically generated marshal implementation. See tools/go_marshal. + +// +build arm64 + +package linux + +import ( + "gvisor.dev/gvisor/pkg/safecopy" + "gvisor.dev/gvisor/pkg/usermem" + "gvisor.dev/gvisor/tools/go_marshal/marshal" + "io" + "reflect" + "runtime" + "unsafe" +) + +// Marshallable types used by this file. +var _ marshal.Marshallable = (*Stat)(nil) +var _ marshal.Marshallable = (*Timespec)(nil) + +// SizeBytes implements marshal.Marshallable.SizeBytes. +func (s *Stat) SizeBytes() int { + return 80 + + (*Timespec)(nil).SizeBytes() + + (*Timespec)(nil).SizeBytes() + + (*Timespec)(nil).SizeBytes() +} + +// MarshalBytes implements marshal.Marshallable.MarshalBytes. +func (s *Stat) MarshalBytes(dst []byte) { + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Dev)) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Ino)) + dst = dst[8:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.Mode)) + dst = dst[4:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.Nlink)) + dst = dst[4:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.UID)) + dst = dst[4:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.GID)) + dst = dst[4:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev)) + dst = dst[8:] + // Padding: dst[:sizeof(uint64)] ~= uint64(0) + dst = dst[8:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Size)) + dst = dst[8:] + usermem.ByteOrder.PutUint32(dst[:4], uint32(s.Blksize)) + dst = dst[4:] + // Padding: dst[:sizeof(int32)] ~= int32(0) + dst = dst[4:] + usermem.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks)) + dst = dst[8:] + s.ATime.MarshalBytes(dst[:s.ATime.SizeBytes()]) + dst = dst[s.ATime.SizeBytes():] + s.MTime.MarshalBytes(dst[:s.MTime.SizeBytes()]) + dst = dst[s.MTime.SizeBytes():] + s.CTime.MarshalBytes(dst[:s.CTime.SizeBytes()]) + dst = dst[s.CTime.SizeBytes():] + // Padding: dst[:sizeof(int32)*2] ~= [2]int32{0} + dst = dst[8:] +} + +// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. +func (s *Stat) UnmarshalBytes(src []byte) { + s.Dev = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Ino = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Mode = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + s.Nlink = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + s.UID = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + s.GID = uint32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + s.Rdev = uint64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + // Padding: var _ uint64 ~= src[:sizeof(uint64)] + src = src[8:] + s.Size = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.Blksize = int32(usermem.ByteOrder.Uint32(src[:4])) + src = src[4:] + // Padding: var _ int32 ~= src[:sizeof(int32)] + src = src[4:] + s.Blocks = int64(usermem.ByteOrder.Uint64(src[:8])) + src = src[8:] + s.ATime.UnmarshalBytes(src[:s.ATime.SizeBytes()]) + src = src[s.ATime.SizeBytes():] + s.MTime.UnmarshalBytes(src[:s.MTime.SizeBytes()]) + src = src[s.MTime.SizeBytes():] + s.CTime.UnmarshalBytes(src[:s.CTime.SizeBytes()]) + src = src[s.CTime.SizeBytes():] + // Padding: ~ copy([2]int32(s._), src[:sizeof(int32)*2]) + src = src[8:] +} + +// Packed implements marshal.Marshallable.Packed. +func (s *Stat) Packed() bool { + return s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() +} + +// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe. +func (s *Stat) MarshalUnsafe(dst []byte) { + if s.MTime.Packed() && s.CTime.Packed() && s.ATime.Packed() { + safecopy.CopyIn(dst, unsafe.Pointer(s)) + } else { + s.MarshalBytes(dst) + } +} + +// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe. +func (s *Stat) UnmarshalUnsafe(src []byte) { + if s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() { + safecopy.CopyOut(unsafe.Pointer(s), src) + } else { + s.UnmarshalBytes(src) + } +} + +// CopyOut implements marshal.Marshallable.CopyOut. +func (s *Stat) CopyOut(task marshal.Task, addr usermem.Addr) error { + if !s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() { + // Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes. + buf := task.CopyScratchBuffer(s.SizeBytes()) + s.MarshalBytes(buf) + _, err := task.CopyOutBytes(addr, buf) + return err + } + + // Bypass escape analysis on s. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on s. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(s) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by s's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = s.SizeBytes() + hdr.Cap = s.SizeBytes() + + _, err := task.CopyOutBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that s + // must live until after the CopyOutBytes. + runtime.KeepAlive(s) + return err +} + +// CopyIn implements marshal.Marshallable.CopyIn. +func (s *Stat) CopyIn(task marshal.Task, addr usermem.Addr) error { + if !s.MTime.Packed() && s.CTime.Packed() && s.ATime.Packed() { + // Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes. + buf := task.CopyScratchBuffer(s.SizeBytes()) + _, err := task.CopyInBytes(addr, buf) + if err != nil { + return err + } + s.UnmarshalBytes(buf) + return nil + } + + // Bypass escape analysis on s. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on s. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(s) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by s's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = s.SizeBytes() + hdr.Cap = s.SizeBytes() + + _, err := task.CopyInBytes(addr, buf) + // Since we bypassed the compiler's escape analysis, indicate that s + // must live until after the CopyInBytes. + runtime.KeepAlive(s) + return err +} + +// WriteTo implements io.WriterTo.WriteTo. +func (s *Stat) WriteTo(w io.Writer) (int64, error) { + if !s.ATime.Packed() && s.MTime.Packed() && s.CTime.Packed() { + // Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes. + buf := make([]byte, s.SizeBytes()) + s.MarshalBytes(buf) + n, err := w.Write(buf) + return int64(n), err + } + + // Bypass escape analysis on s. The no-op arithmetic operation on the + // pointer makes the compiler think val doesn't depend on s. + // See src/runtime/stubs.go:noescape() in the golang toolchain. + ptr := unsafe.Pointer(s) + val := uintptr(ptr) + val = val^0 + + // Construct a slice backed by s's underlying memory. + var buf []byte + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) + hdr.Data = val + hdr.Len = s.SizeBytes() + hdr.Cap = s.SizeBytes() + + len, err := w.Write(buf) + // Since we bypassed the compiler's escape analysis, indicate that s + // must live until after the Write. + runtime.KeepAlive(s) + return int64(len), err +} + diff --git a/pkg/abi/linux/linux_arm64_state_autogen.go b/pkg/abi/linux/linux_arm64_state_autogen.go new file mode 100755 index 000000000..7b31374fe --- /dev/null +++ b/pkg/abi/linux/linux_arm64_state_autogen.go @@ -0,0 +1,5 @@ +// automatically generated by stateify. + +// +build arm64 + +package linux diff --git a/pkg/abi/linux/linux_state_autogen.go b/pkg/abi/linux/linux_state_autogen.go new file mode 100755 index 000000000..b8e488a11 --- /dev/null +++ b/pkg/abi/linux/linux_state_autogen.go @@ -0,0 +1,68 @@ +// automatically generated by stateify. + +package linux + +import ( + "gvisor.dev/gvisor/pkg/state" +) + +func (x *BPFInstruction) beforeSave() {} +func (x *BPFInstruction) save(m state.Map) { + x.beforeSave() + m.Save("OpCode", &x.OpCode) + m.Save("JumpIfTrue", &x.JumpIfTrue) + m.Save("JumpIfFalse", &x.JumpIfFalse) + m.Save("K", &x.K) +} + +func (x *BPFInstruction) afterLoad() {} +func (x *BPFInstruction) load(m state.Map) { + m.Load("OpCode", &x.OpCode) + m.Load("JumpIfTrue", &x.JumpIfTrue) + m.Load("JumpIfFalse", &x.JumpIfFalse) + m.Load("K", &x.K) +} + +func (x *KernelTermios) beforeSave() {} +func (x *KernelTermios) save(m state.Map) { + x.beforeSave() + m.Save("InputFlags", &x.InputFlags) + m.Save("OutputFlags", &x.OutputFlags) + m.Save("ControlFlags", &x.ControlFlags) + m.Save("LocalFlags", &x.LocalFlags) + m.Save("LineDiscipline", &x.LineDiscipline) + m.Save("ControlCharacters", &x.ControlCharacters) + m.Save("InputSpeed", &x.InputSpeed) + m.Save("OutputSpeed", &x.OutputSpeed) +} + +func (x *KernelTermios) afterLoad() {} +func (x *KernelTermios) load(m state.Map) { + m.Load("InputFlags", &x.InputFlags) + m.Load("OutputFlags", &x.OutputFlags) + m.Load("ControlFlags", &x.ControlFlags) + m.Load("LocalFlags", &x.LocalFlags) + m.Load("LineDiscipline", &x.LineDiscipline) + m.Load("ControlCharacters", &x.ControlCharacters) + m.Load("InputSpeed", &x.InputSpeed) + m.Load("OutputSpeed", &x.OutputSpeed) +} + +func (x *WindowSize) beforeSave() {} +func (x *WindowSize) save(m state.Map) { + x.beforeSave() + m.Save("Rows", &x.Rows) + m.Save("Cols", &x.Cols) +} + +func (x *WindowSize) afterLoad() {} +func (x *WindowSize) load(m state.Map) { + m.Load("Rows", &x.Rows) + m.Load("Cols", &x.Cols) +} + +func init() { + state.Register("pkg/abi/linux.BPFInstruction", (*BPFInstruction)(nil), state.Fns{Save: (*BPFInstruction).save, Load: (*BPFInstruction).load}) + state.Register("pkg/abi/linux.KernelTermios", (*KernelTermios)(nil), state.Fns{Save: (*KernelTermios).save, Load: (*KernelTermios).load}) + state.Register("pkg/abi/linux.WindowSize", (*WindowSize)(nil), state.Fns{Save: (*WindowSize).save, Load: (*WindowSize).load}) +} diff --git a/pkg/abi/linux/netfilter_test.go b/pkg/abi/linux/netfilter_test.go deleted file mode 100644 index 21e237f92..000000000 --- a/pkg/abi/linux/netfilter_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package linux - -import ( - "testing" - - "gvisor.dev/gvisor/pkg/binary" -) - -func TestSizes(t *testing.T) { - testCases := []struct { - typ interface{} - defined uintptr - }{ - {IPTEntry{}, SizeOfIPTEntry}, - {IPTGetEntries{}, SizeOfIPTGetEntries}, - {IPTGetinfo{}, SizeOfIPTGetinfo}, - {IPTIP{}, SizeOfIPTIP}, - {IPTReplace{}, SizeOfIPTReplace}, - {XTCounters{}, SizeOfXTCounters}, - {XTEntryMatch{}, SizeOfXTEntryMatch}, - {XTEntryTarget{}, SizeOfXTEntryTarget}, - {XTErrorTarget{}, SizeOfXTErrorTarget}, - {XTStandardTarget{}, SizeOfXTStandardTarget}, - } - - for _, tc := range testCases { - if calculated := binary.Size(tc.typ); calculated != tc.defined { - t.Errorf("%T has a defined size of %d and calculated size of %d", tc.typ, tc.defined, calculated) - } - } -} diff --git a/pkg/abi/linux/rseq.go b/pkg/abi/linux/rseq.go index 76253ba30..76253ba30 100644..100755 --- a/pkg/abi/linux/rseq.go +++ b/pkg/abi/linux/rseq.go diff --git a/pkg/abi/linux/signalfd.go b/pkg/abi/linux/signalfd.go index 85fad9956..85fad9956 100644..100755 --- a/pkg/abi/linux/signalfd.go +++ b/pkg/abi/linux/signalfd.go diff --git a/pkg/abi/linux/xattr.go b/pkg/abi/linux/xattr.go index a3b6406fa..a3b6406fa 100644..100755 --- a/pkg/abi/linux/xattr.go +++ b/pkg/abi/linux/xattr.go |