diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index 8b87a66fbe2a..326019f9a31c 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -63,6 +63,8 @@ public: ORDER_RODATA = 100, ORDER_EH_FRAME = 110, ORDER_EH_FRAMEHDR = 120, + ORDER_TDATA = 124, + ORDER_TBSS = 128, ORDER_CTORS = 130, ORDER_DTORS = 140, ORDER_INIT_ARRAY = 150, @@ -353,6 +355,10 @@ Layout::SegmentType DefaultLayout::getSegmentType( case ORDER_FINI_ARRAY: return llvm::ELF::PT_LOAD; + case ORDER_TDATA: + case ORDER_TBSS: + return llvm::ELF::PT_TLS; + default: return llvm::ELF::PT_NULL; } @@ -376,6 +382,8 @@ bool DefaultLayout::hasOutputSegment(Section *section) { case ORDER_RODATA: case ORDER_EH_FRAME: case ORDER_EH_FRAMEHDR: + case ORDER_TDATA: + case ORDER_TBSS: case ORDER_NOTE: case ORDER_DYNAMIC: case ORDER_CTORS: diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index bb53ad7c5241..101089dec222 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -81,7 +81,6 @@ public: for (auto &ai : _atoms) { ai->_virtualAddr = addr + ai->_fileOffset; } - addr += this->memSize(); } /// \brief Set the file offset of each Atom in the section. This routine diff --git a/lld/lib/ReaderWriter/ELF/SegmentChunks.h b/lld/lib/ReaderWriter/ELF/SegmentChunks.h index 12ced7036acc..efdfc655fd99 100644 --- a/lld/lib/ReaderWriter/ELF/SegmentChunks.h +++ b/lld/lib/ReaderWriter/ELF/SegmentChunks.h @@ -318,9 +318,13 @@ Segment::assignOffsets(uint64_t startOffset) { } /// \brief Assign virtual addresses to the slices -template -void -Segment::assignVirtualAddress(uint64_t &addr) { +template void Segment::assignVirtualAddress(uint64_t &addr) { + // Check if the segment is of type TLS + // The sections that belong to the TLS segment have their + // virtual addresses that are relative To TP + bool isTLSSegment = (segmentType() == llvm::ELF::PT_TLS); + uint64_t tlsStartAddr = 0; + for (auto slice : slices()) { // Align to a page addr = llvm::RoundUpToAlignment(addr, this->_targetInfo.getPageSize()); @@ -331,15 +335,20 @@ Segment::assignVirtualAddress(uint64_t &addr) { for (auto section : slice->sections()) { // Align the section address addr = llvm::RoundUpToAlignment(addr, section->align2()); + tlsStartAddr = (isTLSSegment) ? + llvm::RoundUpToAlignment(tlsStartAddr, section->align2()):0; if (!virtualAddressSet) { slice->setVAddr(addr); virtualAddressSet = true; } section->setVAddr(addr); - if (auto s = dyn_cast>(section)) - s->assignVirtualAddress(addr); - else - addr += section->memSize(); + if (auto s = dyn_cast >(section)) { + if (isTLSSegment) + s->assignVirtualAddress(tlsStartAddr); + else + s->assignVirtualAddress(addr); + } + addr += section->memSize(); section->setMemSize(addr - section->virtualAddr()); } slice->setMemSize(addr - slice->virtualAddr());