summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2013-02-23 03:58:06 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2013-02-23 03:58:06 +0000
commit13db19d64e2013b90cd78006aa533008a857d8d3 (patch)
treea65be7f94c1d49ae14d896c6d9080cb841e4ebb1
parentdacee2bb448da9fb9c984e9802573a8cada3c052 (diff)
downloadbcm5719-llvm-13db19d64e2013b90cd78006aa533008a857d8d3.tar.gz
bcm5719-llvm-13db19d64e2013b90cd78006aa533008a857d8d3.zip
[ELF][Writer] Add a PHDR program table entry for dynamic files.
llvm-svn: 175951
-rw-r--r--lld/lib/ReaderWriter/ELF/DefaultLayout.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/HeaderChunks.h21
-rw-r--r--lld/test/elf/dynamic-phdr.test7
3 files changed, 30 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
index a3dad87e2b5..95cd8cf8cc9 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
@@ -593,6 +593,8 @@ DefaultLayout<ELFT>::assignVirtualAddress() {
for (auto si : _segments) {
newSegmentHeaderAdded = _programHeader->addSegment(si);
}
+ if (_targetInfo.isDynamic() && _programHeader->addPHDR())
+ newSegmentHeaderAdded = true;
if (!newSegmentHeaderAdded)
break;
uint64_t fileoffset = 0;
diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
index 6282ee916ce..3682b23b754 100644
--- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h
+++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
@@ -119,6 +119,27 @@ public:
bool addSegment(Segment<ELFT> *segment);
+ bool addPHDR() {
+ bool allocatedNew = false;
+ auto phdr = allocateProgramHeader();
+ if (phdr.second)
+ allocatedNew = true;
+
+ this->_fsize = fileSize();
+ this->_msize = this->_fsize;
+
+ phdr.first->p_type = llvm::ELF::PT_PHDR;
+ phdr.first->p_offset = this->fileOffset();
+ phdr.first->p_vaddr = this->virtualAddr();
+ phdr.first->p_paddr = this->virtualAddr();
+ phdr.first->p_filesz = this->fileSize();
+ phdr.first->p_memsz = this->memSize();
+ phdr.first->p_flags = llvm::ELF::PF_R;
+ phdr.first->p_align = 8;
+
+ return allocatedNew;
+ }
+
void resetProgramHeaders() {
_phi = _ph.begin();
}
diff --git a/lld/test/elf/dynamic-phdr.test b/lld/test/elf/dynamic-phdr.test
new file mode 100644
index 00000000000..55b81fcc974
--- /dev/null
+++ b/lld/test/elf/dynamic-phdr.test
@@ -0,0 +1,7 @@
+RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN: %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
+RUN: -output-type=dynamic
+RUN: llvm-objdump -p %t | FileCheck %s
+
+CHECK: PHDR off 0x{{0+}}40
+CHECK: flags r--
OpenPOWER on IntegriCloud