1
0
mirror of https://github.com/golang/go synced 2024-11-17 14:04:48 -07: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). // unwind of g's stack (see comment at top of file).
mp := acquirem() mp := acquirem()
sched := &mp.g0.sched sched := &mp.g0.sched
switch GOARCH { sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + alignUp(sys.MinFrameSize, sys.StackAlign)))
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))
}
// Do the accounting that cgocall will not have a chance to do // Do the accounting that cgocall will not have a chance to do
// during an unwind. // during an unwind.

View File

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

View File

@ -18,3 +18,41 @@ const (
S390X S390X
WASM 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 package sys
const ( const (
ArchFamily = I386 _ArchFamily = I386
BigEndian = false _DefaultPhysPageSize = 4096
DefaultPhysPageSize = 4096 _PCQuantum = 1
PCQuantum = 1 _MinFrameSize = 0
Int64Align = 4 _StackAlign = PtrSize
MinFrameSize = 0
) )
type Uintreg uint32

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,12 +5,9 @@
package sys package sys
const ( const (
ArchFamily = WASM _ArchFamily = WASM
BigEndian = false _DefaultPhysPageSize = 65536
DefaultPhysPageSize = 65536 _PCQuantum = 1
PCQuantum = 1 _MinFrameSize = 0
Int64Align = 8 _StackAlign = PtrSize
MinFrameSize = 0
) )
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 { if usesLR {
c.setlr(pc) c.setlr(pc)
} else { } else {
if sys.RegSize > sys.PtrSize {
sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = 0
}
sp -= sys.PtrSize sp -= sys.PtrSize
*(*uintptr)(unsafe.Pointer(sp)) = pc *(*uintptr)(unsafe.Pointer(sp)) = pc
c.setsp(sp) c.setsp(sp)

View File

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

View File

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

View File

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

View File

@ -63,7 +63,7 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
// functions are correctly handled. This smashes // functions are correctly handled. This smashes
// the stack frame but we're not going back there // the stack frame but we're not going back there
// anyway. // 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) c.set_sp(sp)
*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr() *(*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. // Adjust saved base pointer if there is one.
// TODO what about arm64 frame pointer adjustment? // 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 { if stackDebug >= 3 {
print(" saved bp\n") print(" saved bp\n")
} }
@ -1245,7 +1245,7 @@ func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) (locals, args
var minsize uintptr var minsize uintptr
switch sys.ArchFamily { switch sys.ArchFamily {
case sys.ARM64: case sys.ARM64:
minsize = sys.SpAlign minsize = sys.StackAlign
default: default:
minsize = sys.MinFrameSize minsize = sys.MinFrameSize
} }

View File

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

View File

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