1
0
mirror of https://github.com/golang/go synced 2024-09-29 16:14:28 -06:00

runtime: document, clean up internal/sys

Document what the values in internal/sys mean.

Remove various special cases for arm64 in the code using StackAlign.

Delete Uintreg - it was for GOARCH=amd64p32,
which was specific to GOOS=nacl and has been retired.

This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.
This CL is, however, not windows/arm64-specific.
It is cleanup meant to make the port (and future ports) easier.

Change-Id: I40e8fa07b4e192298b6536b98a72a751951a4383
Reviewed-on: https://go-review.googlesource.com/c/go/+/288795
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Russ Cox 2021-01-27 01:06:52 -05:00
parent 678568a5cf
commit 8ac23a1f15
26 changed files with 124 additions and 168 deletions

View File

@ -306,14 +306,7 @@ func unwindm(restore *bool) {
// unwind of g's stack (see comment at top of file).
mp := acquirem()
sched := &mp.g0.sched
switch GOARCH {
default:
throw("unwindm not implemented")
case "386", "amd64", "arm", "ppc64", "ppc64le", "mips64", "mips64le", "s390x", "mips", "mipsle", "riscv64":
sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + sys.MinFrameSize))
case "arm64":
sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 16))
}
sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + alignUp(sys.MinFrameSize, sys.StackAlign)))
// Do the accounting that cgocall will not have a chance to do
// during an unwind.

View File

@ -200,8 +200,6 @@ func GostringW(w []uint16) (s string) {
return
}
type Uintreg sys.Uintreg
var Open = open
var Close = closefd
var Read = read

View File

@ -18,3 +18,41 @@ const (
S390X
WASM
)
// PtrSize is the size of a pointer in bytes - unsafe.Sizeof(uintptr(0)) but as an ideal constant.
// It is also the size of the machine's native word size (that is, 4 on 32-bit systems, 8 on 64-bit).
const PtrSize = 4 << (^uintptr(0) >> 63)
// AIX requires a larger stack for syscalls.
const StackGuardMultiplier = StackGuardMultiplierDefault*(1-GoosAix) + 2*GoosAix
// ArchFamily is the architecture family (AMD64, ARM, ...)
const ArchFamily ArchFamilyType = _ArchFamily
// BigEndian reports whether the architecture is big-endian.
const BigEndian = GoarchArmbe|GoarchArm64be|GoarchMips|GoarchMips64|GoarchPpc|GoarchPpc64|GoarchS390|GoarchS390x|GoarchSparc|GoarchSparc64 == 1
// DefaultPhysPageSize is the default physical page size.
const DefaultPhysPageSize = _DefaultPhysPageSize
// PCQuantum is the minimal unit for a program counter (1 on x86, 4 on most other systems).
// The various PC tables record PC deltas pre-divided by PCQuantum.
const PCQuantum = _PCQuantum
// Int64Align is the required alignment for a 64-bit integer (4 on 32-bit systems, 8 on 64-bit).
const Int64Align = PtrSize
// MinFrameSize is the size of the system-reserved words at the bottom
// of a frame (just above the architectural stack pointer).
// It is zero on x86 and PtrSize on most non-x86 (LR-based) systems.
// On PowerPC it is larger, to cover three more reserved words:
// the compiler word, the link editor word, and the TOC save word.
const MinFrameSize = _MinFrameSize
// StackAlign is the required alignment of the SP register.
// The stack must be at least word aligned, but some architectures require more.
const StackAlign = _StackAlign
// DefaultGoroot is set by the linker for use by package runtime.
// It doesn't really belong in this file or this package.
var DefaultGoroot string

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = I386
BigEndian = false
DefaultPhysPageSize = 4096
PCQuantum = 1
Int64Align = 4
MinFrameSize = 0
_ArchFamily = I386
_DefaultPhysPageSize = 4096
_PCQuantum = 1
_MinFrameSize = 0
_StackAlign = PtrSize
)
type Uintreg uint32

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = AMD64
BigEndian = false
DefaultPhysPageSize = 4096
PCQuantum = 1
Int64Align = 8
MinFrameSize = 0
_ArchFamily = AMD64
_DefaultPhysPageSize = 4096
_PCQuantum = 1
_MinFrameSize = 0
_StackAlign = PtrSize
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = ARM
BigEndian = false
DefaultPhysPageSize = 65536
PCQuantum = 4
Int64Align = 4
MinFrameSize = 4
_ArchFamily = ARM
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 4
_StackAlign = PtrSize
)
type Uintreg uint32

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = ARM64
BigEndian = false
DefaultPhysPageSize = 65536
PCQuantum = 4
Int64Align = 8
MinFrameSize = 8
_ArchFamily = ARM64
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = 16
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = MIPS
BigEndian = true
DefaultPhysPageSize = 65536
PCQuantum = 4
Int64Align = 4
MinFrameSize = 4
_ArchFamily = MIPS
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 4
_StackAlign = PtrSize
)
type Uintreg uint32

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = MIPS64
BigEndian = true
DefaultPhysPageSize = 16384
PCQuantum = 4
Int64Align = 8
MinFrameSize = 8
_ArchFamily = MIPS64
_DefaultPhysPageSize = 16384
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = MIPS64
BigEndian = false
DefaultPhysPageSize = 16384
PCQuantum = 4
Int64Align = 8
MinFrameSize = 8
_ArchFamily = MIPS64
_DefaultPhysPageSize = 16384
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = MIPS
BigEndian = false
DefaultPhysPageSize = 65536
PCQuantum = 4
Int64Align = 4
MinFrameSize = 4
_ArchFamily = MIPS
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 4
_StackAlign = PtrSize
)
type Uintreg uint32

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = PPC64
BigEndian = true
DefaultPhysPageSize = 65536
PCQuantum = 4
Int64Align = 8
MinFrameSize = 32
_ArchFamily = PPC64
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 32
_StackAlign = 16
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = PPC64
BigEndian = false
DefaultPhysPageSize = 65536
PCQuantum = 4
Int64Align = 8
MinFrameSize = 32
_ArchFamily = PPC64
_DefaultPhysPageSize = 65536
_PCQuantum = 4
_MinFrameSize = 32
_StackAlign = 16
)
type Uintreg uint64

