limit int // limit on entry to sym
}
-var (
- morestack *LSym
- newstack *LSym
-)
+var morestack *LSym
// TODO: Record enough information in new object files to
// allow stack checks here.
var ch Chain
morestack = Linklookup(Ctxt, "runtime.morestack", 0)
- newstack = Linklookup(Ctxt, "runtime.newstack", 0)
// Every splitting function ensures that there are at least StackLimit
// bytes available below SP when the splitting prologue finishes.
// Don't duplicate work: only need to consider each
// function at top of safe zone once.
- if limit == obj.StackLimit-callsize() {
+ top := limit == obj.StackLimit-callsize()
+ if top {
if s.Stkcheck != 0 {
return 0
}
var ch Chain
ch.up = up
- // Check for a call to morestack anywhere and treat it
- // as occurring at function entry.
- // The decision about whether to call morestack occurs
- // in the prolog, but the call site is near the end
- // of the function on some architectures.
- // This is needed because the stack check is flow-insensitive,
- // so it incorrectly thinks the call to morestack happens wherever it shows up.
- // This check will be wrong if there are any hand-inserted calls to morestack.
- // There are not any now, nor should there ever be.
- for _, r := range s.R {
- if r.Sym == nil || !strings.HasPrefix(r.Sym.Name, "runtime.morestack") {
- continue
- }
- // Ignore non-calls to morestack, such as the jump to morestack
- // found in the implementation of morestack_noctxt.
- switch r.Type {
- default:
- continue
- case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER:
- }
-
+ if s.Nosplit == 0 {
// Ensure we have enough stack to call morestack.
ch.limit = limit - callsize()
- ch.sym = r.Sym
+ ch.sym = morestack
if stkcheck(&ch, depth+1) < 0 {
return -1
}
- // Bump up the limit.
+ if !top {
+ return 0
+ }
+ // Raise limit to allow frame.
limit = int(obj.StackLimit + s.Locals)
if haslinkregister() {
limit += Thearch.Regsize
}
- break // there can be only one
}
// Walk through sp adjustments in function, consuming relocs.
switch r.Type {
// Direct call.
case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER:
- // We handled calls to morestack already.
- if strings.HasPrefix(r.Sym.Name, "runtime.morestack") {
- continue
- }
-
ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
ch.sym = r.Sym
if stkcheck(&ch, depth+1) < 0 {
if ch.sym != nil {
name = ch.sym.Name
+ if ch.sym.Nosplit != 0 {
+ name += " (nosplit)"
+ }
} else {
name = "function pointer"
}