Commit 8f3f4c96 authored by Joel Sing's avatar Joel Sing

syscall: dragonfly/amd64 support

Add syscall support for dragonfly/amd64.

Also add support for generating syscall z* files for dragonfly.

R=bradfitz
CC=golang-dev
https://golang.org/cl/13188043
parent ac00524b
// 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.
#include "../../cmd/ld/textflag.h"
//
// System call support for AMD64, DragonFly
//
// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64)
// Trap # in AX, args in DI SI DX, return in AX DX
TEXT ·Syscall(SB),NOSPLIT,$0-64
CALL runtime·entersyscall(SB)
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok
MOVQ $-1, 40(SP) // r1
MOVQ $0, 48(SP) // r2
MOVQ AX, 56(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok:
MOVQ AX, 40(SP) // r1
MOVQ DX, 48(SP) // r2
MOVQ $0, 56(SP) // errno
CALL runtime·exitsyscall(SB)
RET
TEXT ·Syscall6(SB),NOSPLIT,$0-88
CALL runtime·entersyscall(SB)
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ 40(SP), R10
MOVQ 48(SP), R8
MOVQ 56(SP), R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok6
MOVQ $-1, 64(SP) // r1
MOVQ $0, 72(SP) // r2
MOVQ AX, 80(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok6:
MOVQ AX, 64(SP) // r1
MOVQ DX, 72(SP) // r2
MOVQ $0, 80(SP) // errno
CALL runtime·exitsyscall(SB)
RET
TEXT ·Syscall9(SB),NOSPLIT,$0-112
CALL runtime·entersyscall(SB)
MOVQ 8(SP), AX
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ 40(SP), R10
MOVQ 48(SP), R8
MOVQ 56(SP), R9
// shift around the last three arguments so they're at the
// top of the stack when the syscall is called.
MOVQ 64(SP), R11 // arg 7
MOVQ R11, 8(SP)
MOVQ 72(SP), R11 // arg 8
MOVQ R11, 16(SP)
MOVQ 80(SP), R11 // arg 9
MOVQ R11, 24(SP)
SYSCALL
JCC ok9
MOVQ $-1, 88(SP) // r1
MOVQ $0, 96(SP) // r2
MOVQ AX, 104(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok9:
MOVQ AX, 88(SP) // r1
MOVQ DX, 96(SP) // r2
MOVQ $0, 104(SP) // errno
CALL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-64
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok1
MOVQ $-1, 40(SP) // r1
MOVQ $0, 48(SP) // r2
MOVQ AX, 56(SP) // errno
RET
ok1:
MOVQ AX, 40(SP) // r1
MOVQ DX, 48(SP) // r2
MOVQ $0, 56(SP) // errno
RET
TEXT ·RawSyscall6(SB),NOSPLIT,$0-88
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ 40(SP), R10
MOVQ 48(SP), R8
MOVQ 56(SP), R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok2
MOVQ $-1, 64(SP) // r1
MOVQ $0, 72(SP) // r2
MOVQ AX, 80(SP) // errno
RET
ok2:
MOVQ AX, 64(SP) // r1
MOVQ DX, 72(SP) // r2
MOVQ $0, 80(SP) // errno
RET
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd netbsd openbsd
// +build darwin dragonfly freebsd netbsd openbsd
// Berkeley packet filter for BSD variants
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build freebsd darwin linux netbsd openbsd
// +build freebsd dragonfly darwin linux netbsd openbsd
// This file tests that some basic syscalls are consistent across
// all Unixes.
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd
// Unix environment variables.
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd netbsd openbsd
// +build darwin dragonfly freebsd netbsd openbsd
package syscall
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd
// Fork, exec, wait, etc.
......
......@@ -121,6 +121,12 @@ darwin_amd64)
mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
dragonfly_amd64)
mkerrors="$mkerrors -m64"
mksyscall="./mksyscall.pl -dragonfly"
mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32"
......@@ -218,7 +224,7 @@ esac
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
syscall_goos="syscall_$GOOS.go"
case "$GOOS" in
darwin | freebsd | netbsd | openbsd)
darwin | dragonfly | freebsd | netbsd | openbsd)
syscall_goos="syscall_bsd.go $syscall_goos"
;;
windows)
......
......@@ -37,6 +37,25 @@ includes_Darwin='
#include <termios.h>
'
includes_DragonFly='
#include <sys/types.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <net/ip_mroute/ip_mroute.h>
'
includes_FreeBSD='
#include <sys/types.h>
#include <sys/event.h>
......
......@@ -27,6 +27,7 @@ my $_32bit = "";
my $plan9 = 0;
my $openbsd = 0;
my $netbsd = 0;
my $dragonfly = 0;
my $arm = 0; # 64-bit value should use (even, odd)-pair
if($ARGV[0] eq "-b32") {
......@@ -48,6 +49,10 @@ if($ARGV[0] eq "-netbsd") {
$netbsd = 1;
shift;
}
if($ARGV[0] eq "-dragonfly") {
$dragonfly = 1;
shift;
}
if($ARGV[0] eq "-arm") {
$arm = 1;
shift;
......@@ -159,6 +164,17 @@ while(<>) {
} else {
push @args, "uintptr($name)";
}
} elsif($type eq "int64" && $dragonfly) {
if ($func !~ /^extp(read|write)/i) {
push @args, "0";
}
if($_32bit eq "big-endian") {
push @args, "uintptr($name>>32)", "uintptr($name)";
} elsif($_32bit eq "little-endian") {
push @args, "uintptr($name)", "uintptr($name>>32)";
} else {
push @args, "uintptr($name)";
}
} elsif($type eq "int64" && $_32bit ne "") {
if(@args % 2 && $arm) {
# arm abi specifies 64-bit argument uses
......
#!/usr/bin/env perl
# 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.
#
# Generate system call table for DragonFly from master list
# (for example, /usr/src/sys/kern/syscalls.master).
use strict;
my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package syscall
const (
EOF
while(<>){
if(/^([0-9]+)\s+STD\s+\S+\s+({ \S+\s+(\w+).*)$/){
my $num = $1;
my $proto = $2;
my $name = "SYS_$3";
$name =~ y/a-z/A-Z/;
# There are multiple entries for enosys and nosys, so comment them out.
if($name =~ /^SYS_E?NOSYS$/){
$name = "// $name";
}
if($name eq 'SYS_SYS_EXIT'){
$name = 'SYS_EXIT';
}
print " $name = $num; // $proto\n";
}
}
print <<EOF;
)
EOF
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux darwin freebsd netbsd openbsd
// +build linux dragonfly darwin freebsd netbsd openbsd
package syscall_test
......@@ -13,6 +13,7 @@ import (
"net"
"os"
"os/exec"
"runtime"
"syscall"
"testing"
"time"
......@@ -26,6 +27,10 @@ import (
// "-test.run=^TestPassFD$" and an environment variable used to signal
// that the test should become the child process instead.
func TestPassFD(t *testing.T) {
if runtime.GOOS == "dragonfly" {
// TODO(jsing): Figure out why sendmsg is returning EINVAL.
t.Skip("Skipping test on dragonfly")
}
if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
passFDChild()
return
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd netbsd openbsd
// +build darwin dragonfly freebsd netbsd openbsd
// Routing sockets and messages
......
// Copyright 2011 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.
// Routing sockets and messages for Dragonfly
package syscall
import "unsafe"
func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage {
switch any.Type {
case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
p := (*RouteMessage)(unsafe.Pointer(any))
return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]}
case RTM_IFINFO:
p := (*InterfaceMessage)(unsafe.Pointer(any))
return &InterfaceMessage{Header: p.Header, Data: b[SizeofIfMsghdr:any.Msglen]}
case RTM_IFANNOUNCE:
p := (*InterfaceAnnounceMessage)(unsafe.Pointer(any))
return &InterfaceAnnounceMessage{Header: p.Header}
case RTM_NEWADDR, RTM_DELADDR:
p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
return &InterfaceAddrMessage{Header: p.Header, Data: b[SizeofIfaMsghdr:any.Msglen]}
case RTM_NEWMADDR, RTM_DELMADDR:
p := (*InterfaceMulticastAddrMessage)(unsafe.Pointer(any))
return &InterfaceMulticastAddrMessage{Header: p.Header, Data: b[SizeofIfmaMsghdr:any.Msglen]}
}
return nil
}
// InterfaceAnnounceMessage represents a routing message containing
// network interface arrival and depature information.
type InterfaceAnnounceMessage struct {
Header IfAnnounceMsghdr
}
func (m *InterfaceAnnounceMessage) sockaddr() (sas []Sockaddr) { return nil }
// InterfaceMulticastAddrMessage represents a routing message
// containing network interface address entries.
type InterfaceMulticastAddrMessage struct {
Header IfmaMsghdr
Data []byte
}
const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfmaMask == 0 {
return nil
}
b := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
switch i {
case RTAX_IFA:
sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if e != nil {
return nil
}
sas = append(sas, sa)
case RTAX_GATEWAY, RTAX_IFP:
// nothing to do
}
b = b[rsaAlignOf(int(rsa.Len)):]
}
return sas
}
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd
// Socket control messages
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd netbsd openbsd
// +build darwin dragonfly freebsd netbsd openbsd
// BSD system call wrappers shared by *BSD based systems
// including OS X (Darwin) and FreeBSD. Like the other
......@@ -291,7 +291,9 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
return
}
// TODO(jsing): Remove after OpenBSD 5.4 is released (see issue 3349).
if runtime.GOOS == "openbsd" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
// TODO(jsing): Apparently dragonfly has the same "bug", which should
// be reported upstream.
if (runtime.GOOS == "dragonfly" || runtime.GOOS == "openbsd") && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
rsa.Addr.Family = AF_UNIX
rsa.Addr.Len = SizeofSockaddrUnix
}
......
This diff is collapsed.
// 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.
package syscall
import "unsafe"
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
}
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3
tv.Sec = int64(nsec / 1e9)
return
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd)
k.Filter = int16(mode)
k.Flags = uint16(flags)
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
written = int(writtenOut)
if e1 != 0 {
err = e1
}
return
}
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build freebsd netbsd openbsd
// +build dragonfly freebsd netbsd openbsd
package syscall
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd
package syscall
......
// 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.
// +build ignore
/*
Input to cgo -godefs. See also mkerrors.sh and mkall.sh
*/
// +godefs map struct_in_addr [4]byte /* in_addr */
// +godefs map struct_in6_addr [16]byte /* in6_addr */
package syscall
/*
#define KERNEL
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <netinet/tcp.h>
enum {
sizeofPtr = sizeof(void*),
};
union sockaddr_all {
struct sockaddr s1; // this one gets used for fields
struct sockaddr_in s2; // these pad it out
struct sockaddr_in6 s3;
struct sockaddr_un s4;
struct sockaddr_dl s5;
};
struct sockaddr_any {
struct sockaddr addr;
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
};
*/
import "C"
// Machine characteristics; for internal use.
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
// Time
type Timespec C.struct_timespec
type Timeval C.struct_timeval
// Processes
type Rusage C.struct_rusage
type Rlimit C.struct_rlimit
type _Gid_t C.gid_t
// Files
const (
F_DUPFD_CLOEXEC = 0 // not supported
)
const ( // Directory mode bits
S_IFMT = C.S_IFMT
S_IFIFO = C.S_IFIFO
S_IFCHR = C.S_IFCHR
S_IFDIR = C.S_IFDIR
S_IFBLK = C.S_IFBLK
S_IFREG = C.S_IFREG
S_IFLNK = C.S_IFLNK
S_IFSOCK = C.S_IFSOCK
S_ISUID = C.S_ISUID
S_ISGID = C.S_ISGID
S_ISVTX = C.S_ISVTX
S_IRUSR = C.S_IRUSR
S_IWUSR = C.S_IWUSR
S_IXUSR = C.S_IXUSR
)
type Stat_t C.struct_stat
type Statfs_t C.struct_statfs
type Flock_t C.struct_flock
type Dirent C.struct_dirent
type Fsid C.struct_fsid
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in
type RawSockaddrInet6 C.struct_sockaddr_in6
type RawSockaddrUnix C.struct_sockaddr_un
type RawSockaddrDatalink C.struct_sockaddr_dl
type RawSockaddr C.struct_sockaddr
type RawSockaddrAny C.struct_sockaddr_any
type _Socklen C.socklen_t
type Linger C.struct_linger
type Iovec C.struct_iovec
type IPMreq C.struct_ip_mreq
type IPv6Mreq C.struct_ipv6_mreq
type Msghdr C.struct_msghdr
type Cmsghdr C.struct_cmsghdr
type Inet6Pktinfo C.struct_in6_pktinfo
type IPv6MTUInfo C.struct_ip6_mtuinfo
type ICMPv6Filter C.struct_icmp6_filter
const (
SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
SizeofLinger = C.sizeof_struct_linger
SizeofIPMreq = C.sizeof_struct_ip_mreq
SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
SizeofMsghdr = C.sizeof_struct_msghdr
SizeofCmsghdr = C.sizeof_struct_cmsghdr
SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
)
// Ptrace requests
const (
PTRACE_TRACEME = C.PT_TRACE_ME
PTRACE_CONT = C.PT_CONTINUE
PTRACE_KILL = C.PT_KILL
)
// Events (kqueue, kevent)
type Kevent_t C.struct_kevent
// Select
type FdSet C.fd_set
// Routing and interface messages
const (
SizeofIfMsghdr = C.sizeof_struct_if_msghdr
SizeofIfData = C.sizeof_struct_if_data
SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr
SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
SizeofRtMetrics = C.sizeof_struct_rt_metrics
)
type IfMsghdr C.struct_if_msghdr
type IfData C.struct_if_data
type IfaMsghdr C.struct_ifa_msghdr
type IfmaMsghdr C.struct_ifma_msghdr
type IfAnnounceMsghdr C.struct_if_announcemsghdr
type RtMsghdr C.struct_rt_msghdr
type RtMetrics C.struct_rt_metrics
// Berkeley packet filter
const (
SizeofBpfVersion = C.sizeof_struct_bpf_version
SizeofBpfStat = C.sizeof_struct_bpf_stat
SizeofBpfProgram = C.sizeof_struct_bpf_program
SizeofBpfInsn = C.sizeof_struct_bpf_insn
SizeofBpfHdr = C.sizeof_struct_bpf_hdr
)
type BpfVersion C.struct_bpf_version
type BpfStat C.struct_bpf_stat
type BpfProgram C.struct_bpf_program
type BpfInsn C.struct_bpf_insn
type BpfHdr C.struct_bpf_hdr
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment