diff options
| author | Keith Randall <keithr@alum.mit.edu> | 2018-10-04 16:32:21 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2018-10-05 03:29:58 +0000 |
| commit | 48e22da1d24dc5b038bd83a78553173af5474e76 (patch) | |
| tree | a93491bfa3d6c2a7bd44f465ee5c2c028f870bd2 /src | |
| parent | 1bca6cecc627cd708c6c5440eb14f84a99d5324b (diff) | |
| download | go-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.go | 24 |
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 } } |
