summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/HeaderChunks.h
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2013-02-01 07:13:49 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2013-02-01 07:13:49 +0000
commitb0ed8e80d82f40f7b35e50d551952e045660742f (patch)
treeb5c6ccfa41014e86bbdb0517546a2f14bca5a7bf /lld/lib/ReaderWriter/ELF/HeaderChunks.h
parentfa4fab77d40c49747372c9d4c397f71e370c431e (diff)
downloadbcm5719-llvm-b0ed8e80d82f40f7b35e50d551952e045660742f.tar.gz
bcm5719-llvm-b0ed8e80d82f40f7b35e50d551952e045660742f.zip
[ELF][x86-84] Add static TLS support.
llvm-svn: 174154
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/HeaderChunks.h')
-rw-r--r--lld/lib/ReaderWriter/ELF/HeaderChunks.h67
1 files changed, 44 insertions, 23 deletions
diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
index e2512b55e74..f3660e8b03f 100644
--- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h
+++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
@@ -156,20 +156,11 @@ public:
}
private:
- std::vector<Elf_Phdr *> _ph;
- PhIterT _phi;
- llvm::BumpPtrAllocator _allocator;
-};
-
-template<class ELFT>
-bool
-ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) {
- Elf_Phdr *phdr = nullptr;
- bool ret = false;
-
- for (auto slice : segment->slices()) {
+ std::pair<Elf_Phdr *, bool> allocateProgramHeader() {
+ Elf_Phdr *phdr;
+ bool ret = false;
if (_phi == _ph.end()) {
- phdr = new(_allocator.Allocate<Elf_Phdr>()) Elf_Phdr;
+ phdr = new (_allocator) Elf_Phdr;
_ph.push_back(phdr);
_phi = _ph.end();
ret = true;
@@ -177,20 +168,50 @@ ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) {
phdr = (*_phi);
++_phi;
}
- phdr->p_type = segment->segmentType();
- phdr->p_offset = slice->fileOffset();
- phdr->p_vaddr = slice->virtualAddr();
- phdr->p_paddr = slice->virtualAddr();
- phdr->p_filesz = slice->fileSize();
- phdr->p_memsz = slice->memSize();
- phdr->p_flags = segment->flags();
- phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ?
- segment->pageSize() : slice->align2();
+
+ return std::make_pair(phdr, ret);
+ }
+
+ std::vector<Elf_Phdr *> _ph;
+ PhIterT _phi;
+ llvm::BumpPtrAllocator _allocator;
+};
+
+template <class ELFT>
+bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) {
+ bool allocatedNew = false;
+ for (auto slice : segment->slices()) {
+ // If we have a TLS segment, emit a LOAD first.
+ if (segment->segmentType() == llvm::ELF::PT_TLS) {
+ auto phdr = allocateProgramHeader();
+ if (phdr.second)
+ allocatedNew = true;
+ phdr.first->p_type = llvm::ELF::PT_LOAD;
+ phdr.first->p_offset = slice->fileOffset();
+ phdr.first->p_vaddr = slice->virtualAddr();
+ phdr.first->p_paddr = slice->virtualAddr();
+ phdr.first->p_filesz = slice->fileSize();
+ phdr.first->p_memsz = slice->memSize();
+ phdr.first->p_flags = segment->flags();
+ phdr.first->p_align = slice->align2();
+ }
+ auto phdr = allocateProgramHeader();
+ if (phdr.second)
+ allocatedNew = true;
+ phdr.first->p_type = segment->segmentType();
+ phdr.first->p_offset = slice->fileOffset();
+ phdr.first->p_vaddr = slice->virtualAddr();
+ phdr.first->p_paddr = slice->virtualAddr();
+ phdr.first->p_filesz = slice->fileSize();
+ phdr.first->p_memsz = slice->memSize();
+ phdr.first->p_flags = segment->flags();
+ phdr.first->p_align = (phdr.first->p_type == llvm::ELF::PT_LOAD) ?
+ segment->pageSize() : slice->align2();
}
this->_fsize = fileSize();
this->_msize = this->_fsize;
- return ret;
+ return allocatedNew;
}
template <class ELFT>
OpenPOWER on IntegriCloud