diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 7eb7da0138c97..5ac5532705dc4 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -690,9 +690,12 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, if (!(RelSecI == Section)) continue; - for (const RelocationRef &Reloc : SI->relocations()) + for (const RelocationRef &Reloc : SI->relocations()) { if (relocationNeedsStub(Reloc)) StubBufSize += StubSize; + if (relocationNeedsDLLImportStub(Reloc)) + StubBufSize = sizeAfterAddingDLLImportStub(StubBufSize); + } } // Get section data size and alignment diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp index 25a2d8780fb56..73b37ee0ff331 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp @@ -119,4 +119,14 @@ bool RuntimeDyldCOFF::isCompatibleFile(const object::ObjectFile &Obj) const { return Obj.isCOFF(); } +bool RuntimeDyldCOFF::relocationNeedsDLLImportStub( + const RelocationRef &R) const { + object::symbol_iterator Symbol = R.getSymbol(); + Expected TargetNameOrErr = Symbol->getName(); + if (!TargetNameOrErr) + return false; + + return TargetNameOrErr->starts_with(getImportSymbolPrefix()); +} + } // namespace llvm diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h index 41ee06c15448f..f58faebf6a004 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h @@ -14,6 +14,7 @@ #define LLVM_RUNTIME_DYLD_COFF_H #include "RuntimeDyldImpl.h" +#include "llvm/Support/MathExtras.h" #define DEBUG_TYPE "dyld" @@ -49,6 +50,12 @@ class RuntimeDyldCOFF : public RuntimeDyldImpl { static constexpr StringRef getImportSymbolPrefix() { return "__imp_"; } + bool relocationNeedsDLLImportStub(const RelocationRef &R) const; + + unsigned sizeAfterAddingDLLImportStub(unsigned Size) const { + return alignTo(Size, PointerSize) + PointerSize; + } + private: unsigned PointerSize; uint32_t PointerReloc; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index e09c632842d6e..de7630b9747ea 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -455,6 +455,16 @@ class RuntimeDyldImpl { return true; // Conservative answer } + // Return true if the relocation R may require allocating a DLL import stub. + virtual bool relocationNeedsDLLImportStub(const RelocationRef &R) const { + return false; + } + + // Add the size of a DLL import stub to the buffer size + virtual unsigned sizeAfterAddingDLLImportStub(unsigned Size) const { + return Size; + } + public: RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)