mirror of
https://github.com/golang/go
synced 2024-11-22 09:34:54 -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:
parent
d7b0271065
commit
2e73453aca
@ -604,6 +604,16 @@ dostkoff(void)
|
|||||||
p->spadj = autoffset;
|
p->spadj = autoffset;
|
||||||
if(q != P)
|
if(q != P)
|
||||||
q->pcond = 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;
|
deltasp = autoffset;
|
||||||
|
|
||||||
|
@ -308,6 +308,7 @@ main(int argc, char *argv[])
|
|||||||
if(HEADTYPE == Hwindows)
|
if(HEADTYPE == Hwindows)
|
||||||
dope();
|
dope();
|
||||||
dostkoff();
|
dostkoff();
|
||||||
|
dostkcheck();
|
||||||
if(debug['p'])
|
if(debug['p'])
|
||||||
if(debug['1'])
|
if(debug['1'])
|
||||||
doprof1();
|
doprof1();
|
||||||
|
@ -580,6 +580,16 @@ dostkoff(void)
|
|||||||
p->spadj = autoffset;
|
p->spadj = autoffset;
|
||||||
if(q != P)
|
if(q != P)
|
||||||
q->pcond = 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;
|
deltasp = autoffset;
|
||||||
|
|
||||||
|
64
test/fixedbugs/issue4316.go
Normal file
64
test/fixedbugs/issue4316.go
Normal 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()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user