1
0
mirror of https://github.com/golang/go synced 2024-11-22 03:44:39 -07:00

cmd/6l, cmd/8l: emit no-ops to separate zero-stack funcs from nosplits.

The stack overflow checker in the linker uses the spadj field
to determine whether stack space will be large enough or not.
When spadj=0, the checker treats the function as a nosplit
and emits an error although the program is correct.

Also enable the stack checker in 8l.

Fixes #4316.

R=rsc, golang-dev
CC=golang-dev
https://golang.org/cl/6855088
This commit is contained in:
Rémy Oudompheng 2012-11-26 21:51:48 +01:00
parent d7b0271065
commit 2e73453aca
4 changed files with 85 additions and 0 deletions

View File

@ -604,6 +604,16 @@ dostkoff(void)
p->spadj = autoffset;
if(q != P)
q->pcond = p;
} else {
// zero-byte stack adjustment.
// Insert a fake non-zero adjustment so that stkcheck can
// recognize the end of the stack-splitting prolog.
p = appendp(p);
p->as = ANOP;
p->spadj = -PtrSize;
p = appendp(p);
p->as = ANOP;
p->spadj = PtrSize;
}
deltasp = autoffset;

View File

@ -308,6 +308,7 @@ main(int argc, char *argv[])
if(HEADTYPE == Hwindows)
dope();
dostkoff();
dostkcheck();
if(debug['p'])
if(debug['1'])
doprof1();

View File

@ -580,6 +580,16 @@ dostkoff(void)
p->spadj = autoffset;
if(q != P)
q->pcond = p;
} else {
// zero-byte stack adjustment.
// Insert a fake non-zero adjustment so that stkcheck can
// recognize the end of the stack-splitting prolog.
p = appendp(p);
p->as = ANOP;
p->spadj = -PtrSize;
p = appendp(p);
p->as = ANOP;
p->spadj = PtrSize;
}
deltasp = autoffset;

View File

@ -0,0 +1,64 @@
// run
// Copyright 2012 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.
// Issue 4316: the stack overflow check in the linker
// is confused when it encounters a split-stack function
// that needs 0 bytes of stack space.
package main
type Peano *Peano
func makePeano(n int) *Peano {
if n == 0 {
return nil
}
p := Peano(makePeano(n - 1))
return &p
}
var countArg Peano
var countResult int
func countPeano() {
if countArg == nil {
countResult = 0
return
}
countArg = *countArg
countPeano()
countResult++
}
var s = "(())"
var pT = 0
func p() {
if pT >= len(s) {
return
}
if s[pT] == '(' {
pT += 1
p()
if pT < len(s) && s[pT] == ')' {
pT += 1
} else {
return
}
p()
}
}
func main() {
countArg = makePeano(4096)
countPeano()
if countResult != 4096 {
println("countResult =", countResult)
panic("countResult != 4096")
}
p()
}