View File

@ -5,14 +5,9 @@
package sys
const (
ArchFamily = RISCV64
BigEndian = false
CacheLineSize = 64
DefaultPhysPageSize = 4096
PCQuantum = 4
Int64Align = 8
HugePageSize = 1 << 21
MinFrameSize = 8
_ArchFamily = RISCV64
_DefaultPhysPageSize = 4096
_PCQuantum = 4
_MinFrameSize = 8
_StackAlign = PtrSize
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = S390X
BigEndian = true
DefaultPhysPageSize = 4096
PCQuantum = 2
Int64Align = 8
MinFrameSize = 8
_ArchFamily = S390X
_DefaultPhysPageSize = 4096
_PCQuantum = 2
_MinFrameSize = 8
_StackAlign = PtrSize
)
type Uintreg uint64

View File

@ -5,12 +5,9 @@
package sys
const (
ArchFamily = WASM
BigEndian = false
DefaultPhysPageSize = 65536
PCQuantum = 1
Int64Align = 8
MinFrameSize = 0
_ArchFamily = WASM
_DefaultPhysPageSize = 65536
_PCQuantum = 1
_MinFrameSize = 0
_StackAlign = PtrSize
)
type Uintreg uint64

View File

@ -1,16 +0,0 @@
// 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 sys
// Declarations for runtime services implemented in C or assembly.
const PtrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
const RegSize = 4 << (^Uintreg(0) >> 63) // unsafe.Sizeof(uintreg(0)) but an ideal const
const SpAlign = 1*(1-GoarchArm64) + 16*GoarchArm64 // SP alignment: 1 normally, 16 for ARM64
var DefaultGoroot string // set at link time
// AIX requires a larger stack for syscalls.
const StackGuardMultiplier = StackGuardMultiplierDefault*(1-GoosAix) + 2*GoosAix

View File

