diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index a9aaff42433f6..fc6353900e891 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 9255311f992d0..e6455ce4a70e0 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp @@ -118,4 +118,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->startswith(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 501417db421a6..a7fdbc5e5b038 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -449,6 +449,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)