]> Cypherpunks repositories - gostls13.git/commitdiff
test: workaround SIGILL on issue11656 on aix
authorPaul E. Murphy <murp@ibm.com>
Mon, 10 Jan 2022 16:57:16 +0000 (10:57 -0600)
committerPaul Murphy <murp@ibm.com>
Tue, 11 Jan 2022 15:28:40 +0000 (15:28 +0000)
For some reason, aix sometimes executes the bogus function body. This
should never happen as it lives in a no-execute section. It might be
a transient permission blip as the heap grows.

Add a small function to cleanup and synchronize the icache before
jumping to the bogus function to ensure it causes a panic, not SIGILL.

Fixes #44583

Change-Id: Iadca62d82bfb70fc62088705dac42a880a1208fa
Reviewed-on: https://go-review.googlesource.com/c/go/+/377314
Trust: Bryan Mills <bcmills@google.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
test/fixedbugs/issue11656.dir/asm.go [new file with mode: 0644]
test/fixedbugs/issue11656.dir/asm_generic.go [new file with mode: 0644]
test/fixedbugs/issue11656.dir/asm_ppc64.s [new file with mode: 0644]
test/fixedbugs/issue11656.dir/asm_ppc64le.s [new file with mode: 0644]
test/fixedbugs/issue11656.dir/issue11656.go [new file with mode: 0644]
test/fixedbugs/issue11656.go

diff --git a/test/fixedbugs/issue11656.dir/asm.go b/test/fixedbugs/issue11656.dir/asm.go
new file mode 100644 (file)
index 0000000..cdcb064
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright 2022 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.
+
+//go:build ppc64 || ppc64le
+// +build ppc64 ppc64le
+
+package main
+
+func syncIcache(p uintptr)
diff --git a/test/fixedbugs/issue11656.dir/asm_generic.go b/test/fixedbugs/issue11656.dir/asm_generic.go
new file mode 100644 (file)
index 0000000..104d44d
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2022 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.
+
+//go:build !ppc64 && !ppc64le
+// +build !ppc64,!ppc64le
+
+package main
+
+func syncIcache(p uintptr) {
+}
diff --git a/test/fixedbugs/issue11656.dir/asm_ppc64.s b/test/fixedbugs/issue11656.dir/asm_ppc64.s
new file mode 100644 (file)
index 0000000..125a197
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2022 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.
+
+#include "textflag.h"
+
+// func syncIcache(p uintptr)
+TEXT main·syncIcache(SB), NOSPLIT|NOFRAME, $0-0
+       SYNC
+       MOVD (R3), R3
+       ICBI (R3)
+       ISYNC
+       RET
diff --git a/test/fixedbugs/issue11656.dir/asm_ppc64le.s b/test/fixedbugs/issue11656.dir/asm_ppc64le.s
new file mode 100644 (file)
index 0000000..125a197
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2022 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.
+
+#include "textflag.h"
+
+// func syncIcache(p uintptr)
+TEXT main·syncIcache(SB), NOSPLIT|NOFRAME, $0-0
+       SYNC
+       MOVD (R3), R3
+       ICBI (R3)
+       ISYNC
+       RET
diff --git a/test/fixedbugs/issue11656.dir/issue11656.go b/test/fixedbugs/issue11656.dir/issue11656.go
new file mode 100644 (file)
index 0000000..a5a52df
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright 2015 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.
+
+package main
+
+import (
+       "encoding/binary"
+       "runtime"
+       "runtime/debug"
+       "unsafe"
+)
+
+func main() {
+       debug.SetPanicOnFault(true)
+       defer func() {
+               if err := recover(); err == nil {
+                       panic("not panicking")
+               }
+               pc, _, _, _ := runtime.Caller(10)
+               f := runtime.FuncForPC(pc)
+               if f == nil || f.Name() != "main.f" {
+                       if f == nil {
+                               println("no func for ", unsafe.Pointer(pc))
+                       } else {
+                               println("found func:", f.Name())
+                       }
+                       panic("cannot find main.f on stack")
+               }
+       }()
+       f(20)
+}
+
+func f(n int) {
+       if n > 0 {
+               f(n - 1)
+       }
+       var f struct {
+               x uintptr
+       }
+
+       // We want to force a seg fault, to get a crash at a PC value != 0.
+       // Not all systems make the data section non-executable.
+       ill := make([]byte, 64)
+       switch runtime.GOARCH {
+       case "386", "amd64":
+               ill = append(ill[:0], 0x89, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00) // MOVL AX, 0
+       case "arm":
+               binary.LittleEndian.PutUint32(ill[0:4], 0xe3a00000) // MOVW $0, R0
+               binary.LittleEndian.PutUint32(ill[4:8], 0xe5800000) // MOVW R0, (R0)
+       case "arm64":
+               binary.LittleEndian.PutUint32(ill, 0xf90003ff) // MOVD ZR, (ZR)
+       case "ppc64":
+               binary.BigEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
+       case "ppc64le":
+               binary.LittleEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
+       case "mips", "mips64":
+               binary.BigEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
+       case "mipsle", "mips64le":
+               binary.LittleEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
+       case "s390x":
+               ill = append(ill[:0], 0xa7, 0x09, 0x00, 0x00)         // MOVD $0, R0
+               ill = append(ill, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x24) // MOVD R0, (R0)
+       case "riscv64":
+               binary.LittleEndian.PutUint32(ill, 0x00003023) // MOV X0, (X0)
+       default:
+               // Just leave it as 0 and hope for the best.
+       }
+
+       f.x = uintptr(unsafe.Pointer(&ill[0]))
+       p := &f
+       fn := *(*func())(unsafe.Pointer(&p))
+       syncIcache(f.x)
+       fn()
+}
index 85fe720b30b667816908afd72da60d323c3c9837..dba8e354391818b25f028514dd1465a320143ee1 100644 (file)
@@ -1,89 +1,22 @@
-// run
+// runindir
 
