[ELF][Layout] Provide a proper way to get the TLS segment size.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Tue, 5 Feb 2013 19:14:43 +0000 (19:14 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Tue, 5 Feb 2013 19:14:43 +0000 (19:14 +0000)
llvm-svn: 174427

lld/lib/ReaderWriter/ELF/DefaultLayout.h
lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp

index 1451996..0bfa51c 100644 (file)
@@ -247,6 +247,13 @@ public:
     return _relocationTable;
   }
 
+  uint64_t getTLSSize() const {
+    for (const auto &phdr : *_programHeader)
+      if (phdr->p_type == llvm::ELF::PT_TLS)
+        return phdr->p_memsz;
+    return 0;
+  }
+
 private:
   SectionMapT _sectionMap;
   MergedSectionMapT _mergedSectionMap;
@@ -316,6 +323,10 @@ StringRef DefaultLayout<ELFT>::getSectionName(
     return ".text";
   if (name.startswith(".rodata"))
     return ".rodata";
+  if (name.startswith(".tdata"))
+    return ".tdata";
+  if (name.startswith(".tbss"))
+    return ".tbss";
   return name;
 }
 
index ec7ba4c..db0fc94 100644 (file)
@@ -78,19 +78,8 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
   case R_X86_64_TPOFF64:
   case R_X86_64_DTPOFF32:
   case R_X86_64_TPOFF32: {
-    // Get the start and end of the TLS segment.
-    if (_tlsSize == 0) {
-      auto tdata = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
-          .findOutputSection(".tdata");
-      auto tbss = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
-          .findOutputSection(".tbss");
-      // HACK: The tdata and tbss sections end up together to from the TLS
-      // segment. This should actually use the TLS program header entry.
-      if (tdata)
-        _tlsSize = tdata->memSize();
-      if (tbss)
-        _tlsSize += tbss->memSize();
-    }
+    _tlsSize = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
+        .getTLSSize();
     if (ref.kind() == R_X86_64_TPOFF32 || ref.kind() == R_X86_64_DTPOFF32) {
       int32_t result = (int32_t)(targetVAddress - _tlsSize);
       *reinterpret_cast<llvm::support::little32_t *>(location) = result;