[lld] 3041b16 - [WebAssembly] Add TLS data segment flag: WASM_SEG_FLAG_TLS

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed May 12 13:31:11 PDT 2021


Author: Sam Clegg
Date: 2021-05-12T13:31:02-07:00
New Revision: 3041b16f7322a0392810e4a14b13cacac1929ad8

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

LOG: [WebAssembly] Add TLS data segment flag: WASM_SEG_FLAG_TLS

Previously the linker was relying solely on the name of the segment
to imply TLS.

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

Added: 
    

Modified: 
    lld/test/wasm/tls.s
    lld/wasm/InputChunks.h
    lld/wasm/Writer.cpp
    llvm/include/llvm/BinaryFormat/Wasm.h
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/MC/MCParser/WasmAsmParser.cpp
    llvm/lib/MC/MCSectionWasm.cpp
    llvm/lib/ObjectYAML/WasmYAML.cpp
    llvm/test/CodeGen/WebAssembly/target-features-tls.ll
    llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
    llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
    llvm/test/MC/WebAssembly/tls.s

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/tls.s b/lld/test/wasm/tls.s
index 878498bc2e483..9675b7839aa9b 100644
--- a/lld/test/wasm/tls.s
+++ b/lld/test/wasm/tls.s
@@ -40,6 +40,8 @@ no_tls:
   .int32  0
   .size no_tls, 4
 
+// Older versions of LLVM did not use the "T" flag so we need to support
+// infering TLS from the name alone.
 .section  .tdata.tls1,"",@
 .globl  tls1
 .p2align  2
@@ -47,14 +49,14 @@ tls1:
   .int32  1
   .size tls1, 4
 
-.section  .tdata.tls2,"",@
+.section  sec_tls2,"T",@
 .globl  tls2
 .p2align  2
 tls2:
   .int32  1
   .size tls2, 4
 
-.section  .tbss.tls3,"",@
+.section  sec_tls3,"T",@
 .globl  tls3
 .p2align  2
 tls3:

