aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Randall <keithr@alum.mit.edu>2018-10-04 16:32:21 -0700
committerKeith Randall <khr@golang.org>2018-10-05 03:29:58 +0000
commit48e22da1d24dc5b038bd83a78553173af5474e76 (patch)
treea93491bfa3d6c2a7bd44f465ee5c2c028f870bd2 /src
parent1bca6cecc627cd708c6c5440eb14f84a99d5324b (diff)
downloadgo-48e22da1d24dc5b038bd83a78553173af5474e76.tar.xz
cmd/link: fix deferreturn location on wasm
On wasm, pcln tables are indexed by "resumption point ID" instead of by pc offset. When finding a deferreturn call, we must find the associated resumption point ID for the deferreturn call. Update #27518 Fixes wasm bug introduced in CL 134637. Change-Id: I3d178a3f5203a06c0180a1aa2309bfb7f3014f0f Reviewed-on: https://go-review.googlesource.com/c/139898 Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/link/internal/ld/pcln.go24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 24398fcc87..3eb3d05882 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/src"
+ "cmd/internal/sys"
"cmd/link/internal/sym"
"log"
"os"
@@ -314,13 +315,26 @@ func (ctxt *Link) pclntab() {
// deferreturn
deferreturn := uint32(0)
+ lastWasmAddr := uint32(0)
for _, r := range s.R {
+ if ctxt.Arch.Family == sys.Wasm && r.Type == objabi.R_ADDR {
+ // Wasm does not have a live variable set at the deferreturn
+ // call itself. Instead it has one identified by the
+ // resumption point immediately preceding the deferreturn.
+ // The wasm code has a R_ADDR relocation which is used to
+ // set the resumption point to PC_B.
+ lastWasmAddr = uint32(r.Add)
+ }
if r.Sym != nil && r.Sym.Name == "runtime.deferreturn" && r.Add == 0 {
- // Note: the relocation target is in the call instruction, but
- // is not necessarily the whole instruction (for instance, on
- // x86 the relocation applies to bytes [1:5] of the 5 byte call
- // instruction).
- deferreturn = uint32(r.Off)
+ if ctxt.Arch.Family == sys.Wasm {
+ deferreturn = lastWasmAddr
+ } else {
+ // Note: the relocation target is in the call instruction, but
+ // is not necessarily the whole instruction (for instance, on
+ // x86 the relocation applies to bytes [1:5] of the 5 byte call
+ // instruction).
+ deferreturn = uint32(r.Off)
+ }
break // only need one
}
}