Index: include/llvm-c/ExecutionEngine.h =================================================================== --- include/llvm-c/ExecutionEngine.h +++ include/llvm-c/ExecutionEngine.h @@ -204,6 +204,68 @@ LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, LLVMMemoryManagerDestroyCallback Destroy); +typedef uint8_t *(*LLVMBSMMAllocateCodeSectionCallback)( + void *Opaque, LLVMMCJITMemoryManagerRef MM, uintptr_t Size, unsigned Alignment, unsigned SectionID, + const char *SectionName); +typedef uint8_t *(*LLVMBSMMAllocateDataSectionCallback)( + void *Opaque, LLVMMCJITMemoryManagerRef MM, uintptr_t Size, unsigned Alignment, unsigned SectionID, + const char *SectionName, LLVMBool IsReadOnly); +typedef LLVMBool (*LLVMBSMMFinalizeMemoryCallback)( + void *Opaque, LLVMMCJITMemoryManagerRef MM, char **ErrMsg); +typedef void (*LLVMBSMMDestroyCallback)(void *Opaque); +typedef void (*LLVMBSMMInvalidateInstructionCacheCallback)( + void *Opaque, LLVMMCJITMemoryManagerRef MM); +typedef uint64_t (*LLVMBSMMGetSymbolAddressCallback)( + void *Opaque, LLVMMCJITMemoryManagerRef MM, const char *Name); + +/** + * Create a simple custom MCJIT memory manager based on SectionMemoryManager. + * If any of passed functions in NULL, appropriate method from the parent class + * (SectionMemoryManager) will be called. + * Every callback receives an opaque pointer to the client object and a pointer to the + * memory manager object, so it can call methods from the parent class. + */ +LLVMMCJITMemoryManagerRef LLVMCreateBindingSectionMemoryManager( + void *Opaque, + LLVMBSMMAllocateCodeSectionCallback AllocateCodeSection, + LLVMBSMMAllocateDataSectionCallback AllocateDataSection, + LLVMBSMMFinalizeMemoryCallback FinalizeMemory, + LLVMBSMMInvalidateInstructionCacheCallback InvalidateInstructionCache, + LLVMBSMMGetSymbolAddressCallback GetSymbolAddress, + LLVMBSMMGetSymbolAddressCallback GetSymbolAddressInLogicalDylib, + LLVMBSMMDestroyCallback Destroy); + +uint8_t *LLVMCallSectionMMAllocateCodeSection( + LLVMMCJITMemoryManagerRef MM, + uintptr_t Size, + unsigned Alignment, + unsigned SectionID, + const char *SectionName); + +uint8_t *LLVMBSMMtCallParentAllocateDataSection( + LLVMMCJITMemoryManagerRef MM, + uintptr_t Size, + unsigned Alignment, + unsigned SectionID, + const char *SectionName, + LLVMBool isReadOnly); + +LLVMBool LLVMCallSectionMMFinalizeMemory( + LLVMMCJITMemoryManagerRef MM, + char **ErrMsg); + +void LLVMCallSectionMMInvalidateInstructionCache(LLVMMCJITMemoryManagerRef MM); + +uint64_t LLVMCallSectionMMGetSymbolAddress( + LLVMMCJITMemoryManagerRef MM, + const char *Name); + +uint64_t LLVMCallSectionMMGetSymbolAddressInLogicalDylib( + LLVMMCJITMemoryManagerRef MM, + const char *Name); + +uint64_t LLVMGetSymbolAddressInProcess(const char *Name); + void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM); /** Index: include/llvm/ExecutionEngine/RTDyldMemoryManager.h =================================================================== --- include/llvm/ExecutionEngine/RTDyldMemoryManager.h +++ include/llvm/ExecutionEngine/RTDyldMemoryManager.h @@ -17,6 +17,7 @@ #include "RuntimeDyld.h" #include "llvm-c/ExecutionEngine.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Memory.h" @@ -55,9 +56,19 @@ RTDyldMemoryManager(const RTDyldMemoryManager&) = delete; void operator=(const RTDyldMemoryManager&) = delete; public: - RTDyldMemoryManager() {} + enum RTDyldMMSubclass { + SectionMemoryManager, + SimpleBindingMemoryManager, + TrivialMemoryManager, + RemoteMemoryManager + }; + +public: + RTDyldMemoryManager(RTDyldMMSubclass Subclass) : Subclass(Subclass) {} ~RTDyldMemoryManager() override; + RTDyldMMSubclass getSubclass() const { return Subclass; } + void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override; void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override; @@ -124,10 +135,13 @@ /// MCJIT or RuntimeDyld. Use getSymbolAddress instead. virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); + +private: + const RTDyldMMSubclass Subclass; }; // Create wrappers for C Binding types (see CBindingWrapping.h). -DEFINE_SIMPLE_CONVERSION_FUNCTIONS( +DEFINE_ISA_CONVERSION_FUNCTIONS( RTDyldMemoryManager, LLVMMCJITMemoryManagerRef) } // namespace llvm Index: include/llvm/ExecutionEngine/SectionMemoryManager.h =================================================================== --- include/llvm/ExecutionEngine/SectionMemoryManager.h +++ include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -39,9 +39,13 @@ void operator=(const SectionMemoryManager&) = delete; public: - SectionMemoryManager() { } + SectionMemoryManager() : RTDyldMemoryManager(RTDyldMemoryManager::SectionMemoryManager) { } ~SectionMemoryManager() override; + static bool classof(const RTDyldMemoryManager *MM) { + return MM->getSubclass() == RTDyldMemoryManager::SectionMemoryManager; + } + /// \brief Allocates a memory block of (at least) the given size suitable for /// executable code. /// Index: lib/ExecutionEngine/ExecutionEngineBindings.cpp =================================================================== --- lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -15,6 +15,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" @@ -362,6 +363,8 @@ void *Opaque); ~SimpleBindingMemoryManager() override; + static bool classof(const RTDyldMemoryManager *MM); + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override; @@ -380,7 +383,9 @@ SimpleBindingMemoryManager::SimpleBindingMemoryManager( const SimpleBindingMMFunctions& Functions, void *Opaque) - : Functions(Functions), Opaque(Opaque) { + : RTDyldMemoryManager(RTDyldMemoryManager::SimpleBindingMemoryManager), + Functions(Functions), + Opaque(Opaque) { assert(Functions.AllocateCodeSection && "No AllocateCodeSection function provided!"); assert(Functions.AllocateDataSection && @@ -395,6 +400,11 @@ Functions.Destroy(Opaque); } +bool SimpleBindingMemoryManager::classof(const RTDyldMemoryManager *MM) { + return MM->getSubclass() == RTDyldMemoryManager::SimpleBindingMemoryManager; +} + + uint8_t *SimpleBindingMemoryManager::allocateCodeSection( uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) { @@ -423,6 +433,115 @@ return result; } +struct BSMMFunctions { + LLVMBSMMAllocateCodeSectionCallback AllocateCodeSection; + LLVMBSMMAllocateDataSectionCallback AllocateDataSection; + LLVMBSMMFinalizeMemoryCallback FinalizeMemory; + LLVMBSMMInvalidateInstructionCacheCallback InvalidateInstructionCache; + LLVMBSMMGetSymbolAddressCallback GetSymbolAddress; + LLVMBSMMGetSymbolAddressCallback GetSymbolAddressInLogicalDylib; + LLVMBSMMDestroyCallback Destroy; +}; + +class BindingSectionMemoryManager : public SectionMemoryManager { +public: + BindingSectionMemoryManager(const BSMMFunctions& Functions, void *Opaque); + ~BindingSectionMemoryManager() override; + + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + StringRef SectionName) override; + + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool isReadOnly) override; + + bool finalizeMemory(std::string *ErrMsg = nullptr) override; + + void invalidateInstructionCache() override; + + uint64_t getSymbolAddress(const std::string &Name) override; + + uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) override; + +private: + BSMMFunctions Functions; + void *Opaque; +}; + +BindingSectionMemoryManager::BindingSectionMemoryManager(const BSMMFunctions& Functions, void *Opaque) + : Functions(Functions), Opaque(Opaque) {} + +BindingSectionMemoryManager::~BindingSectionMemoryManager() { + if (Functions.Destroy) { + Functions.Destroy(Opaque); + } +} + +uint8_t *BindingSectionMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + StringRef SectionName) { + if (Functions.AllocateCodeSection) { + return Functions.AllocateCodeSection(Opaque, wrap(this), Size, Alignment, SectionID, + SectionName.str().c_str()); + } else { + return SectionMemoryManager::allocateCodeSection(Size, Alignment, SectionID, SectionName); + } +} + +uint8_t *BindingSectionMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool isReadOnly) { + if (Functions.AllocateDataSection) { + return Functions.AllocateDataSection(Opaque, wrap(this), Size, Alignment, SectionID, + SectionName.str().c_str(), + isReadOnly); + } else { + return SectionMemoryManager::allocateDataSection(Size, Alignment, SectionID, SectionName, isReadOnly); + } +} + +bool BindingSectionMemoryManager::finalizeMemory(std::string *ErrMsg) { + if (Functions.FinalizeMemory) { + char *errMsgCString = nullptr; + bool result = Functions.FinalizeMemory(Opaque, wrap(this), &errMsgCString); + assert((result || !errMsgCString) && + "Did not expect an error message if FinalizeMemory succeeded"); + if (errMsgCString) { + if (ErrMsg) + *ErrMsg = errMsgCString; + free(errMsgCString); + } + return result; + } else { + return SectionMemoryManager::finalizeMemory(ErrMsg); + } +} + +void BindingSectionMemoryManager::invalidateInstructionCache() { + if (Functions.InvalidateInstructionCache) { + Functions.InvalidateInstructionCache(Opaque, wrap(this)); + } else { + SectionMemoryManager::invalidateInstructionCache(); + } +} + +uint64_t BindingSectionMemoryManager::getSymbolAddress(const std::string &Name) { + if (Functions.GetSymbolAddress) { + return Functions.GetSymbolAddress(Opaque, wrap(this), Name.c_str()); + } else { + return SectionMemoryManager::getSymbolAddress(Name); + } +} + +uint64_t BindingSectionMemoryManager::getSymbolAddressInLogicalDylib(const std::string &Name) { + if (Functions.GetSymbolAddressInLogicalDylib) { + return Functions.GetSymbolAddressInLogicalDylib(Opaque, wrap(this), Name.c_str()); + } else { + return SectionMemoryManager::getSymbolAddressInLogicalDylib(Name); + } +} + } // anonymous namespace LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager( @@ -431,11 +550,11 @@ LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, LLVMMemoryManagerDestroyCallback Destroy) { - + if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory || !Destroy) return nullptr; - + SimpleBindingMMFunctions functions; functions.AllocateCodeSection = AllocateCodeSection; functions.AllocateDataSection = AllocateDataSection; @@ -444,6 +563,81 @@ return wrap(new SimpleBindingMemoryManager(functions, Opaque)); } +LLVMMCJITMemoryManagerRef LLVMCreateBindingSectionMemoryManager( + void *Opaque, + LLVMBSMMAllocateCodeSectionCallback AllocateCodeSection, + LLVMBSMMAllocateDataSectionCallback AllocateDataSection, + LLVMBSMMFinalizeMemoryCallback FinalizeMemory, + LLVMBSMMInvalidateInstructionCacheCallback InvalidateInstructionCache, + LLVMBSMMGetSymbolAddressCallback GetSymbolAddress, + LLVMBSMMGetSymbolAddressCallback GetSymbolAddressInLogicalDylib, + LLVMBSMMDestroyCallback Destroy) { + BSMMFunctions functions; + functions.AllocateCodeSection = AllocateCodeSection; + functions.AllocateDataSection = AllocateDataSection; + functions.FinalizeMemory = FinalizeMemory; + functions.InvalidateInstructionCache = InvalidateInstructionCache; + functions.GetSymbolAddress = GetSymbolAddress; + functions.GetSymbolAddressInLogicalDylib = GetSymbolAddressInLogicalDylib; + functions.Destroy = Destroy; + return wrap(new BindingSectionMemoryManager(functions, Opaque)); +} + +uint8_t *LLVMCallSectionMMAllocateCodeSection( + LLVMMCJITMemoryManagerRef MM, + uintptr_t Size, + unsigned Alignment, + unsigned SectionID, + const char *SectionName) { + return unwrap(MM)->SectionMemoryManager::allocateCodeSection( + Size, Alignment, SectionID, SectionName); +} + +uint8_t *LLVMCallSectionMMAllocateDataSection( + LLVMMCJITMemoryManagerRef MM, + uintptr_t Size, + unsigned Alignment, + unsigned SectionID, + const char *SectionName, + LLVMBool isReadOnly) { + return unwrap(MM)->SectionMemoryManager::allocateDataSection( + Size, Alignment, SectionID, SectionName, isReadOnly); +} + +LLVMBool LLVMCallSectionMMFinalizeMemory( + LLVMMCJITMemoryManagerRef MM, + char **ErrMsg) { + std::string errMsg; + bool result = unwrap(MM)->SectionMemoryManager::finalizeMemory(&errMsg); + if (result && !errMsg.empty()) { + *ErrMsg = new char[errMsg.size() + 1]; + std::copy(&(errMsg.c_str()[0]), &(errMsg.c_str()[errMsg.size() - 1]), *ErrMsg); + (*ErrMsg)[errMsg.size()] = '\0'; + } + + return result; +} + +void LLVMCallSectionMMInvalidateInstructionCache(LLVMMCJITMemoryManagerRef MM) { + unwrap(MM)->SectionMemoryManager::invalidateInstructionCache(); +} + +uint64_t LLVMCallSectionMMGetSymbolAddress( + LLVMMCJITMemoryManagerRef MM, + const char *Name) { + return unwrap(MM)->SectionMemoryManager::getSymbolAddress(Name); +} + +uint64_t LLVMCallSectionMMGetSymbolAddressInLogicalDylib( + LLVMMCJITMemoryManagerRef MM, + const char *Name) { + return unwrap(MM)->SectionMemoryManager::getSymbolAddressInLogicalDylib(Name); +} + +uint64_t LLVMGetSymbolAddressInProcess(const char *Name) { + return RTDyldMemoryManager::getSymbolAddressInProcess(Name); +} + void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) { delete unwrap(MM); } Index: tools/lli/RemoteMemoryManager.h =================================================================== --- tools/lli/RemoteMemoryManager.h +++ tools/lli/RemoteMemoryManager.h @@ -63,9 +63,14 @@ RemoteTarget *Target; public: - RemoteMemoryManager() : Target(nullptr) {} + RemoteMemoryManager() : RTDyldMemoryManager(RTDyldMemoryManager::RemoteMemoryManager), + Target(nullptr) {} ~RemoteMemoryManager() override; + static bool classof(const RTDyldMemoryManager *MM) { + return MM->getSubclass() == RTDyldMemoryManager::RemoteMemoryManager; + } + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override; Index: tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- tools/llvm-rtdyld/llvm-rtdyld.cpp +++ tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -136,6 +136,12 @@ SmallVector FunctionMemory; SmallVector DataMemory; + TrivialMemoryManager() : RTDyldMemoryManager(RTDyldMemoryManager::TrivialMemoryManager) {} + + static bool classof(const RTDyldMemoryManager *MM) { + return MM->getSubclass() == RTDyldMemoryManager::TrivialMemoryManager; + } + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override;