[lld] cb03ac0 - [ELF] Move Symbol::needsTlsLd to config->needsTlsLd

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 7 10:26:21 PST 2022


Author: Fangrui Song
Date: 2022-02-07T10:26:16-08:00
New Revision: cb03ac0b5d6f5c46d453762b2f6e234c24eabe1e

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

LOG: [ELF] Move Symbol::needsTlsLd to config->needsTlsLd

to decrease sizeof(SymbolUnion) from 72 to 64 on ELF64 platforms.

Use a dummy `Undefined` to prevent null pointer dereference (though unused)
`*rel.sym` in InputSectionBase::relocateAlloc.

The relocation order may shuffle a bit, but otherwise there is no behavior
difference.

Added: 
    

Modified: 
    lld/ELF/Config.h
    lld/ELF/Relocations.cpp
    lld/ELF/Symbols.h
    lld/test/ELF/i386-tls-dynamic.s
    lld/test/ELF/ppc64-tls-missing-gdld.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 72b7be8165e05..6d5c4cb592878 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -312,6 +312,9 @@ struct Configuration {
   // if that's true.)
   bool isMips64EL;
 
+  // True if we need to reserve two .got entries for local-dynamic TLS model.
+  bool needsTlsLd = false;
+
   // True if we need to set the DF_STATIC_TLS flag to an output file, which
   // works as a hint to the dynamic loader that the shared object contains code
   // compiled with the initial-exec TLS model.

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 58a61b4154dc4..f2b312c7729c3 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1238,7 +1238,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
     }
     if (expr == R_TLSLD_HINT)
       return 1;
-    sym.needsTlsLd = true;
+    config->needsTlsLd = true;
     c.relocations.push_back({expr, type, offset, addend, &sym});
     return 1;
   }
@@ -1681,15 +1681,6 @@ void elf::postScanRelocations() {
       mainPart->relaDyn->addSymbolReloc(target->tlsGotRel, *in.got,
                                         sym.getGotOffset(), sym);
     }
