[llvm] 9c7b580 - [WebAssembly][MC] Fix computation of relative symbol offset

Dominic Chen via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 21:53:41 PDT 2020


Author: Dominic Chen
Date: 2020-09-22T00:53:23-04:00
New Revision: 9c7b58080ebd7ad3a63b892b5ae7f92e41587327

URL: https://github.com/llvm/llvm-project/commit/9c7b58080ebd7ad3a63b892b5ae7f92e41587327
DIFF: https://github.com/llvm/llvm-project/commit/9c7b58080ebd7ad3a63b892b5ae7f92e41587327.diff

LOG: [WebAssembly][MC] Fix computation of relative symbol offset

For relative symbols, add its offset when computing relocation value.
Also, warn on unsupported absolute symbols.

Differential Revision: https://reviews.llvm.org/D87407

Added: 
    llvm/test/MC/WebAssembly/alias-offset.s

Modified: 
    llvm/lib/MC/WasmObjectWriter.cpp

Removed: 
    llvm/test/MC/WebAssembly/offset.s


################################################################################
diff  --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 32541e5e4ff8..ca6230f74eb1 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -614,16 +614,17 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
   case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
   case wasm::R_WASM_MEMORY_ADDR_I32:
   case wasm::R_WASM_MEMORY_ADDR_I64: {
-    // Provisional value is address of the global
+    // Provisional value is address of the global plus the offset
     const MCSymbolWasm *Base =
         cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol));
     // For undefined symbols, use zero
     if (!Base->isDefined())
       return 0;
-    const wasm::WasmDataReference &Ref = DataLocations[Base];
-    const WasmDataSegment &Segment = DataSegments[Ref.Segment];
+    const wasm::WasmDataReference &BaseRef = DataLocations[Base],
+                                  &SymRef = DataLocations[RelEntry.Symbol];
+    const WasmDataSegment &Segment = DataSegments[BaseRef.Segment];
     // Ignore overflow. LLVM allows address arithmetic to silently wrap.
-    return Segment.Offset + Ref.Offset + RelEntry.Addend;
+    return Segment.Offset + BaseRef.Offset + SymRef.Offset + RelEntry.Addend;
   }
   default:
     llvm_unreachable("invalid relocation type");
@@ -1230,8 +1231,11 @@ void WasmObjectWriter::prepareImports(
     // Register types for all functions, including those with private linkage
     // (because wasm always needs a type signature).
     if (WS.isFunction()) {
-      const MCSymbolWasm *Base = cast<MCSymbolWasm>(Layout.getBaseSymbol(S));
-      registerFunctionType(*Base);
+      const auto *BS = Layout.getBaseSymbol(S);
+      if (!BS)
+        report_fatal_error(Twine(S.getName()) +
+                           ": absolute addressing not supported!");
+      registerFunctionType(*cast<MCSymbolWasm>(BS));
     }
 
     if (WS.isEvent())
@@ -1565,7 +1569,11 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
 
     assert(S.isDefined());
 
-    const MCSymbolWasm *Base = cast<MCSymbolWasm>(Layout.getBaseSymbol(S));
+    const auto *BS = Layout.getBaseSymbol(S);
+    if (!BS)
+      report_fatal_error(Twine(S.getName()) +
+                         ": absolute addressing not supported!");
+    const MCSymbolWasm *Base = cast<MCSymbolWasm>(BS);
 
     // Find the target symbol of this weak alias and export that index
     const auto &WS = static_cast<const MCSymbolWasm &>(S);

diff  --git a/llvm/test/MC/WebAssembly/alias-offset.s b/llvm/test/MC/WebAssembly/alias-offset.s
new file mode 100644
index 000000000000..93dbe21c3f9b
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/alias-offset.s
@@ -0,0 +1,34 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj %s | llvm-objdump --triple=wasm32-unknown-unknown -d -t -r - | FileCheck %s
+
+  .section    .data,"",@
+foo:
+  .int32 0
+  .size foo, 4
+sym_a:
+  .int32 1
+  .int32 2
+  .size sym_a, 8
+
+.set sym_b, sym_a + 4
+
+# CHECK-LABEL: SYMBOL TABLE:
+# CHECK-NEXT: 00000000 l     O DATA foo
+# CHECK-NEXT: 00000004 l     O DATA sym_a
+# CHECK-NEXT: 00000008 l     O DATA sym_b
+# CHECK-NEXT: 00000001 l     F CODE main
+
+  .text
+  .section    .text,"",@
+main:
+  .functype   main () -> ()
+  i32.const sym_a
+  i32.store sym_b
+  end_function
+
+# CHECK-LABEL: <main>:
+# CHECK-EMPTY:
+# CHECK-NEXT:       3: 41 88 80 80 80 00     i32.const       8
+# CHECK-NEXT:                        00000004:  R_WASM_MEMORY_ADDR_SLEB      sym_a+0
+# CHECK-NEXT:       9: 36 02 8c 80 80 80 00  i32.store       12
+# CHECK-NEXT:                        0000000b:  R_WASM_MEMORY_ADDR_LEB      sym_b+0
+# CHECK-NEXT:      10: 0b            end

diff  --git a/llvm/test/MC/WebAssembly/offset.s b/llvm/test/MC/WebAssembly/offset.s
deleted file mode 100644
index cf3f521dd366..000000000000
--- a/llvm/test/MC/WebAssembly/offset.s
+++ /dev/null
@@ -1,16 +0,0 @@
-# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj %s | llvm-objdump -t - | FileCheck %s
-
-.section    .data,"",@
-foo:
-  .int32 0
-  .size foo, 4
-sym_a:
-  .int32 1
-  .int32 2
-  .size sym_a, 8
-
-.set sym_b, sym_a + 4
-
-# CHECK: 00000000 l     O DATA foo
-# CHECK: 00000004 l     O DATA sym_a
-# CHECK: 00000008 l     O DATA sym_b


        


More information about the llvm-commits mailing list