-// Copyright 2015 The Go Authors. All rights reserved.
+// Copyright 2022 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 11656: runtime: jump to bad PC missing good traceback
+
 // windows doesn't work, because Windows exception handling
 // delivers signals based on the current PC, and that current PC
 // doesn't go into the Go runtime.
-// +build !windows
 
 // wasm does not work, because the linear memory is not executable.
-// +build !wasm
 
 // This test doesn't work on gccgo/GoLLVM, because they will not find
 // any unwind information for the artificial function, and will not be
 // able to unwind past that point.
-// +build !gccgo
-
-package main
-
-import (
-       "encoding/binary"
-       "runtime"
-       "runtime/debug"
-       "unsafe"
-)
-
-func main() {
-       debug.SetPanicOnFault(true)
-       defer func() {
-               if err := recover(); err == nil {
-                       panic("not panicking")
-               }
-               pc, _, _, _ := runtime.Caller(10)
-               f := runtime.FuncForPC(pc)
-               if f == nil || f.Name() != "main.f" {
-                       if f == nil {
-                               println("no func for ", unsafe.Pointer(pc))
-                       } else {
-                               println("found func:", f.Name())
-                       }
-                       panic("cannot find main.f on stack")
-               }
-       }()
-       f(20)
-}
-
-func f(n int) {
-       if n > 0 {
-               f(n - 1)
-       }
-       var f struct {
-               x uintptr
-       }
 
-       // We want to force a seg fault, to get a crash at a PC value != 0.
-       // Not all systems make the data section non-executable.
-       ill := make([]byte, 64)
-       switch runtime.GOARCH {
-       case "386", "amd64":
-               ill = append(ill[:0], 0x89, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00) // MOVL AX, 0
-       case "arm":
-               binary.LittleEndian.PutUint32(ill[0:4], 0xe3a00000) // MOVW $0, R0
-               binary.LittleEndian.PutUint32(ill[4:8], 0xe5800000) // MOVW R0, (R0)
-       case "arm64":
-               binary.LittleEndian.PutUint32(ill, 0xf90003ff) // MOVD ZR, (ZR)
-       case "ppc64":
-               binary.BigEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
-       case "ppc64le":
-               binary.LittleEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
-       case "mips", "mips64":
-               binary.BigEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
-       case "mipsle", "mips64le":
-               binary.LittleEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
-       case "s390x":
-               ill = append(ill[:0], 0xa7, 0x09, 0x00, 0x00)         // MOVD $0, R0
-               ill = append(ill, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x24) // MOVD R0, (R0)
-       case "riscv64":
-               binary.LittleEndian.PutUint32(ill, 0x00003023) // MOV X0, (X0)
-       default:
-               // Just leave it as 0 and hope for the best.
-       }
+//go:build !windows && !wasm && !gccgo
+// +build !windows,!wasm,!gccgo
 
-       f.x = uintptr(unsafe.Pointer(&ill[0]))
-       p := &f
-       fn := *(*func())(unsafe.Pointer(&p))
-       fn()
-}
+package ignored