]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix deferreturn location on wasm
authorKeith Randall <keithr@alum.mit.edu>
Thu, 4 Oct 2018 23:32:21 +0000 (16:32 -0700)
committerKeith Randall <khr@golang.org>
Fri, 5 Oct 2018 03:29:58 +0000 (03:29 +0000)
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>
src/cmd/link/internal/ld/pcln.go

index 24398fcc872e0dd913c1216de0e75472df031af6..3eb3d058824f79400acb09d2ea2533e68896c883 100644 (file)
@@ -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
                        }
                }