aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-03-05 14:24:44 -0500
committerRuss Cox <rsc@golang.org>2011-03-05 14:24:44 -0500
commit11695596588172331984de8a443eedbd44c56bd5 (patch)
tree1f05065d8cdee241664e53b9c8aac5c3dca66609
parentd42bfe26ad003cf2c29dc1b8cf21026f4a2a8fb9 (diff)
downloadgo-11695596588172331984de8a443eedbd44c56bd5.tar.gz
go-11695596588172331984de8a443eedbd44c56bd5.zip
cgo: use correct frame size for 0 arguments
Passing a frame size of 1 was causing the cgo callback to push 1 byte of arguments onto the stack, making the stack pointer misaligned, which had the effect of hiding all the pointers on the stack from the garbage collector. SWIG only wraps calls to C++ virtual methods, so it always has at least 1 argument, so SWIG does not need to be fixed too. Fixes #1328. R=iant CC=golang-dev https://golang.org/cl/4261046
-rw-r--r--src/cmd/cgo/out.go7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 279a9c15c7..4d903dbeeb 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -180,7 +180,6 @@ func (p *Package) structType(n *Name) (string, int64) {
}
if off == 0 {
fmt.Fprintf(&buf, "\t\tchar unused;\n") // avoid empty struct
- off++
}
fmt.Fprintf(&buf, "\t}")
return buf.String(), off
@@ -225,6 +224,9 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
fmt.Fprintf(fc, "void _cgo%s%s(void*);\n", cPrefix, n.Mangle)
fmt.Fprintf(fc, "\n")
fmt.Fprintf(fc, "void\n")
+ if argSize == 0 {
+ argSize++
+ }
fmt.Fprintf(fc, "·%s(struct{uint8 x[%d];}p)\n", n.Mangle, argSize)
fmt.Fprintf(fc, "{\n")
fmt.Fprintf(fc, "\truntime·cgocall(_cgo%s%s, &p);\n", cPrefix, n.Mangle)
@@ -392,7 +394,6 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
}
if ctype == "struct {\n" {
ctype += "\t\tchar unused;\n" // avoid empty struct
- off++
}
ctype += "\t}"
@@ -444,7 +445,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
func(i int, atype ast.Expr) {
fmt.Fprintf(fgcc, "\ta.p%d = p%d;\n", i, i)
})
- fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &a, (int) sizeof a);\n", cPrefix, exp.ExpName)
+ fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &a, %d);\n", cPrefix, exp.ExpName, off)
if gccResult != "void" {
if len(fntype.Results.List) == 1 && len(fntype.Results.List[0].Names) <= 1 {
fmt.Fprintf(fgcc, "\treturn a.r0;\n")