-
-    if (sym.needsTlsLd && in.got->addTlsIndex()) {
-      if (isLocalInExecutable)
-        in.got->relocations.push_back(
-            {R_ADDEND, target->symbolicRel, in.got->getTlsIndexOff(), 1, &sym});
-      else
-        mainPart->relaDyn->addReloc({target->tlsModuleIndexRel, in.got.get(),
-                                     in.got->getTlsIndexOff()});
-    }
     if (sym.needsGotDtprel) {
       in.got->addEntry(sym);
       in.got->relocations.push_back(
@@ -1700,6 +1691,16 @@ void elf::postScanRelocations() {
       addTpOffsetGotEntry(sym);
   };
 
+  if (config->needsTlsLd && in.got->addTlsIndex()) {
+    static Undefined dummy(nullptr, "", STB_LOCAL, 0, 0);
+    if (config->shared)
+      mainPart->relaDyn->addReloc(
+          {target->tlsModuleIndexRel, in.got.get(), in.got->getTlsIndexOff()});
+    else
+      in.got->relocations.push_back(
+          {R_ADDEND, target->symbolicRel, in.got->getTlsIndexOff(), 1, &dummy});
+  }
+
   assert(symAux.empty());
   for (Symbol *sym : symtab->symbols())
     fn(*sym);

diff  --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index b682601667990..271b0fadae23c 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -247,8 +247,8 @@ class Symbol {
         isInIplt(false), gotInIgot(false), folded(false),
         needsTocRestore(false), scriptDefined(false), needsCopy(false),
         needsGot(false), needsPlt(false), needsTlsDesc(false),
-        needsTlsGd(false), needsTlsGdToIe(false), needsTlsLd(false),
-        needsGotDtprel(false), needsTlsIe(false), hasDirectReloc(false) {}
+        needsTlsGd(false), needsTlsGdToIe(false), needsGotDtprel(false),
+        needsTlsIe(false), hasDirectReloc(false) {}
 
 public:
   // True if this symbol is in the Iplt sub-section of the Plt and the Igot
@@ -283,7 +283,6 @@ class Symbol {
   uint8_t needsTlsDesc : 1;
   uint8_t needsTlsGd : 1;
   uint8_t needsTlsGdToIe : 1;
-  uint8_t needsTlsLd : 1;
   uint8_t needsGotDtprel : 1;
   uint8_t needsTlsIe : 1;
   uint8_t hasDirectReloc : 1;
@@ -301,7 +300,7 @@ class Symbol {
 
   bool needsDynReloc() const {
     return needsCopy || needsGot || needsPlt || needsTlsDesc || needsTlsGd ||
-           needsTlsGdToIe || needsTlsLd || needsGotDtprel || needsTlsIe;
+           needsTlsGdToIe || needsGotDtprel || needsTlsIe;
   }
   void allocateAux() {
     assert(auxIdx == uint32_t(-1));
@@ -513,9 +512,9 @@ union SymbolUnion {
 };
 
 // It is important to keep the size of SymbolUnion small for performance and
-// memory usage reasons. 72 bytes is a soft limit based on the size of Defined
+// memory usage reasons. 64 bytes is a soft limit based on the size of Defined
 // on a 64-bit system.
-static_assert(sizeof(SymbolUnion) <= 72, "SymbolUnion too large");
+static_assert(sizeof(SymbolUnion) <= 64, "SymbolUnion too large");
 
 template <typename T> struct AssertSymbol {
   static_assert(std::is_trivially_destructible<T>(),

diff  --git a/lld/test/ELF/i386-tls-dynamic.s b/lld/test/ELF/i386-tls-dynamic.s
index d61ee5526bb11..cff442e8ead39 100644
--- a/lld/test/ELF/i386-tls-dynamic.s
+++ b/lld/test/ELF/i386-tls-dynamic.s
@@ -66,13 +66,13 @@ addl tls1 at gotntpoff(%ebx),%eax
 
 # CHECK: Relocations [
 # CHECK:      Section ({{.+}}) .rel.dyn {
-# CHECK-NEXT: 0x2370 R_386_TLS_DTPMOD32 -
-# CHECK-NEXT: 0x2358 R_386_TLS_DTPMOD32 tls0
-# CHECK-NEXT: 0x235C R_386_TLS_DTPOFF32 tls0
-# CHECK-NEXT: 0x2360 R_386_TLS_TPOFF tls0
-# CHECK-NEXT: 0x2364 R_386_TLS_DTPMOD32 tls1
-# CHECK-NEXT: 0x2368 R_386_TLS_DTPOFF32 tls1
-# CHECK-NEXT: 0x236C R_386_TLS_TPOFF tls1
+# CHECK-NEXT: 0x2358 R_386_TLS_DTPMOD32 -
+# CHECK-NEXT: 0x2360 R_386_TLS_DTPMOD32 tls0
+# CHECK-NEXT: 0x2364 R_386_TLS_DTPOFF32 tls0
+# CHECK-NEXT: 0x2368 R_386_TLS_TPOFF tls0
+# CHECK-NEXT: 0x236C R_386_TLS_DTPMOD32 tls1
+# CHECK-NEXT: 0x2370 R_386_TLS_DTPOFF32 tls1
+# CHECK-NEXT: 0x2374 R_386_TLS_TPOFF tls1
 # CHECK-NEXT: }
 
 # DIS:      Disassembly of section .text:
@@ -81,20 +81,20 @@ addl tls1 at gotntpoff(%ebx),%eax
 ## General dynamic model:
 ## -4128 and -4116 are first and second GOT entries offsets.
 ## Each one is a pair of records.
-# DIS-NEXT: 1260:       leal -4128(,%ebx), %eax
+# DIS-NEXT: 1260:       leal -4120(,%ebx), %eax
 # DIS-NEXT: 1267:       calll 0x12d0
-# DIS-NEXT: 126c:       leal -4116(,%ebx), %eax
+# DIS-NEXT: 126c:       leal -4108(,%ebx), %eax
 # DIS-NEXT: 1273:       calll 0x12d0
 ## Local dynamic model:
 ## -16 is a local module tls index offset.
-# DIS-NEXT: 1278:       leal -4104(%ebx), %eax
+# DIS-NEXT: 1278:       leal -4128(%ebx), %eax
 # DIS-NEXT: 127e:       calll 0x12d0
 # DIS-NEXT: 1283:       leal 8(%eax), %edx
-# DIS-NEXT: 1289:       leal -4104(%ebx), %eax
+# DIS-NEXT: 1289:       leal -4128(%ebx), %eax
 # DIS-NEXT: 128f:       calll 0x12d0
 # DIS-NEXT: 1294:       leal 12(%eax), %edx
 ## Initial exec model:
 # DIS-NEXT: 129a:       movl %gs:0, %eax
-# DIS-NEXT: 12a0:       addl -4120(%ebx), %eax
+# DIS-NEXT: 12a0:       addl -4112(%ebx), %eax
 # DIS-NEXT: 12a6:       movl %gs:0, %eax
-# DIS-NEXT: 12ac:       addl -4108(%ebx), %eax
+# DIS-NEXT: 12ac:       addl -4100(%ebx), %eax

diff  --git a/lld/test/ELF/ppc64-tls-missing-gdld.s b/lld/test/ELF/ppc64-tls-missing-gdld.s
index 2d1954e95b191..16a3085872c07 100644
--- a/lld/test/ELF/ppc64-tls-missing-gdld.s
+++ b/lld/test/ELF/ppc64-tls-missing-gdld.s
@@ -25,28 +25,28 @@
 ## .got+32: TPOFFSET for x = st_value-0x7000
 # HEX:      section '.got':
 # HEX-NEXT: [[#%x,IGNORE:]] 50820210 00000000 01000000 00000000
-# HEX-NEXT: [[#%x,IGNORE:]] 0080ffff ffffffff 01000000 00000000
-# HEX-NEXT: [[#%x,IGNORE:]] 00000000 00000000 0090ffff ffffffff
+# HEX-NEXT: [[#%x,IGNORE:]] 00000000 00000000 01000000 00000000
+# HEX-NEXT: [[#%x,IGNORE:]] 0080ffff ffffffff 0090ffff ffffffff
 
 ## .TOC.-32768 = (.got+0x8000)-32768 = .got
 # DIS-LABEL: <GeneralDynamic>:
 # DIS-NEXT:    addis 3, 2, 0
-# DIS-NEXT:    addi 3, 3, -32760
+# DIS-NEXT:    addi 3, 3, -32744
 # DIS-NEXT:    bl [[#%x,TGA:]]
 # DIS-LABEL: <GeneralDynamic_NOTOC>:
 # DIS-NEXT:    addis 3, 2, 0
-# DIS-NEXT:    addi 3, 3, -32760
+# DIS-NEXT:    addi 3, 3, -32744
 # DIS-NEXT:    bl [[#TGA]]
 
 ## LocalDynamic references _TLS_MODULE_BASE_.
 ## .TOC.-32752 = (.got+0x8000)-32752 = .got+16
 # DIS-LABEL: <LocalDynamic>:
 # DIS-NEXT:    addis 3, 2, 0
-# DIS-NEXT:    addi 3, 3, -32744
+# DIS-NEXT:    addi 3, 3, -32760
 # DIS-NEXT:    bl [[#TGA]]
 # DIS-LABEL: <LocalDynamic_NOTOC>:
 # DIS-NEXT:    addis 3, 2, 0
-# DIS-NEXT:    addi 3, 3, -32744
+# DIS-NEXT:    addi 3, 3, -32760
 # DIS-NEXT:    bl [[#TGA]]
 
 ## Technically we don't have to disable IE to LE relaxation,


        


More information about the llvm-commits mailing list