summaryrefslogtreecommitdiffhomepage
path: root/pkg/abi/linux
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2021-05-04 23:55:46 +0000
committergVisor bot <gvisor-bot@google.com>2021-05-04 23:55:46 +0000
commitae3ce097bd142f8d8cf059f2ace92c164421af9c (patch)
treeca3507d14c1f2626119e92622bd6c45834398bbe /pkg/abi/linux
parent3207672c9e2b3f3603f76e7aa801f63cb30a8fe0 (diff)
parent689b369f5788c15f9b018246baa4e318082c0d79 (diff)
Merge release-20210419.0-64-g689b369f5 (automated)
Diffstat (limited to 'pkg/abi/linux')
-rw-r--r--pkg/abi/linux/elf.go50
-rw-r--r--pkg/abi/linux/epoll.go6
-rw-r--r--pkg/abi/linux/file.go5
-rw-r--r--pkg/abi/linux/linux_abi_autogen_unsafe.go391
-rw-r--r--pkg/abi/linux/netdevice.go4
5 files changed, 445 insertions, 11 deletions
diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go
index 7c9a02f20..c5713541f 100644
--- a/pkg/abi/linux/elf.go
+++ b/pkg/abi/linux/elf.go
@@ -106,3 +106,53 @@ const (
// NT_ARM_TLS is for ARM TLS register.
NT_ARM_TLS = 0x401
)
+
+// ElfHeader64 is the ELF64 file header.
+//
+// +marshal
+type ElfHeader64 struct {
+ Ident [16]byte // File identification.
+ Type uint16 // File type.
+ Machine uint16 // Machine architecture.
+ Version uint32 // ELF format version.
+ Entry uint64 // Entry point.
+ Phoff uint64 // Program header file offset.
+ Shoff uint64 // Section header file offset.
+ Flags uint32 // Architecture-specific flags.
+ Ehsize uint16 // Size of ELF header in bytes.
+ Phentsize uint16 // Size of program header entry.
+ Phnum uint16 // Number of program header entries.
+ Shentsize uint16 // Size of section header entry.
+ Shnum uint16 // Number of section header entries.
+ Shstrndx uint16 // Section name strings section.
+}
+
+// ElfSection64 is the ELF64 Section header.
+//
+// +marshal
+type ElfSection64 struct {
+ Name uint32 // Section name (index into the section header string table).
+ Type uint32 // Section type.
+ Flags uint64 // Section flags.
+ Addr uint64 // Address in memory image.
+ Off uint64 // Offset in file.
+ Size uint64 // Size in bytes.
+ Link uint32 // Index of a related section.
+ Info uint32 // Depends on section type.
+ Addralign uint64 // Alignment in bytes.
+ Entsize uint64 // Size of each entry in section.
+}
+
+// ElfProg64 is the ELF64 Program header.
+//
+// +marshal
+type ElfProg64 struct {
+ Type uint32 // Entry type.
+ Flags uint32 // Access permission flags.
+ Off uint64 // File offset of contents.
+ Vaddr uint64 // Virtual address in memory image.
+ Paddr uint64 // Physical address (not used).
+ Filesz uint64 // Size of contents in file.
+ Memsz uint64 // Size of contents in memory.
+ Align uint64 // Alignment in memory and file.
+}
diff --git a/pkg/abi/linux/epoll.go b/pkg/abi/linux/epoll.go
index 1121a1a92..67706f5aa 100644
--- a/pkg/abi/linux/epoll.go
+++ b/pkg/abi/linux/epoll.go
@@ -14,10 +14,6 @@
package linux
-import (
- "gvisor.dev/gvisor/pkg/binary"
-)
-
// Event masks.
const (
EPOLLIN = 0x1
@@ -59,4 +55,4 @@ const (
)
// SizeOfEpollEvent is the size of EpollEvent struct.
-var SizeOfEpollEvent = int(binary.Size(EpollEvent{}))
+var SizeOfEpollEvent = (*EpollEvent)(nil).SizeBytes()
diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go
index e11ca2d62..1e23850a9 100644
--- a/pkg/abi/linux/file.go
+++ b/pkg/abi/linux/file.go
@@ -19,7 +19,6 @@ import (
"strings"
"gvisor.dev/gvisor/pkg/abi"
- "gvisor.dev/gvisor/pkg/binary"
)
// Constants for open(2).
@@ -201,7 +200,7 @@ const (
)
// SizeOfStat is the size of a Stat struct.
-var SizeOfStat = binary.Size(Stat{})
+var SizeOfStat = (*Stat)(nil).SizeBytes()
// Flags for statx.
const (
@@ -268,7 +267,7 @@ type Statx struct {
}
// SizeOfStatx is the size of a Statx struct.
-var SizeOfStatx = binary.Size(Statx{})
+var SizeOfStatx = (*Statx)(nil).SizeBytes()
// FileMode represents a mode_t.
type FileMode uint16
diff --git a/pkg/abi/linux/linux_abi_autogen_unsafe.go b/pkg/abi/linux/linux_abi_autogen_unsafe.go
index 4a267d833..b77c2c972 100644
--- a/pkg/abi/linux/linux_abi_autogen_unsafe.go
+++ b/pkg/abi/linux/linux_abi_autogen_unsafe.go
@@ -27,6 +27,9 @@ var _ marshal.Marshallable = (*ControlMessageCredentials)(nil)
var _ marshal.Marshallable = (*ControlMessageHeader)(nil)
var _ marshal.Marshallable = (*ControlMessageIPPacketInfo)(nil)
var _ marshal.Marshallable = (*DigestMetadata)(nil)
+var _ marshal.Marshallable = (*ElfHeader64)(nil)
+var _ marshal.Marshallable = (*ElfProg64)(nil)
+var _ marshal.Marshallable = (*ElfSection64)(nil)
var _ marshal.Marshallable = (*ErrorName)(nil)
var _ marshal.Marshallable = (*ExtensionName)(nil)
var _ marshal.Marshallable = (*FOwnerEx)(nil)
@@ -814,6 +817,394 @@ func (c *CapUserHeader) WriteTo(writer io.Writer) (int64, error) {
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (e *ElfHeader64) SizeBytes() int {
+ return 48 +
+ 1*16
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (e *ElfHeader64) MarshalBytes(dst []byte) {
+ for idx := 0; idx < 16; idx++ {
+ dst[0] = byte(e.Ident[idx])
+ dst = dst[1:]
+ }
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Type))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Machine))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Version))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Entry))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Phoff))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Shoff))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Flags))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Ehsize))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Phentsize))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Phnum))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Shentsize))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Shnum))
+ dst = dst[2:]
+ hostarch.ByteOrder.PutUint16(dst[:2], uint16(e.Shstrndx))
+ dst = dst[2:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (e *ElfHeader64) UnmarshalBytes(src []byte) {
+ for idx := 0; idx < 16; idx++ {
+ e.Ident[idx] = src[0]
+ src = src[1:]
+ }
+ e.Type = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Machine = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Version = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Entry = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Phoff = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Shoff = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Flags = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Ehsize = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Phentsize = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Phnum = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Shentsize = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Shnum = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+ e.Shstrndx = uint16(hostarch.ByteOrder.Uint16(src[:2]))
+ src = src[2:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (e *ElfHeader64) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (e *ElfHeader64) MarshalUnsafe(dst []byte) {
+ gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(e.SizeBytes()))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (e *ElfHeader64) UnmarshalUnsafe(src []byte) {
+ gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(e.SizeBytes()))
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (e *ElfHeader64) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (e *ElfHeader64) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
+ return e.CopyOutN(cc, addr, e.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (e *ElfHeader64) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := cc.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (e *ElfHeader64) WriteTo(writer io.Writer) (int64, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := writer.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (e *ElfProg64) SizeBytes() int {
+ return 56
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (e *ElfProg64) MarshalBytes(dst []byte) {
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Type))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Flags))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Off))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Vaddr))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Paddr))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Filesz))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Memsz))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Align))
+ dst = dst[8:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (e *ElfProg64) UnmarshalBytes(src []byte) {
+ e.Type = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Flags = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Off = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Vaddr = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Paddr = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Filesz = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Memsz = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Align = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (e *ElfProg64) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (e *ElfProg64) MarshalUnsafe(dst []byte) {
+ gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(e.SizeBytes()))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (e *ElfProg64) UnmarshalUnsafe(src []byte) {
+ gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(e.SizeBytes()))
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (e *ElfProg64) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (e *ElfProg64) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
+ return e.CopyOutN(cc, addr, e.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (e *ElfProg64) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := cc.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (e *ElfProg64) WriteTo(writer io.Writer) (int64, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := writer.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
+func (e *ElfSection64) SizeBytes() int {
+ return 64
+}
+
+// MarshalBytes implements marshal.Marshallable.MarshalBytes.
+func (e *ElfSection64) MarshalBytes(dst []byte) {
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Name))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Type))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Flags))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Addr))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Off))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Size))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Link))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Info))
+ dst = dst[4:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Addralign))
+ dst = dst[8:]
+ hostarch.ByteOrder.PutUint64(dst[:8], uint64(e.Entsize))
+ dst = dst[8:]
+}
+
+// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
+func (e *ElfSection64) UnmarshalBytes(src []byte) {
+ e.Name = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Type = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Flags = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Addr = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Off = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Size = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Link = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Info = uint32(hostarch.ByteOrder.Uint32(src[:4]))
+ src = src[4:]
+ e.Addralign = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+ e.Entsize = uint64(hostarch.ByteOrder.Uint64(src[:8]))
+ src = src[8:]
+}
+
+// Packed implements marshal.Marshallable.Packed.
+//go:nosplit
+func (e *ElfSection64) Packed() bool {
+ return true
+}
+
+// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
+func (e *ElfSection64) MarshalUnsafe(dst []byte) {
+ gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(e.SizeBytes()))
+}
+
+// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
+func (e *ElfSection64) UnmarshalUnsafe(src []byte) {
+ gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(e.SizeBytes()))
+}
+
+// CopyOutN implements marshal.Marshallable.CopyOutN.
+//go:nosplit
+func (e *ElfSection64) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return length, err
+}
+
+// CopyOut implements marshal.Marshallable.CopyOut.
+//go:nosplit
+func (e *ElfSection64) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
+ return e.CopyOutN(cc, addr, e.SizeBytes())
+}
+
+// CopyIn implements marshal.Marshallable.CopyIn.
+//go:nosplit
+func (e *ElfSection64) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := cc.CopyInBytes(addr, buf) // escapes: okay.
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return length, err
+}
+
+// WriteTo implements io.WriterTo.WriteTo.
+func (e *ElfSection64) WriteTo(writer io.Writer) (int64, error) {
+ // Construct a slice backed by dst's underlying memory.
+ var buf []byte
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+ hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
+ hdr.Len = e.SizeBytes()
+ hdr.Cap = e.SizeBytes()
+
+ length, err := writer.Write(buf)
+ // Since we bypassed the compiler's escape analysis, indicate that e
+ // must live until the use above.
+ runtime.KeepAlive(e) // escapes: replaced by intrinsic.
+ return int64(length), err
+}
+
+// SizeBytes implements marshal.Marshallable.SizeBytes.
func (s *SockErrCMsgIPv4) SizeBytes() int {
return 0 +
(*SockExtendedErr)(nil).SizeBytes() +
diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go
index 0faf015c7..51a39704b 100644
--- a/pkg/abi/linux/netdevice.go
+++ b/pkg/abi/linux/netdevice.go
@@ -14,8 +14,6 @@
package linux
-import "gvisor.dev/gvisor/pkg/binary"
-
const (
// IFNAMSIZ is the size of the name field for IFReq.
IFNAMSIZ = 16
@@ -66,7 +64,7 @@ func (ifr *IFReq) SetName(name string) {
}
// SizeOfIFReq is the binary size of an IFReq struct (40 bytes).
-var SizeOfIFReq = binary.Size(IFReq{})
+var SizeOfIFReq = (*IFReq)(nil).SizeBytes()
// IFMap contains interface hardware parameters.
type IFMap struct {