diff  --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index 161e7435090b7..d0195b5f8ceeb 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -137,8 +137,11 @@ class InputSegment : public InputChunk {
 
   uint64_t getVA(uint64_t offset = 0) const;
 
-  bool isTLS() {
-    return getName().startswith(".tdata") || getName().startswith(".tbss");
+  bool isTLS() const {
+    // Older object files don't include WASM_SEG_FLAG_TLS and instead
+    // relied on the naming convention.
+    return flags & llvm::wasm::WASM_SEG_FLAG_TLS ||
+           getName().startswith(".tdata") || getName().startswith(".tbss");
   }
 
   const OutputSegment *outputSeg = nullptr;

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 14a68ebdf907f..08149bc605a24 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -461,9 +461,7 @@ void Writer::populateTargetFeatures() {
 
     // Find TLS data segments
     auto isTLS = [](InputSegment *segment) {
-      StringRef name = segment->getName();
-      return segment->live &&
-             (name.startswith(".tdata") || name.startswith(".tbss"));
+      return segment->live && segment->isTLS();
     };
     tlsUsed = tlsUsed ||
               std::any_of(file->segments.begin(), file->segments.end(), isTLS);
@@ -818,12 +816,12 @@ void Writer::assignIndexes() {
   out.tableSec->assignIndexes();
 }
 
-static StringRef getOutputDataSegmentName(StringRef name) {
-  // We only support one thread-local segment, so we must merge the segments
-  // despite --no-merge-data-segments.
-  // We also need to merge .tbss into .tdata so they share the same offsets.
-  if (name.startswith(".tdata") || name.startswith(".tbss"))
+static StringRef getOutputDataSegmentName(const InputSegment &seg) {
+  // We always merge .tbss and .tdata into a single TLS segment so all TLS
+  // symbols are be relative to single __tls_base.
+  if (seg.isTLS())
     return ".tdata";
+  StringRef name = seg.getName();
   if (!config->mergeDataSegments)
     return name;
   if (name.startswith(".text."))
@@ -857,7 +855,7 @@ void Writer::createOutputSegments() {
     for (InputSegment *segment : file->segments) {
       if (!segment->live)
         continue;
-      StringRef name = getOutputDataSegmentName(segment->getName());
+      StringRef name = getOutputDataSegmentName(*segment);
       OutputSegment *s = nullptr;
       // When running in relocatable mode we can't merge segments that are part
       // of comdat groups since the ultimate linker needs to be able exclude or

diff  --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index 077913d7fa59d..999f4a2578130 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -359,6 +359,7 @@ enum WasmSymbolType : unsigned {
 
 enum WasmSegmentFlag : unsigned {
   WASM_SEG_FLAG_STRINGS = 0x1,
+  WASM_SEG_FLAG_TLS = 0x2,
 };
 
 // Kinds of event attributes.

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 54d65ccac50d9..31122295fa37c 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2009,11 +2009,14 @@ static const Comdat *getWasmComdat(const GlobalValue *GV) {
 static unsigned getWasmSectionFlags(SectionKind K) {
   unsigned Flags = 0;
 
-  // TODO(sbc): Add suport for K.isMergeableConst()
+  if (K.isThreadLocal())
+    Flags |= wasm::WASM_SEG_FLAG_TLS;
 
   if (K.isMergeableCString())
     Flags |= wasm::WASM_SEG_FLAG_STRINGS;
 
+  // TODO(sbc): Add suport for K.isMergeableConst()
+
   return Flags;
 }
 

diff  --git a/llvm/lib/MC/MCParser/WasmAsmParser.cpp b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
index fdf8c45ba5c6a..833530bef3bf3 100644
--- a/llvm/lib/MC/MCParser/WasmAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
@@ -100,6 +100,9 @@ class WasmAsmParser : public MCAsmParserExtension {
       case 'G':
         Group = true;
         break;
+      case 'T':
+        flags |= wasm::WASM_SEG_FLAG_TLS;
+        break;
       case 'S':
         flags |= wasm::WASM_SEG_FLAG_STRINGS;
         break;

diff  --git a/llvm/lib/MC/MCSectionWasm.cpp b/llvm/lib/MC/MCSectionWasm.cpp
index 9faa4caad64f9..459913263268b 100644
--- a/llvm/lib/MC/MCSectionWasm.cpp
+++ b/llvm/lib/MC/MCSectionWasm.cpp
@@ -69,6 +69,8 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     OS << 'G';
   if (SegmentFlags & wasm::WASM_SEG_FLAG_STRINGS)
     OS << 'S';
+  if (SegmentFlags & wasm::WASM_SEG_FLAG_TLS)
+    OS << 'T';
 
   OS << '"';
 

diff  --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index 0017e7e609a9d..6b7357c4d1d8e 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -544,6 +544,7 @@ void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset(
     IO &IO, WasmYAML::SegmentFlags &Value) {
 #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_SEG_FLAG_##X)
   BCase(STRINGS);
+  BCase(TLS);
 #undef BCase
 }
 

diff  --git a/llvm/test/CodeGen/WebAssembly/target-features-tls.ll b/llvm/test/CodeGen/WebAssembly/target-features-tls.ll
index e146bdae5f54e..f5ec6842de71f 100644
--- a/llvm/test/CodeGen/WebAssembly/target-features-tls.ll
+++ b/llvm/test/CodeGen/WebAssembly/target-features-tls.ll
@@ -23,4 +23,4 @@ target triple = "wasm32-unknown-unknown"
 ; BULK-MEM-NEXT: .int8 43
 ; BULK-MEM-NEXT: .int8 11
 ; BULK-MEM-NEXT: .ascii "bulk-memory"
-; BULK-MEM-NEXT: .tbss.foo,"",@
+; BULK-MEM-NEXT: .tbss.foo,"T",@

diff  --git a/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll b/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
index 16a312bd6bada..cb20066e14c57 100644
--- a/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
+++ b/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
@@ -105,7 +105,7 @@ define void @tls_base_write(i8** %output) {
 }
 
 ; CHECK: .type tls, at object
-; TLS-NEXT: .section .tbss.tls,"",@
+; TLS-NEXT: .section .tbss.tls,"T",@
 ; NO-TLS-NEXT: .section .bss.tls,"",@
 ; CHECK-NEXT: .p2align 2
 ; CHECK-NEXT: tls:

diff  --git a/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll b/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
index 7cc043a13ac0d..c6ae34b7fc81b 100644
--- a/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
+++ b/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
@@ -72,7 +72,7 @@ define i32 @tls_size() {
 }
 
 ; CHECK: .type tls, at object
-; TLS-NEXT: .section .tbss.tls,"",@
+; TLS-NEXT: .section .tbss.tls,"T",@
 ; NO-TLS-NEXT: .section .bss.tls,"",@
 ; CHECK-NEXT: .p2align 2
 ; CHECK-NEXT: tls:

diff  --git a/llvm/test/MC/WebAssembly/tls.s b/llvm/test/MC/WebAssembly/tls.s
index f1dba82994460..2df245ff9385a 100644
--- a/llvm/test/MC/WebAssembly/tls.s
+++ b/llvm/test/MC/WebAssembly/tls.s
@@ -5,15 +5,26 @@
 tls_store:
   .functype tls_store (i32) -> ()
   # CHECK: global.get __tls_base
-  # CHECK-NEXT: i32.const tls at TLSREL
+  # CHECK-NEXT: i32.const tls1 at TLSREL
   # CHECK-NEXT: i32.add
   # CHECK-NEXT: i32.store 0
   global.get __tls_base
-  i32.const tls at TLSREL
+  i32.const tls1 at TLSREL
   i32.add
   i32.store 0
   end_function
 
+.section .tls.foo,"T",@
+# CHECK: .tls.foo,"T",@
+tls1:
+  .int32 42
+  .size tls1, 4
+
+.section custom_tls,"T",@
+# CHECK: custom_tls,"T",@
+tls2:
+  .int32 43
+  .size tls2, 4
 
 #      CHECK-OBJ:  - Type:            CODE
 # CHECK-OBJ-NEXT:    Relocations:
@@ -39,5 +50,22 @@ tls_store:
 # CHECK-OBJ-NEXT:        Flags:           [ UNDEFINED ]
 # CHECK-OBJ-NEXT:      - Index:           2
 # CHECK-OBJ-NEXT:        Kind:            DATA
-# CHECK-OBJ-NEXT:        Name:            tls
-# CHECK-OBJ-NEXT:        Flags:           [ UNDEFINED ]
+# CHECK-OBJ-NEXT:        Name:            tls1
+# CHECK-OBJ-NEXT:        Flags:           [ BINDING_LOCAL ]
+# CHECK-OBJ-NEXT:        Segment:         0
+# CHECK-OBJ-NEXT:        Size:            4
+# CHECK-OBJ-NEXT:      - Index:           3
+# CHECK-OBJ-NEXT:        Kind:            DATA
+# CHECK-OBJ-NEXT:        Name:            tls2
+# CHECK-OBJ-NEXT:        Flags:           [ BINDING_LOCAL ]
+# CHECK-OBJ-NEXT:        Segment:         1
+# CHECK-OBJ-NEXT:        Size:            4
+# CHECK-OBJ-NEXT:    SegmentInfo:
+# CHECK-OBJ-NEXT:      - Index:           0
+# CHECK-OBJ-NEXT:        Name:            .tls.foo
+# CHECK-OBJ-NEXT:        Alignment:       0
+# CHECK-OBJ-NEXT:        Flags:           [ TLS ]
+# CHECK-OBJ-NEXT:      - Index:           1
+# CHECK-OBJ-NEXT:        Name:            custom_tls
+# CHECK-OBJ-NEXT:        Alignment:       0
+# CHECK-OBJ-NEXT:        Flags:           [ TLS ]


        


More information about the llvm-commits mailing list