diff options
-rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultLayout.h | 5 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SegmentChunks.h | 12 | ||||
-rw-r--r-- | lld/test/elf/Inputs/tlsAddr.x86-64 | bin | 0 -> 1752 bytes | |||
-rw-r--r-- | lld/test/elf/Inputs/tlsaddr.c | 8 | ||||
-rw-r--r-- | lld/test/elf/dynamic-segorder.test | 2 | ||||
-rw-r--r-- | lld/test/elf/tlsAddr.test | 7 |
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 Binary files differnew file mode 100644 index 00000000000..16cc9ab25ab --- /dev/null +++ b/lld/test/elf/Inputs/tlsAddr.x86-64 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 |