@ -92,10 +92,6 @@ func sighandler(_ureg *ureg, note *byte, gp *g) int {
if usesLR {
c.setlr(pc)
} else {
if sys.RegSize > sys.PtrSize {
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = 0
}
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = pc
c.setsp(sp)

View File

@ -1900,7 +1900,7 @@ func oneNewExtraM() {
gp := malg(4096)
gp.sched.pc = funcPC(goexit) + sys.PCQuantum
gp.sched.sp = gp.stack.hi
gp.sched.sp -= 4 * sys.RegSize // extra space in case of reads slightly beyond frame
gp.sched.sp -= 4 * sys.PtrSize // extra space in case of reads slightly beyond frame
gp.sched.lr = 0
gp.sched.g = guintptr(unsafe.Pointer(gp))
gp.syscallpc = gp.sched.pc
@ -4009,9 +4009,9 @@ func newproc1(fn *funcval, argp unsafe.Pointer, narg int32, callergp *g, callerp
// We could allocate a larger initial stack if necessary.
// Not worth it: this is almost always an error.
// 4*sizeof(uintreg): extra space added below
// sizeof(uintreg): caller's LR (arm) or return address (x86, in gostartcall).
if siz >= _StackMin-4*sys.RegSize-sys.RegSize {
// 4*PtrSize: extra space added below
// PtrSize: caller's LR (arm) or return address (x86, in gostartcall).
if siz >= _StackMin-4*sys.PtrSize-sys.PtrSize {
throw("newproc: function arguments too large for new goroutine")
}
@ -4030,8 +4030,8 @@ func newproc1(fn *funcval, argp unsafe.Pointer, narg int32, callergp *g, callerp
throw("newproc1: new g is not Gdead")
}
totalSize := 4*sys.RegSize + uintptr(siz) + sys.MinFrameSize // extra space in case of reads slightly beyond frame
totalSize += -totalSize & (sys.SpAlign - 1) // align to spAlign
totalSize := 4*sys.PtrSize + uintptr(siz) + sys.MinFrameSize // extra space in case of reads slightly beyond frame
totalSize += -totalSize & (sys.StackAlign - 1) // align to StackAlign
sp := newg.stack.hi - totalSize
spArg := sp
if usesLR {

View File

@ -327,7 +327,7 @@ type gobuf struct {
pc uintptr
g guintptr
ctxt unsafe.Pointer
ret sys.Uintreg
ret uintptr
lr uintptr
bp uintptr // for framepointer-enabled architectures
}

View File

@ -266,8 +266,8 @@ func TestTrailingZero(t *testing.T) {
n int64
z struct{}
}
if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(Uintreg(0)) {
t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(Uintreg(0)))
if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(uintptr(0)) {
t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(uintptr(0)))
}
type T3 struct {
n byte

View File

@ -63,7 +63,7 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
// functions are correctly handled. This smashes
// the stack frame but we're not going back there
// anyway.
sp := c.sp() - sys.SpAlign // needs only sizeof uint64, but must align the stack
sp := c.sp() - sys.StackAlign // needs only sizeof uint64, but must align the stack
c.set_sp(sp)
*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()

View File

@ -651,7 +651,7 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
// Adjust saved base pointer if there is one.
// TODO what about arm64 frame pointer adjustment?
if sys.ArchFamily == sys.AMD64 && frame.argp-frame.varp == 2*sys.RegSize {
if sys.ArchFamily == sys.AMD64 && frame.argp-frame.varp == 2*sys.PtrSize {
if stackDebug >= 3 {
print(" saved bp\n")
}
@ -1245,7 +1245,7 @@ func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) (locals, args
var minsize uintptr
switch sys.ArchFamily {
case sys.ARM64:
minsize = sys.SpAlign
minsize = sys.StackAlign
default:
minsize = sys.MinFrameSize
}

View File

@ -30,10 +30,6 @@ func wasmExit(code int32)
// and then did an immediate gosave.
func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
sp := buf.sp
if sys.RegSize > sys.PtrSize {
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = 0
}
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = buf.pc
buf.sp = sp

View File

@ -15,10 +15,6 @@ import (
// and then did an immediate gosave.
func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
sp := buf.sp
if sys.RegSize > sys.PtrSize {
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = 0
}
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = buf.pc
buf.sp = sp

View File

@ -144,8 +144,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp))
frame.lr = 0
} else {
frame.pc = uintptr(*(*sys.Uintreg)(unsafe.Pointer(frame.sp)))
frame.sp += sys.RegSize
frame.pc = uintptr(*(*uintptr)(unsafe.Pointer(frame.sp)))
frame.sp += sys.PtrSize
}
}
@ -208,7 +208,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc, &cache))
if !usesLR {
// On x86, call instruction pushes return PC before entering new function.
frame.fp += sys.RegSize
frame.fp += sys.PtrSize
}
}
var flr funcInfo
@ -235,8 +235,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
}
} else {
if frame.lr == 0 {
lrPtr = frame.fp - sys.RegSize
frame.lr = uintptr(*(*sys.Uintreg)(unsafe.Pointer(lrPtr)))
lrPtr = frame.fp - sys.PtrSize
frame.lr = uintptr(*(*uintptr)(unsafe.Pointer(lrPtr)))
}
}
flr = findfunc(frame.lr)
@ -266,13 +266,13 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
frame.varp = frame.fp
if !usesLR {
// On x86, call instruction pushes return PC before entering new function.
frame.varp -= sys.RegSize
frame.varp -= sys.PtrSize
}
// For architectures with frame pointers, if there's
// a frame, then there's a saved frame pointer here.
if frame.varp > frame.sp && (GOARCH == "amd64" || GOARCH == "arm64") {
frame.varp -= sys.RegSize
frame.varp -= sys.PtrSize
}
// Derive size of arguments.
@ -490,11 +490,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
// before faking a call.
if usesLR && injectedCall {
x := *(*uintptr)(unsafe.Pointer(frame.sp))
frame.sp += sys.MinFrameSize
if GOARCH == "arm64" {
// arm64 needs 16-byte aligned SP, always
frame.sp += sys.PtrSize
}
frame.sp += alignUp(sys.MinFrameSize, sys.StackAlign)
f = findfunc(frame.pc)
frame.fn = f
if !f.valid() {