[lld] bda8b84 - [lld][WebAssembly] Disallow exporting of TLS symbols

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon May 10 10:05:42 PDT 2021


Author: Sam Clegg
Date: 2021-05-10T09:58:44-07:00
New Revision: bda8b8488442215e0557a53016a8d9c0a36b90c5

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

LOG: [lld][WebAssembly] Disallow exporting of TLS symbols

Cross module TLS is currently not supported by our ABI.  This
change makes explicitly exporting a TLS symbol into an error
and prevents implicit exporting (via --export-all).

See https://github.com/emscripten-core/emscripten/issues/14120

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

Added: 
    lld/test/wasm/tls-export.s

Modified: 
    lld/wasm/InputChunks.h
    lld/wasm/InputFiles.cpp
    lld/wasm/OutputSegment.h
    lld/wasm/Relocations.cpp
    lld/wasm/Symbols.cpp
    lld/wasm/Symbols.h
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/tls-export.s b/lld/test/wasm/tls-export.s
new file mode 100644
index 0000000000000..b8a36aa55aa1b
--- /dev/null
+++ b/lld/test/wasm/tls-export.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld -no-gc-sections --shared-memory --no-entry -o %t.wasm %t.o
+# RUN: not wasm-ld --shared-memory --no-entry --export=tls1 -o %t.wasm %t.o 2>&1 | FileCheck %s
+# With --export-all we ignore TLS symbols so we don't expect an error here
+# RUN: wasm-ld --shared-memory --no-entry --export-all -o %t.wasm %t.o
+
+# CHECK: error: TLS symbols cannot yet be exported: `tls1`
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+.p2align  2
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 3
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 15
+  .ascii "mutable-globals"

diff  --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index fe30fea62d1cc..f17751b312931 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -117,6 +117,9 @@ class InputSegment : public InputChunk {
   const OutputSegment *outputSeg = nullptr;
   uint32_t outputSegmentOffset = 0;
   uint32_t alignment = 0;
+  bool isTLS() {
+    return getName().startswith(".tdata") || getName().startswith(".tbss");
+  }
 
 protected:
   ArrayRef<uint8_t> data() const override { return segment.Data.Content; }

diff  --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 889280a71c1ad..3b1dccbe46670 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -247,7 +247,7 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
     // files created before we introduced TLS relocations.
     // TODO(sbc): Remove this legacy behaviour one day.  This will break
     // backward compat with old object files built with `-fPIC`.
-    if (D->segment && D->segment->outputSeg->name == ".tdata")
+    if (D->segment && D->segment->outputSeg->isTLS())
       return D->getOutputSegmentOffset() + reloc.Addend;
 
     uint64_t value = D->getVA(reloc.Addend);

diff  --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h
index 30553b9883e22..c9d58cf231b80 100644
--- a/lld/wasm/OutputSegment.h
+++ b/lld/wasm/OutputSegment.h
@@ -32,6 +32,8 @@ class OutputSegment {
     size += inSeg->getSize();
   }
 
+  bool isTLS() const { return name == ".tdata"; }
+
   StringRef name;
   bool isBss = false;
   uint32_t index = 0;

diff  --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index 18eb522ebe0b7..f909c377b9a54 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -115,7 +115,7 @@ void scanRelocations(InputChunk *chunk) {
       break;
     case R_WASM_MEMORY_ADDR_TLS_SLEB:
       if (auto *D = dyn_cast<DefinedData>(sym)) {
-        if (D->segment->outputSeg->name != ".tdata") {
+        if (!D->segment->outputSeg->isTLS()) {
           error(toString(file) + ": relocation " +
                 relocTypeToString(reloc.Type) + " cannot be used against `" +
                 toString(*sym) +

diff  --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index 2bb89ae8ea5fe..66f276ba10fc7 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -207,13 +207,14 @@ bool Symbol::isExported() const {
   if (!isDefined() || isLocal())
     return false;
 
-  if (forceExport || config->exportAll)
+  if (config->exportAll || (config->exportDynamic && !isHidden()))
     return true;
 
-  if (config->exportDynamic && !isHidden())
-    return true;
+  return isExportedExplicit();
+}
 
-  return flags & WASM_SYMBOL_EXPORTED;
+bool Symbol::isExportedExplicit() const {
+  return forceExport || flags & WASM_SYMBOL_EXPORTED;
 }
 
 bool Symbol::isNoStrip() const {

diff  --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index e2a594ff0bef3..e6968d45261a5 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -110,6 +110,7 @@ class Symbol {
 
   WasmSymbolType getWasmType() const;
   bool isExported() const;
+  bool isExportedExplicit() const;
 
   // Indicates that the symbol is used in an __attribute__((used)) directive
   // or similar.

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index dbe947daf781c..7598d6f360d4a 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -270,7 +270,7 @@ void Writer::layoutMemory() {
     log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name,
                 memoryPtr, seg->size, seg->alignment));
 
-    if (!config->relocatable && seg->name == ".tdata") {
+    if (!config->relocatable && seg->isTLS()) {
       if (config->sharedMemory) {
         auto *tlsSize = cast<DefinedGlobal>(WasmSym::tlsSize);
         setGlobalPtr(tlsSize, seg->size);
@@ -631,6 +631,12 @@ void Writer::calculateExports() {
     } else if (auto *e = dyn_cast<DefinedEvent>(sym)) {
       export_ = {name, WASM_EXTERNAL_EVENT, e->getEventIndex()};
     } else if (auto *d = dyn_cast<DefinedData>(sym)) {
+      if (d->segment && d->segment->isTLS()) {
+        // We can't currenly export TLS data symbols.
+        if (sym->isExportedExplicit())
+          error("TLS symbols cannot yet be exported: `" + toString(*sym) + "`");
+        continue;
+      }
       out.globalSec->dataAddressGlobals.push_back(d);
       export_ = {name, WASM_EXTERNAL_GLOBAL, globalIndex++};
     } else {
@@ -900,7 +906,7 @@ void Writer::combineOutputSegments() {
   OutputSegment *combined = nullptr;
   std::vector<OutputSegment *> new_segments;
   for (OutputSegment *s : segments) {
-    if (s->name == ".tdata") {
+    if (s->isTLS()) {
       new_segments.push_back(s);
     } else {
       if (!combined) {
@@ -946,7 +952,7 @@ static void createFunction(DefinedFunction *func, StringRef bodyContent) {
 
 bool Writer::needsPassiveInitialization(const OutputSegment *segment) {
   return segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE &&
-         segment->name != ".tdata" && !segment->isBss;
+         !segment->isTLS() && !segment->isBss;
 }
 
 bool Writer::hasPassiveInitializedSegments() {


        


More information about the llvm-commits mailing list