if Ctxt.FixedFrameSize() == 0 {
offs -= int64(Widthptr)
}
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) || objabi.GOARCH == "arm64" {
+ if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
// There is a word space for FP on ARM64 even if the frame pointer is disabled
offs -= int64(Widthptr)
}
if Ctxt.FixedFrameSize() == 0 {
base -= int64(Widthptr)
}
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) || objabi.GOARCH == "arm64" {
+ if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
// There is a word space for FP on ARM64 even if the frame pointer is disabled
base -= int64(Widthptr)
}
if s.f.Config.hasGReg {
s.allocatable &^= 1 << s.GReg
}
- if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
+ if objabi.Framepointer_enabled && s.f.Config.FPReg >= 0 {
s.allocatable &^= 1 << uint(s.f.Config.FPReg)
}
if s.f.Config.LinkReg != -1 {
prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd)
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
q1 = obj.Appendp(q1, c.newprog)
q1.Pos = p.Pos
q1.As = AMOVD
p.To.Reg = REGSP
p.Spadj = -c.autosize
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
p = obj.Appendp(p, c.newprog)
p.As = ASUB
p.From.Type = obj.TYPE_CONST
} else {
/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGSP
}
case obj.ADUFFCOPY:
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
// ADR ret_addr, R27
// STP (FP, R27), -24(SP)
// SUB 24, SP, FP
}
case obj.ADUFFZERO:
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
// ADR ret_addr, R27
// STP (FP, R27), -24(SP)
// SUB 24, SP, FP
GenAbstractFunc func(fn *LSym)
Errors int
- InParallel bool // parallel backend phase in effect
- Framepointer_enabled bool
- UseBASEntries bool // use Base Address Selection Entries in location lists and PC ranges
- IsAsm bool // is the source assembly language, which may contain surprising idioms (e.g., call tables)
+ InParallel bool // parallel backend phase in effect
+ UseBASEntries bool // use Base Address Selection Entries in location lists and PC ranges
+ IsAsm bool // is the source assembly language, which may contain surprising idioms (e.g., call tables)
// state for writing objects
Text []*LSym
}
ctxt.Flag_optimize = true
- ctxt.Framepointer_enabled = objabi.Framepointer_enabled(objabi.GOOS, arch.Name)
return ctxt
}
ctxt.Diag("directly calling duff when dynamically linking Go")
}
- if ctxt.Framepointer_enabled && yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
+ if yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
// Maintain BP around call, since duffcopy/duffzero can't do it
// (the call jumps into the middle of the function).
// This makes it possible to see call sites for duffcopy/duffzero in
// BP-based profiling tools like Linux perf (which is the
- // whole point of obj.Framepointer_enabled).
+ // whole point of maintaining frame pointers in Go).
// MOVQ BP, -16(SP)
// LEAQ -16(SP), BP
ab.Put(bpduff1)
r.Siz = 4
ab.PutInt32(0)
- if ctxt.Framepointer_enabled && yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
+ if yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
// Pop BP pushed above.
// MOVQ 0(BP), BP
ab.Put(bpduff2)
}
var bpsize int
- if ctxt.Arch.Family == sys.AMD64 && ctxt.Framepointer_enabled &&
+ if ctxt.Arch.Family == sys.AMD64 &&
!p.From.Sym.NoFrame() && // (1) below
!(autoffset == 0 && p.From.Sym.NoSplit()) && // (2) below
!(autoffset == 0 && !hasCall) { // (3) below
}
}
-func Framepointer_enabled(goos, goarch string) bool {
- return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin"))
-}
+// Note: must agree with runtime.framepointer_enabled.
+var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin")
func addexp(s string) {
// Could do general integer parsing here, but the runtime copy doesn't yet.
}
var (
- framepointer_enabled int = 1
Fieldtrack_enabled int
Preemptibleloops_enabled int
Staticlockranking_enabled int
val *int
}{
{"fieldtrack", &Fieldtrack_enabled},
- {"framepointer", &framepointer_enabled},
{"preemptibleloops", &Preemptibleloops_enabled},
{"staticlockranking", &Staticlockranking_enabled},
}
sb.SetSize(0)
sb.AddUint8(uint8(objabi.GOARM))
}
-
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
- fpe := ctxt.loader.LookupOrCreateSym("runtime.framepointer_enabled", 0)
- sb := ctxt.loader.MakeSymbolUpdater(fpe)
- sb.SetType(sym.SNOPTRDATA)
- sb.SetSize(0)
- sb.AddUint8(1)
- }
} else {
// If OTOH the module does not contain the runtime package,
// create a local symbol for the moduledata.
// Additional two words (16-byte alignment) are for saving FP.
cb = (*args)(unsafe.Pointer(sp + 7*sys.PtrSize))
case "amd64":
- // On amd64, stack frame is two words, plus caller PC.
- if framepointer_enabled {
- // In this case, there's also saved BP.
- cb = (*args)(unsafe.Pointer(sp + 4*sys.PtrSize))
- break
- }
- cb = (*args)(unsafe.Pointer(sp + 3*sys.PtrSize))
+ // On amd64, stack frame is two words, plus caller PC and BP.
+ cb = (*args)(unsafe.Pointer(sp + 4*sys.PtrSize))
case "386":
// On 386, stack frame is three words, plus caller PC.
cb = (*args)(unsafe.Pointer(sp + 4*sys.PtrSize))
}
func haveexperiment(name string) bool {
- if name == "framepointer" {
- return framepointer_enabled // set by linker
- }
x := sys.Goexperiment
for x != "" {
xname := ""
ctxt unsafe.Pointer
ret sys.Uintreg
lr uintptr
- bp uintptr // for GOEXPERIMENT=framepointer
+ bp uintptr // for framepointer-enabled architectures
}
// sudog represents a g in a wait list, such as for sending/receiving
isIntel bool
lfenceBeforeRdtsc bool
- goarm uint8 // set by cmd/link on arm systems
- framepointer_enabled bool // set by cmd/link
+ goarm uint8 // set by cmd/link on arm systems
)
// Set by the linker so the runtime can determine the buildmode.
islibrary bool // -buildmode=c-shared
isarchive bool // -buildmode=c-archive
)
+
+// Must agree with cmd/internal/objabi.Framepointer_enabled.
+const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin")
}
// 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 !framepointer_enabled {
- print("runtime: found space for saved base pointer, but no framepointer experiment\n")
- print("argp=", hex(frame.argp), " varp=", hex(frame.varp), "\n")
- throw("bad frame layout")
- }
if stackDebug >= 3 {
print(" saved bp\n")
}
frame.varp -= sys.RegSize
}
- // If framepointer_enabled and there's a frame, then
- // there's a saved bp here.
- if frame.varp > frame.sp && (framepointer_enabled && GOARCH == "amd64" || GOARCH == "arm64") {
+ // 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
}