go.net/ipv6: simplify syscall shims

This CL replaces syscall duplicates with tiny syscall shims to help
to add new platform support, to improve existing platform support.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/166910043
This commit is contained in:
Mikio Hara
2014-10-31 09:53:30 +09:00
parent d3b1e66114
commit fa893e0b22
6 changed files with 17 additions and 106 deletions

View File

@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code is a duplicate of syscall/syscall_linux_386.go with small
// modifications.
package ipv6
import (
@@ -12,30 +9,22 @@ import (
"unsafe"
)
// On x86 Linux, all the socket calls go through an extra indirection,
// I think because the 5-register system call interface can't handle
// the 6-argument calls like sendto and recvfrom. Instead the
// arguments to the underlying system call are the number below and a
// pointer to an array of uintptr. We hide the pointer in the
// socketcall assembly to avoid allocation on every system call.
const (
// See /usr/include/linux/net.h.
_SETSOCKOPT = 14
_GETSOCKOPT = 15
sysGETSOCKOPT = 0xf
sysSETSOCKOPT = 0xe
)
var socketcall func(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func getsockopt(fd int, level int, name int, v unsafe.Pointer, l *sysSockoptLen) error {
if _, errno := socketcall(_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
if _, errno := socketcall(sysGETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
return error(errno)
}
return nil
}
func setsockopt(fd int, level int, name int, v unsafe.Pointer, l uintptr) error {
if _, errno := socketcall(_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
if _, errno := socketcall(sysSETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
return error(errno)
}
return nil

View File

@@ -1,56 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code is a duplicate of syscall/syscall_linux_386.s with small
// modifications.
#define SYS_SOCKETCALL 102 // from zsysnum_linux_386.go
// func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
// Kernel interface gets call sub-number and pointer to a0 for Go 1.1.
TEXT ·socketcallnosplit7(SB),7,$0
CALL runtime·entersyscall(SB)
MOVL $SYS_SOCKETCALL, AX // syscall entry
MOVL 4(SP), BX // socket call number
LEAL 8(SP), CX // pointer to call arguments
MOVL $0, DX
MOVL $0, SI
MOVL $0, DI
CALL *runtime·_vdso(SB)
CMPL AX, $0xfffff001
JLS ok1
MOVL $-1, 32(SP) // n
NEGL AX
MOVL AX, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok1:
MOVL AX, 32(SP) // n
MOVL $0, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
// func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
// Kernel interface gets call sub-number and pointer to a0 for Go 1.2.
TEXT ·socketcallnosplit4(SB),4,$0-40
CALL runtime·entersyscall(SB)
MOVL $SYS_SOCKETCALL, AX // syscall entry
MOVL 4(SP), BX // socket call number
LEAL 8(SP), CX // pointer to call arguments
MOVL $0, DX
MOVL $0, SI
MOVL $0, DI
CALL *runtime·_vdso(SB)
CMPL AX, $0xfffff001
JLS ok2
MOVL $-1, 32(SP) // n
NEGL AX
MOVL AX, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok2:
MOVL AX, 32(SP) // n
MOVL $0, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET

View File

@@ -1,15 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.2
package ipv6
import "syscall"
func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func init() {
socketcall = socketcallnosplit4
}

View File

@@ -1,15 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.1,!go1.2
package ipv6
import "syscall"
func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func init() {
socketcall = socketcallnosplit7
}

View File

@@ -11,14 +11,14 @@ import (
"unsafe"
)
func getsockopt(fd int, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
return error(errno)
}
return nil
}
func setsockopt(fd int, level int, name int, v unsafe.Pointer, l uintptr) error {
func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
return error(errno)
}

8
ipv6/thunk_linux_386.s Normal file
View File

@@ -0,0 +1,8 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.2
TEXT ·socketcall(SB),4,$0-36
JMP syscall·socketcall(SB)