Commit 6e211225 authored by Shenghou Ma's avatar Shenghou Ma

syscall: fix mkall.sh, mksyscall_linux.pl, and regen for Linux/ARM

CL 3075041 says ARM is not little-endian, but my test suggests otherwise.
My test program is:

    package main
    import ("fmt"; "syscall"; "os")
    func main() {
       err := syscall.Fallocate(1, 1/*FALLOC_FL_KEEP_SIZE*/, 0, int64(40960));
       fmt.Fprintln(os.Stderr, err)
    }

Without this CL, ./test > testfile will show: file too large; and strace shows:
    fallocate(1, 01, 0, 175921860444160)    = -1 EFBIG (File too large)
With this CL, ./test > testfile will show: <nil>; and strace shows:
    fallocate(1, 01, 0, 40960)              = 0

Quoting rsc:
"[It turns out that] ARM syscall ABI requires 64-bit arguments to use an
(even, odd) register pair, not an (odd, even) pair. Switching to "big-endian"
worked because it ended up using the high 32-bits (always zero in the tests
we had) as the padding word, because the 64-bit argument was the last one,
and because we fill in zeros for the rest of the system call arguments, up to
six. So it happened to work."

I updated mksyscall_linux.pl to accommodate the register pair ABI requirement,
and removed all hand-tweaked syscall routines in favor of the auto-generated
ones. These including: Ftruncate, Truncate, Pread and Pwrite.

Some recent Linux/ARM distributions do not bundle kernel asm headers,
so instead we always get latest asm/unistd.h from git.kernel.org (just like
what we do for FreeBSD).

