[ELF] Add support for IFUNC.
This sadly doesn't have a test for the final
output because llvm-objdump can't dump relocations
that don't belong to a section :(
llvm-svn: 173808
diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
index d43ebfb..fa744ca 100644
--- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
@@ -156,6 +156,8 @@
_runtimeFile.addAbsoluteAtom("end");
_runtimeFile.addAbsoluteAtom("__init_array_start");
_runtimeFile.addAbsoluteAtom("__init_array_end");
+ _runtimeFile.addAbsoluteAtom("__rela_iplt_start");
+ _runtimeFile.addAbsoluteAtom("__rela_iplt_end");
}
/// \brief Hook in lld to add CRuntime file
@@ -169,41 +171,47 @@
/// created
template<class ELFT>
void ELFExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
- auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
- auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
- auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
- auto endAtomIter = _layout->findAbsoluteAtom("end");
- auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
- auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
+ auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
+ auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
+ auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
+ auto endAtomIter = _layout->findAbsoluteAtom("end");
+ auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
+ auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
+ auto realIpltStartIter = _layout->findAbsoluteAtom("__rela_iplt_start");
+ auto realIpltEndIter = _layout->findAbsoluteAtom("__rela_iplt_end");
- auto section = _layout->findOutputSection(".init_array");
- if (section) {
- initArrayStartIter->setValue(section->virtualAddr());
- initArrayEndIter->setValue(section->virtualAddr() +
- section->memSize());
- } else {
- initArrayStartIter->setValue(0);
- initArrayEndIter->setValue(0);
- }
+ auto startEnd = [&](typename DefaultELFLayout<ELFT>::AbsoluteAtomIterT start,
+ typename DefaultELFLayout<ELFT>::AbsoluteAtomIterT end,
+ StringRef sec) -> void {
+ auto section = _layout->findOutputSection(sec);
+ if (section) {
+ start->setValue(section->virtualAddr());
+ end->setValue(section->virtualAddr() + section->memSize());
+ } else {
+ start->setValue(0);
+ end->setValue(0);
+ }
+ };
- assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
- bssEndAtomIter == _layout->absoluteAtoms().end() ||
- underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
- endAtomIter == _layout->absoluteAtoms().end()) &&
- "Unable to find the absolute atoms that have been added by lld");
+ startEnd(initArrayStartIter, initArrayEndIter, ".init_array");
+ startEnd(realIpltStartIter, realIpltEndIter, ".rela.plt");
- auto phe = _programHeader->findProgramHeader(
- llvm::ELF::PT_LOAD,
- llvm::ELF::PF_W,
- llvm::ELF::PF_X);
+ assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
+ bssEndAtomIter == _layout->absoluteAtoms().end() ||
+ underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
+ endAtomIter == _layout->absoluteAtoms().end()) &&
+ "Unable to find the absolute atoms that have been added by lld");
- assert(!(phe == _programHeader->end()) &&
- "Can't find a data segment in the program header!");
+ auto phe = _programHeader->findProgramHeader(
+ llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
- bssStartAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_filesz);
- bssEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
- underScoreEndAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
- endAtomIter->setValue((*phe)->p_vaddr+(*phe)->p_memsz);
+ assert(!(phe == _programHeader->end()) &&
+ "Can't find a data segment in the program header!");
+
+ bssStartAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_filesz);
+ bssEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
+ underScoreEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
+ endAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
}
template<class ELFT>