aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/runtime/signal_386.go25
-rw-r--r--src/runtime/signal_amd64.go26
-rw-r--r--src/runtime/signal_arm.go6
-rw-r--r--src/runtime/signal_arm64.go6
-rw-r--r--src/runtime/signal_linux_s390x.go6
-rw-r--r--src/runtime/signal_mips64x.go6
-rw-r--r--src/runtime/signal_mipsx.go6
-rw-r--r--src/runtime/signal_ppc64x.go6
8 files changed, 69 insertions, 18 deletions
diff --git a/src/runtime/signal_386.go b/src/runtime/signal_386.go
index ef97979796..2670dc850d 100644
--- a/src/runtime/signal_386.go
+++ b/src/runtime/signal_386.go
@@ -57,14 +57,21 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
sp := uintptr(c.esp())
if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
- // Make it look like the faulting PC called sigpanic.
- if sys.RegSize > sys.PtrSize {
- sp -= sys.PtrSize
- *(*uintptr)(unsafe.Pointer(sp)) = 0
- }
- sp -= sys.PtrSize
- *(*uintptr)(unsafe.Pointer(sp)) = pc
- c.set_esp(uint32(sp))
+ c.pushCall(funcPC(sigpanic))
+ } else {
+ // Not safe to push the call. Just clobber the frame.
+ c.set_eip(uint32(funcPC(sigpanic)))
}
- c.set_eip(uint32(funcPC(sigpanic)))
+}
+
+const pushCallSupported = true
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ // Make it look like the signaled instruction called target.
+ pc := uintptr(c.eip())
+ sp := uintptr(c.esp())
+ sp -= sys.PtrSize
+ *(*uintptr)(unsafe.Pointer(sp)) = pc
+ c.set_esp(uint32(sp))
+ c.set_eip(uint32(targetPC))
}
diff --git a/src/runtime/signal_amd64.go b/src/runtime/signal_amd64.go
index 9e9bb9ca33..29b6a9e7e6 100644
--- a/src/runtime/signal_amd64.go
+++ b/src/runtime/signal_amd64.go
@@ -66,14 +66,22 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
sp := uintptr(c.rsp())
if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
- // Make it look the like faulting PC called sigpanic.
- if sys.RegSize > sys.PtrSize {
- sp -= sys.PtrSize
- *(*uintptr)(unsafe.Pointer(sp)) = 0
- }
- sp -= sys.PtrSize
- *(*uintptr)(unsafe.Pointer(sp)) = pc
- c.set_rsp(uint64(sp))
+ c.pushCall(funcPC(sigpanic))
+ } else {
+ // Not safe to push the call. Just clobber the frame.
+ c.set_rip(uint64(funcPC(sigpanic)))
}
- c.set_rip(uint64(funcPC(sigpanic)))
+}
+
+// TODO: Remove pushCallSupported once all platforms support it.
+const pushCallSupported = true
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ // Make it look like the signaled instruction called target.
+ pc := uintptr(c.rip())
+ sp := uintptr(c.rsp())
+ sp -= sys.PtrSize
+ *(*uintptr)(unsafe.Pointer(sp)) = pc
+ c.set_rsp(uint64(sp))
+ c.set_rip(uint64(targetPC))
}
diff --git a/src/runtime/signal_arm.go b/src/runtime/signal_arm.go
index 97742206c7..1b3e53d01c 100644
--- a/src/runtime/signal_arm.go
+++ b/src/runtime/signal_arm.go
@@ -62,3 +62,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_r10(uint32(uintptr(unsafe.Pointer(gp))))
c.set_pc(uint32(funcPC(sigpanic)))
}
+
+const pushCallSupported = false
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ throw("not implemented")
+}
diff --git a/src/runtime/signal_arm64.go b/src/runtime/signal_arm64.go
index e1fe62d99d..2341d779da 100644
--- a/src/runtime/signal_arm64.go
+++ b/src/runtime/signal_arm64.go
@@ -78,3 +78,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_r28(uint64(uintptr(unsafe.Pointer(gp))))
c.set_pc(uint64(funcPC(sigpanic)))
}
+
+const pushCallSupported = false
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ throw("not implemented")
+}
diff --git a/src/runtime/signal_linux_s390x.go b/src/runtime/signal_linux_s390x.go
index 6892f63b9f..390ff5db48 100644
--- a/src/runtime/signal_linux_s390x.go
+++ b/src/runtime/signal_linux_s390x.go
@@ -109,3 +109,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_r13(uint64(uintptr(unsafe.Pointer(gp))))
c.set_pc(uint64(funcPC(sigpanic)))
}
+
+const pushCallSupported = false
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ throw("not implemented")
+}
diff --git a/src/runtime/signal_mips64x.go b/src/runtime/signal_mips64x.go
index 1b9684295e..3f1992c711 100644
--- a/src/runtime/signal_mips64x.go
+++ b/src/runtime/signal_mips64x.go
@@ -84,3 +84,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
c.set_pc(sigpanicPC)
}
+
+const pushCallSupported = false
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ throw("not implemented")
+}
diff --git a/src/runtime/signal_mipsx.go b/src/runtime/signal_mipsx.go
index e223c28402..6b5ed2872d 100644
--- a/src/runtime/signal_mipsx.go
+++ b/src/runtime/signal_mipsx.go
@@ -79,3 +79,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_r30(uint32(uintptr(unsafe.Pointer(gp))))
c.set_pc(uint32(funcPC(sigpanic)))
}
+
+const pushCallSupported = false
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ throw("not implemented")
+}
diff --git a/src/runtime/signal_ppc64x.go b/src/runtime/signal_ppc64x.go
index cac1a23c9f..7befad40d2 100644
--- a/src/runtime/signal_ppc64x.go
+++ b/src/runtime/signal_ppc64x.go
@@ -85,3 +85,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
c.set_r12(uint64(funcPC(sigpanic)))
c.set_pc(uint64(funcPC(sigpanic)))
}
+
+const pushCallSupported = false
+
+func (c *sigctxt) pushCall(targetPC uintptr) {
+ throw("not implemented")
+}