[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