summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/ELF/DefaultLayout.h5
-rw-r--r--lld/lib/ReaderWriter/ELF/SegmentChunks.h12
-rw-r--r--lld/test/elf/Inputs/tlsAddr.x86-64bin0 -> 1752 bytes
-rw-r--r--lld/test/elf/Inputs/tlsaddr.c8
-rw-r--r--lld/test/elf/dynamic-segorder.test2
-rw-r--r--lld/test/elf/tlsAddr.test7
6 files changed, 30 insertions, 4 deletions
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
index f0bafc15ed6..96479a581d1 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
@@ -581,8 +581,13 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
int64_t lookupSectionFlag = msi->flags();
if (!(lookupSectionFlag & llvm::ELF::SHF_WRITE))
lookupSectionFlag &= ~llvm::ELF::SHF_EXECINSTR;
+
+ // Merge string sections into Data segment itself
lookupSectionFlag &= ~(llvm::ELF::SHF_STRINGS | llvm::ELF::SHF_MERGE);
+ // Merge the TLS section into the DATA segment itself
+ lookupSectionFlag &= ~(llvm::ELF::SHF_TLS);
+
Segment<ELFT> *segment;
// We need a seperate segment for sections that dont have
// the segment type to be PT_LOAD
diff --git a/lld/lib/ReaderWriter/ELF/SegmentChunks.h b/lld/lib/ReaderWriter/ELF/SegmentChunks.h
index 5660a6a7733..453f905242a 100644
--- a/lld/lib/ReaderWriter/ELF/SegmentChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SegmentChunks.h
@@ -30,6 +30,9 @@
namespace lld {
namespace elf {
+
+template <typename ELFT> class DefaultLayout;
+
/// \brief A segment can be divided into segment slices
/// depending on how the segments can be split
template<class ELFT>
@@ -496,8 +499,13 @@ template <class ELFT> void Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
}
if (isTLSSegment)
tlsStartAddr += section->memSize();
- addr += section->memSize();
- section->setMemSize(addr - section->virtualAddr());
+ section->setMemSize(addr + section->memSize() - section->virtualAddr());
+ // TBSS section is special that it doesnot contribute to memory of any
+ // segment, If we see a tbss section, dont add memory size to addr
+ // The fileOffset is automatically taken care of since TBSS section does
+ // not endup using file size
+ if (section->order() != DefaultLayout<ELFT>::ORDER_TBSS)
+ addr += section->memSize();
}
slice->setMemSize(addr - slice->virtualAddr());
}
diff --git a/lld/test/elf/Inputs/tlsAddr.x86-64 b/lld/test/elf/Inputs/tlsAddr.x86-64
new file mode 100644
index 00000000000..16cc9ab25ab
--- /dev/null
+++ b/lld/test/elf/Inputs/tlsAddr.x86-64
Binary files differ
diff --git a/lld/test/elf/Inputs/tlsaddr.c b/lld/test/elf/Inputs/tlsaddr.c
new file mode 100644
index 00000000000..f62d57b3bfb
--- /dev/null
+++ b/lld/test/elf/Inputs/tlsaddr.c
@@ -0,0 +1,8 @@
+__thread int tls0 = 0;
+__thread int tls1 = 0;
+__thread int tls2 = 1;
+__thread int tls3 = 2;
+
+int main() {
+ return tls0 + tls1 + tls2;
+}
diff --git a/lld/test/elf/dynamic-segorder.test b/lld/test/elf/dynamic-segorder.test
index 83a93ab93b7..6148cf391f9 100644
--- a/lld/test/elf/dynamic-segorder.test
+++ b/lld/test/elf/dynamic-segorder.test
@@ -10,8 +10,6 @@ CHECK: LOAD
CHECK: flags r-x
CHECK: LOAD
CHECK: flags rw-
-CHECK: LOAD
-CHECK: flags rw-
CHECK: DYNAMIC
CHECK: flags r--
CHECK: TLS
diff --git a/lld/test/elf/tlsAddr.test b/lld/test/elf/tlsAddr.test
new file mode 100644
index 00000000000..4d1a33bcd45
--- /dev/null
+++ b/lld/test/elf/tlsAddr.test
@@ -0,0 +1,7 @@
+# This tests verifies that TLS variables have correct offsets
+# and that TBSS doesnot occupy memory
+RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/tlsAddr.x86-64 -static \
+RUN: -o %t --noinhibit-exec
+RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=CHECKADDR %s
+
+CHECKADDR: 8 .data 00000000 0000000000401008 DATA
OpenPOWER on IntegriCloud