diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 728e78260cae459f6712cf821d671ddd269b2c73..8ccbec9dd6342c35ae7e7482721bfc715de60299 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1465,10 +1465,7 @@ type Chain struct { 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. @@ -1488,7 +1485,6 @@ func dostkcheck() { 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. @@ -1533,7 +1529,8 @@ func stkcheck(up *Chain, depth int) int { // 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 } @@ -1571,39 +1568,21 @@ func stkcheck(up *Chain, depth int) int { 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. @@ -1628,11 +1607,6 @@ func stkcheck(up *Chain, depth int) int { 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 { @@ -1670,6 +1644,9 @@ func stkprint(ch *Chain, limit int) { if ch.sym != nil { name = ch.sym.Name + if ch.sym.Nosplit != 0 { + name += " (nosplit)" + } } else { name = "function pointer" }