[lld] a04a507 - [lld][WebAssembly] Fix crash accessing non-live __tls_base symbol

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 17 14:02:36 PDT 2022


Author: Sam Clegg
Date: 2022-03-17T13:59:45-07:00
New Revision: a04a5077140b6699938a73643f71d00d9748ec7e

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

LOG: [lld][WebAssembly] Fix crash accessing non-live __tls_base symbol

In programs that don't otherwise depend on `__tls_base` it won't
be marked as live.  However this symbol is used internally in
a couple of places do we need to mark it as live explictily in
those places.

Fixes: #54386

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

Added: 
    lld/test/wasm/tls_init_symbols.s

Modified: 
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/tls_init_symbols.s b/lld/test/wasm/tls_init_symbols.s
new file mode 100644
index 0000000000000..1470e0658e008
--- /dev/null
+++ b/lld/test/wasm/tls_init_symbols.s
@@ -0,0 +1,69 @@
+# Regression test based on https://github.com/llvm/llvm-project/issues/54386
+# Test that that linker synthetic functions such as __wasm_tls_init and
+# __wasm_apply_global_tls_relocs can be created successfully in programs
+# that don't reference __tls_base or __wasm_tls_init.  These function both
+# reference __tls_base which need to be marks as alive if they are generated.
+
+# This is very basic TLS-using program that doesn't reference any of the
+# linker-generated symbols.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld -no-gc-sections --shared-memory -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  global.get tls_sym at GOT@TLS
+  end_function
+
+.section  .tdata.tls_sym,"",@
+.globl  tls_sym
+.p2align  2
+tls_sym:
+  .int32  1
+  .size tls_sym, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+
+# CHECK:       - Type:            CUSTOM
+# CHECK-NEXT:    Name:            name
+# CHECK-NEXT:    FunctionNames:
+# CHECK-NEXT:      - Index:           0
+# CHECK-NEXT:        Name:            __wasm_call_ctors
+# CHECK-NEXT:      - Index:           1
+# CHECK-NEXT:        Name:            __wasm_init_tls
+# CHECK-NEXT:      - Index:           2
+# CHECK-NEXT:        Name:            __wasm_apply_global_tls_relocs
+# CHECK-NEXT:      - Index:           3
+# CHECK-NEXT:        Name:            _start
+
+# DIS:       <__wasm_init_tls>:
+# DIS:        local.get 0
+# DIS-NEXT:   global.set  1
+# DIS-NEXT:   local.get 0
+# DIS-NEXT:   i32.const 0
+# DIS-NEXT:   i32.const 4
+# DIS-NEXT:   memory.init 0, 0
+# DIS-NEXT:   call  2
+# DIS-NEXT:   end
+
+# DIS:      <__wasm_apply_global_tls_relocs>:
+# DIS:        global.get  1
+# DIS-NEXT:   i32.const 0
+# DIS-NEXT:   i32.add
+# DIS-NEXT:   global.set  4
+# DIS-NEXT:   end
+
+# DIS:      <_start>:
+# DIS:        global.get  4
+# DIS-NEXT:   end
+

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 95e9ab810efa5..fa5b8d5db0e80 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -1010,6 +1010,8 @@ void Writer::createSyntheticInitFunctions() {
         make<SyntheticFunction>(nullSignature,
                                 "__wasm_apply_global_tls_relocs"));
     WasmSym::applyGlobalTLSRelocs->markLive();
+    // TLS relocations depend on  the __tls_base symbols
+    WasmSym::tlsBase->markLive();
   }
 
   if (config->isPic ||
@@ -1438,6 +1440,7 @@ void Writer::createInitTLSFunction() {
 
       writeU8(os, WASM_OPCODE_GLOBAL_SET, "global.set");
       writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "global index");
+      WasmSym::tlsBase->markLive();
 
       // FIXME(wvo): this local needs to be I64 in wasm64, or we need an extend op.
       writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");


        


More information about the llvm-commits mailing list