diff --git a/llvm/include/llvm/ExecutionEngine/JITSymbol.h b/llvm/include/llvm/ExecutionEngine/JITSymbol.h index 9bbdd21f77de1a..440e10cc881f03 100644 --- a/llvm/include/llvm/ExecutionEngine/JITSymbol.h +++ b/llvm/include/llvm/ExecutionEngine/JITSymbol.h @@ -390,6 +390,9 @@ class JITSymbolResolver { virtual Expected getResponsibilitySet(const LookupSet &Symbols) = 0; + /// Specify if this resolver can return valid symbols with zero value. + virtual bool allowsZeroSymbols() { return false; } + private: virtual void anchor(); }; diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h index 9b83092e653ffe..128c9967a59686 100644 --- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -56,12 +56,11 @@ class RuntimeDyldError : public ErrorInfo { class RuntimeDyldImpl; class RuntimeDyld { -protected: +public: // Change the address associated with a section when resolving relocations. // Any relocations already associated with the symbol will be re-resolved. void reassignSectionAddress(unsigned SectionID, uint64_t Addr); -public: using NotifyStubEmittedFunction = std::function; @@ -130,6 +129,11 @@ class RuntimeDyld { /// Override to return true to enable the reserveAllocationSpace callback. virtual bool needsToReserveAllocationSpace() { return false; } + /// Override to return false to tell LLVM no stub space will be needed. + /// This requires some guarantees depending on architecuture, but when + /// you know what you are doing it saves allocated space. + virtual bool allowStubAllocation() const { return true; } + /// Register the EH frames with the runtime so that c++ exceptions work. /// /// \p Addr parameter provides the local address of the EH frame section diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 57c4e9306af3b7..687fd839805fad 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -655,6 +655,10 @@ unsigned RuntimeDyldImpl::computeGOTSize(const ObjectFile &Obj) { // compute stub buffer size for the given section unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section) { + if (!MemMgr.allowStubAllocation()) { + return 0; + } + unsigned StubSize = getMaxStubSize(); if (StubSize == 0) { return 0; @@ -1113,7 +1117,7 @@ void RuntimeDyldImpl::applyExternalSymbolRelocations( } // FIXME: Implement error handling that doesn't kill the host program! - if (!Addr) + if (!Addr && !Resolver.allowsZeroSymbols()) report_fatal_error("Program used external function '" + Name + "' which could not be resolved!"); diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 57852e02ee0b65..30c3856f77eb13 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -1269,7 +1269,9 @@ RuntimeDyldELF::processRelocationRef( LLVM_DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset << "\n"); if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be)) { - if (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26) { + if ((RelType == ELF::R_AARCH64_CALL26 || + RelType == ELF::R_AARCH64_JUMP26) && + MemMgr.allowStubAllocation()) { resolveAArch64Branch(SectionID, Value, RelI, Stubs); } else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) { // Craete new GOT entry or find existing one. If GOT entry is @@ -1732,7 +1734,7 @@ RuntimeDyldELF::processRelocationRef( // equivalent to the usual PLT implementation except that we use the stub // mechanism in RuntimeDyld (which puts stubs at the end of the section) // rather than allocating a PLT section. - if (Value.SymbolName) { + if (Value.SymbolName && MemMgr.allowStubAllocation()) { // This is a call to an external function. // Look for an existing stub. SectionEntry *Section = &Sections[SectionID]; @@ -1777,9 +1779,9 @@ RuntimeDyldELF::processRelocationRef( resolveRelocation(*Section, Offset, StubAddress, ELF::R_X86_64_PC32, Addend); } else { - RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend, - Value.Offset); - addRelocationForSection(RE, Value.SectionID); + Value.Addend += support::ulittle32_t::ref( + computePlaceholderAddress(SectionID, Offset)); + processSimpleRelocation(SectionID, Offset, ELF::R_X86_64_PC32, Value); } } else if (RelType == ELF::R_X86_64_GOTPCREL || RelType == ELF::R_X86_64_GOTPCRELX ||