R=ken, r, rsc, r, dave, iant
CC=golang-dev
https://golang.org/cl/5726051
parent 1042d7d5
...@@ -144,8 +144,8 @@ linux_amd64) ...@@ -144,8 +144,8 @@ linux_amd64)
;; ;;
linux_arm) linux_arm)
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -b32" mksyscall="./mksyscall.pl -l32 -arm"
mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd.h" mksysnum="curl -s 'http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=arch/arm/include/asm/unistd.h;hb=HEAD' | ./mksysnum_linux.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
netbsd_386) netbsd_386)
......
...@@ -27,6 +27,7 @@ my $_32bit = ""; ...@@ -27,6 +27,7 @@ my $_32bit = "";
my $plan9 = 0; my $plan9 = 0;
my $openbsd = 0; my $openbsd = 0;
my $netbsd = 0; my $netbsd = 0;
my $arm = 0; # 64-bit value should use (even, odd)-pair
if($ARGV[0] eq "-b32") { if($ARGV[0] eq "-b32") {
$_32bit = "big-endian"; $_32bit = "big-endian";
...@@ -47,6 +48,10 @@ if($ARGV[0] eq "-netbsd") { ...@@ -47,6 +48,10 @@ if($ARGV[0] eq "-netbsd") {
$netbsd = 1; $netbsd = 1;
shift; shift;
} }
if($ARGV[0] eq "-arm") {
$arm = 1;
shift;
}
if($ARGV[0] =~ /^-/) { if($ARGV[0] =~ /^-/) {
print STDERR "usage: mksyscall.pl [-b32 | -l32] [file ...]\n"; print STDERR "usage: mksyscall.pl [-b32 | -l32] [file ...]\n";
...@@ -135,6 +140,11 @@ while(<>) { ...@@ -135,6 +140,11 @@ while(<>) {
push @args, "uintptr($name)"; push @args, "uintptr($name)";
} }
} elsif($type eq "int64" && $_32bit ne "") { } elsif($type eq "int64" && $_32bit ne "") {
if(@args % 2 && $arm) {
# arm abi specifies 64-bit argument uses
# (even, odd) pair
push @args, "0"
}
if($_32bit eq "big-endian") { if($_32bit eq "big-endian") {
push @args, "uintptr($name>>32)", "uintptr($name)"; push @args, "uintptr($name>>32)", "uintptr($name)";
} else { } else {
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
package syscall package syscall
import "unsafe"
func Getpagesize() int { return 4096 } func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
...@@ -23,52 +21,6 @@ func NsecToTimeval(nsec int64) (tv Timeval) { ...@@ -23,52 +21,6 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
return return
} }
// Pread and Pwrite are special: they insert padding before the int64.
func Pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
}
r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
}
r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
func Ftruncate(fd int, length int64) (err error) {
// ARM EABI requires 64-bit arguments should be put in a pair
// of registers from an even register number.
_, _, e1 := Syscall6(SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
if e1 != 0 {
err = e1
}
return
}
func Truncate(path string, length int64) (err error) {
_, _, e1 := Syscall6(SYS_TRUNCATE64, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, uintptr(length), uintptr(length>>32), 0, 0)
if e1 != 0 {
err = e1
}
return
}
// Seek is defined in assembly. // Seek is defined in assembly.
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) func Seek(fd int, offset int64, whence int) (newoffset int64, err error)
...@@ -118,6 +70,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) ...@@ -118,6 +70,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
......
This diff is collapsed.
// mksyscall.pl -b32 syscall_linux.go syscall_linux_arm.go // mksyscall.pl -l32 -arm syscall_linux.go syscall_linux_arm.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package syscall package syscall
...@@ -287,7 +287,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { ...@@ -287,7 +287,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off>>32), uintptr(off), uintptr(len>>32), uintptr(len)) _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32))
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
...@@ -784,7 +784,7 @@ func Sysinfo(info *Sysinfo_t) (err error) { ...@@ -784,7 +784,7 @@ func Sysinfo(info *Sysinfo_t) (err error) {
func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) { func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0) r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
n = int64(int64(r0)<<32 | int64(r1)) n = int64(int64(r1)<<32 | int64(r0))
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
...@@ -1458,6 +1458,60 @@ func Time(t *Time_t) (tt Time_t, err error) { ...@@ -1458,6 +1458,60 @@ func Time(t *Time_t) (tt Time_t, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
n = int(r0)
if e1 != 0 {
err = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Truncate(path string, length int64) (err error) {
_, _, e1 := Syscall6(SYS_TRUNCATE64, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, uintptr(length), uintptr(length>>32), 0, 0)
if e1 != 0 {
err = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Ftruncate(fd int, length int64) (err error) {
_, _, e1 := Syscall6(SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
if e1 != 0 {
err = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) { func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) {
r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset)) r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset))
xaddr = uintptr(r0) xaddr = uintptr(r0)
......
// mksysnum_linux.pl /usr/include/asm/unistd.h // mksysnum_linux.pl
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT // MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package syscall package syscall
...@@ -338,5 +338,17 @@ const ( ...@@ -338,5 +338,17 @@ const (
SYS_PWRITEV = 362 SYS_PWRITEV = 362
SYS_RT_TGSIGQUEUEINFO = 363 SYS_RT_TGSIGQUEUEINFO = 363
SYS_PERF_EVENT_OPEN = 364 SYS_PERF_EVENT_OPEN = 364
SYS_RECVMMSG = 365
SYS_ACCEPT4 = 366 SYS_ACCEPT4 = 366
SYS_FANOTIFY_INIT = 367
SYS_FANOTIFY_MARK = 368
SYS_PRLIMIT64 = 369
SYS_NAME_TO_HANDLE_AT = 370
SYS_OPEN_BY_HANDLE_AT = 371
SYS_CLOCK_ADJTIME = 372
SYS_SYNCFS = 373
SYS_SENDMMSG = 374
SYS_SETNS = 375
SYS_PROCESS_VM_READV = 376
SYS_PROCESS_VM_WRITEV = 377
) )
...@@ -233,7 +233,7 @@ type Cmsghdr struct { ...@@ -233,7 +233,7 @@ type Cmsghdr struct {
Len uint32 Len uint32
Level int32 Level int32
Type int32 Type int32
X__cmsg_data [0]byte X__cmsg_data [0]uint8
} }
type Inet4Pktinfo struct { type Inet4Pktinfo struct {
...@@ -301,7 +301,7 @@ const ( ...@@ -301,7 +301,7 @@ const (
IFLA_LINKINFO = 0x12 IFLA_LINKINFO = 0x12
IFLA_NET_NS_PID = 0x13 IFLA_NET_NS_PID = 0x13
IFLA_IFALIAS = 0x14 IFLA_IFALIAS = 0x14
IFLA_MAX = 0x14 IFLA_MAX = 0x1c
RT_SCOPE_UNIVERSE = 0x0 RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8 RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd RT_SCOPE_LINK = 0xfd
...@@ -435,7 +435,7 @@ type InotifyEvent struct { ...@@ -435,7 +435,7 @@ type InotifyEvent struct {
Mask uint32 Mask uint32
Cookie uint32 Cookie uint32
Len uint32 Len uint32
Name [0]byte Name [0]uint8
} }
const SizeofInotifyEvent = 0x10 const SizeofInotifyEvent = 0x10
......
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