aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2021-02-04 11:41:34 -0500
committerCherry Zhang <cherryyz@google.com>2021-02-08 17:48:48 +0000
commit22f9e1ccbc9db9a1d9ecbadca972264e5ad2f169 (patch)
tree0ca9252b1e3287d4f6ff77ef6c429df0dae5bb77 /src/runtime
parent5d7dc53888c3c91ef4122d584a064bc24b6f7540 (diff)
downloadgo-22f9e1ccbc9db9a1d9ecbadca972264e5ad2f169.tar.xz
[dev.regabi] runtime: initialize special registers before sigpanic
In case that we are panicking in ABI0 context or external code, special registers are not initialized. Initialized them in injected code before calling sigpanic. TODO: Windows, Plan 9. Change-Id: I0919b80e7cc55463f3dd94f1f63cba305717270a Reviewed-on: https://go-review.googlesource.com/c/go/+/289710 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm.s5
-rw-r--r--src/runtime/asm_amd64.s12
-rw-r--r--src/runtime/signal_amd64.go7
-rw-r--r--src/runtime/stubs.go4
4 files changed, 26 insertions, 2 deletions
diff --git a/src/runtime/asm.s b/src/runtime/asm.s
index 27d8df9e06..72c744925d 100644
--- a/src/runtime/asm.s
+++ b/src/runtime/asm.s
@@ -11,3 +11,8 @@
DATA runtime·no_pointers_stackmap+0x00(SB)/4, $2
DATA runtime·no_pointers_stackmap+0x04(SB)/4, $0
GLOBL runtime·no_pointers_stackmap(SB),RODATA, $8
+
+#ifndef GOARCH_amd64
+TEXT ·sigpanic0<ABIInternal>(SB),NOSPLIT,$0-0
+ JMP ·sigpanic<ABIInternal>(SB)
+#endif
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 9f15990b13..83c08a52f7 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -1364,6 +1364,18 @@ TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
POPQ R15
RET
+// Initialize special registers then jump to sigpanic.
+// This function is injected from the signal handler for panicking
+// signals. It is quite painful to set X15 in the signal context,
+// so we do it here.
+TEXT ·sigpanic0<ABIInternal>(SB),NOSPLIT,$0-0
+#ifdef GOEXPERIMENT_REGABI
+ get_tls(R14)
+ MOVQ g(R14), R14
+ XORPS X15, X15
+#endif
+ JMP ·sigpanic<ABIInternal>(SB)
+
// gcWriteBarrier performs a heap pointer write and informs the GC.
//
// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
diff --git a/src/runtime/signal_amd64.go b/src/runtime/signal_amd64.go
index 6ab1f758c2..3eeb5e044f 100644
--- a/src/runtime/signal_amd64.go
+++ b/src/runtime/signal_amd64.go
@@ -65,11 +65,14 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
pc := uintptr(c.rip())
sp := uintptr(c.rsp())
+ // In case we are panicking from external code, we need to initialize
+ // Go special registers. We inject sigpanic0 (instead of sigpanic),
+ // which takes care of that.
if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
- c.pushCall(funcPC(sigpanic), pc)
+ c.pushCall(funcPC(sigpanic0), pc)
} else {
// Not safe to push the call. Just clobber the frame.
- c.set_rip(uint64(funcPC(sigpanic)))
+ c.set_rip(uint64(funcPC(sigpanic0)))
}
}
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index 36bbc8991a..3d1e0c0bb4 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -356,3 +356,7 @@ func duffcopy()
// Called from linker-generated .initarray; declared for go vet; do NOT call from Go.
func addmoduledata()
+
+// Injected by the signal handler for panicking signals. On many platforms it just
+// jumps to sigpanic.
+func sigpanic0()