[llvm] a33687e - [RuntimeDyld] Add allowStubs/allowZeroSyms
Rafael Auler via llvm-commits
llvm-commits at lists.llvm.org
Tue May 18 11:36:15 PDT 2021
Author: Rafael Auler
Date: 2021-05-18T11:35:27-07:00
New Revision: a33687ec584d18dc0d092853d583d7116808459c
URL: https://github.com/llvm/llvm-project/commit/a33687ec584d18dc0d092853d583d7116808459c
DIFF: https://github.com/llvm/llvm-project/commit/a33687ec584d18dc0d092853d583d7116808459c.diff
LOG: [RuntimeDyld] Add allowStubs/allowZeroSyms
This patch introduces functionality used by BOLT when
re-linking the final binary. It adds to MemoryManager a new member
function allowStubAllocation to control whether this MemoryManager
supports increasing code size with stubs or not. Since BOLT can
rewrite some files in-place, it needs to avoid stub insertion done
by the linker. This patch also introduces allowsZeroSymbols to the
JITSymbolResolver class, enabling us to finish a link successfully
even when some symbols resolve to the value zero. When rewriting a
binary, sometimes we do need to resolve a target to zero in case
the input binary calls address zero and we want to be bug
compatible. We also expose reassignSectionAddress as it is used by
BOLT.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D97898
Added:
Modified:
llvm/include/llvm/ExecutionEngine/JITSymbol.h
llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/JITSymbol.h b/llvm/include/llvm/ExecutionEngine/JITSymbol.h
index 9bbdd21f77de1..440e10cc881f0 100644
--- a/llvm/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/llvm/include/llvm/ExecutionEngine/JITSymbol.h
@@ -390,6 +390,9 @@ class JITSymbolResolver {
virtual Expected<LookupSet>
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 9b83092e653ff..128c9967a5968 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -56,12 +56,11 @@ class RuntimeDyldError : public ErrorInfo<RuntimeDyldError> {
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<void(
StringRef FileName, StringRef SectionName, StringRef SymbolName,
unsigned SectionID, uint32_t StubOffset)>;
@@ -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 57c4e9306af3b..687fd839805fa 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 57852e02ee0b6..30c3856f77eb1 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 ||
More information about the llvm-commits
mailing list