cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
package runtime
|
|
|
|
|
|
|
|
import "unsafe"
|
|
|
|
|
2015-10-21 13:48:53 -06:00
|
|
|
type mts struct {
|
|
|
|
tv_sec int64
|
|
|
|
tv_nsec int64
|
|
|
|
}
|
|
|
|
|
|
|
|
type mscratch struct {
|
|
|
|
v [6]uintptr
|
|
|
|
}
|
|
|
|
|
|
|
|
type mOS struct {
|
|
|
|
perrno *int32 // pointer to tls errno
|
|
|
|
// these are here because they are too large to be on the stack
|
|
|
|
// of low-level NOSPLIT functions.
|
|
|
|
//LibCall libcall;
|
|
|
|
ts mts
|
|
|
|
scratch mscratch
|
|
|
|
}
|
|
|
|
|
[dev.cc] runtime: convert Solaris port to Go
Memory management was consolitated with the BSD ports, since
it was almost identical.
Assembly thunks are gone, being replaced by the new //go:linkname
feature.
This change supersedes CL 138390043 (runtime: convert solaris
netpoll to Go), which was previously reviewed and tested.
This change is only the first step, the port now builds,
but doesn't run. Binaries fail to exec:
ld.so.1: 6.out: fatal: 6.out: TLS requirement failure : TLS support is unavailable
Killed
This seems to happen because binaries don't link with libc.so
anymore. We will have to solve that in a different CL.
Also this change is just a rough translation of the original
C code, cleanup will come in a different CL.
[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]
LGTM=rsc
R=rsc, dave
CC=golang-codereviews, iant, khr, minux, r, rlh
https://golang.org/cl/174960043
2014-11-13 08:07:10 -07:00
|
|
|
type libcFunc uintptr
|
2014-08-29 04:28:09 -06:00
|
|
|
|
|
|
|
var asmsysvicall6 libcFunc
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall0(fn *libcFunc) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 0
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.args = uintptr(unsafe.Pointer(fn)) // it's unused but must be non-nil, otherwise crashes
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 1
|
[dev.cc] runtime: convert Solaris port to Go
Memory management was consolitated with the BSD ports, since
it was almost identical.
Assembly thunks are gone, being replaced by the new //go:linkname
feature.
This change supersedes CL 138390043 (runtime: convert solaris
netpoll to Go), which was previously reviewed and tested.
This change is only the first step, the port now builds,
but doesn't run. Binaries fail to exec:
ld.so.1: 6.out: fatal: 6.out: TLS requirement failure : TLS support is unavailable
Killed
This seems to happen because binaries don't link with libc.so
anymore. We will have to solve that in a different CL.
Also this change is just a rough translation of the original
C code, cleanup will come in a different CL.
[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]
LGTM=rsc
R=rsc, dave
CC=golang-codereviews, iant, khr, minux, r, rlh
https://golang.org/cl/174960043
2014-11-13 08:07:10 -07:00
|
|
|
// TODO(rsc): Why is noescape necessary here and below?
|
2014-09-14 20:24:29 -06:00
|
|
|
libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 2
|
2014-09-14 20:24:29 -06:00
|
|
|
libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 3
|
2014-09-14 20:24:29 -06:00
|
|
|
libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 4
|
2014-09-14 20:24:29 -06:00
|
|
|
libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 5
|
2014-09-14 20:24:29 -06:00
|
|
|
libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:nosplit
|
2015-03-30 05:52:07 -06:00
|
|
|
func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall := &getg().m.libcall
|
2015-03-30 05:52:07 -06:00
|
|
|
libcall.fn = uintptr(unsafe.Pointer(fn))
|
2014-08-29 04:28:09 -06:00
|
|
|
libcall.n = 6
|
2014-09-14 20:24:29 -06:00
|
|
|
libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
2015-04-27 01:32:23 -06:00
|
|
|
asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
|
2014-08-29 04:28:09 -06:00
|
|
|
return libcall.r1
|
|
|
|
}
|