diff options
Diffstat (limited to 'include/llvm/ExecutionEngine')
-rw-r--r-- | include/llvm/ExecutionEngine/ExecutionEngine.h | 202 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/JIT.h | 38 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/JITEventListener.h | 36 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/JITMemoryManager.h | 164 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/ObjectBuffer.h | 83 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/ObjectCache.h | 11 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/ObjectImage.h | 71 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/RTDyldMemoryManager.h | 21 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/RuntimeDyld.h | 51 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/RuntimeDyldChecker.h | 53 |
10 files changed, 137 insertions, 593 deletions
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index e5dab6191ab6..d79bd3c4dfc8 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -18,9 +18,11 @@ #include "llvm-c/ExecutionEngine.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueMap.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/Object/Binary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mutex.h" #include "llvm/Target/TargetMachine.h" @@ -39,9 +41,7 @@ class Function; class GlobalVariable; class GlobalValue; class JITEventListener; -class JITMemoryManager; class MachineCodeInfo; -class Module; class MutexGuard; class ObjectCache; class RTDyldMemoryManager; @@ -131,29 +131,20 @@ class ExecutionEngine { protected: /// The list of Modules that we are JIT'ing from. We use a SmallVector to /// optimize for the case where there is only one module. - SmallVector<Module*, 1> Modules; + SmallVector<std::unique_ptr<Module>, 1> Modules; void setDataLayout(const DataLayout *Val) { DL = Val; } /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); - // To avoid having libexecutionengine depend on the JIT and interpreter - // libraries, the execution engine implementations set these functions to ctor - // pointers at startup time if they are linked in. - static ExecutionEngine *(*JITCtor)( - Module *M, - std::string *ErrorStr, - JITMemoryManager *JMM, - bool GVsWithCode, - TargetMachine *TM); static ExecutionEngine *(*MCJITCtor)( - Module *M, - std::string *ErrorStr, - RTDyldMemoryManager *MCJMM, - bool GVsWithCode, - TargetMachine *TM); - static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); + std::unique_ptr<Module> M, + std::string *ErrorStr, + std::unique_ptr<RTDyldMemoryManager> MCJMM, + std::unique_ptr<TargetMachine> TM); + static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M, + std::string *ErrorStr); /// LazyFunctionCreator - If an unknown function is needed, this function /// pointer is invoked to create it. If this returns null, the JIT will @@ -161,9 +152,8 @@ protected: void *(*LazyFunctionCreator)(const std::string &); public: - /// lock - This lock protects the ExecutionEngine, MCJIT, JIT, JITResolver and - /// JITEmitter classes. It must be held while changing the internal state of - /// any of those classes. + /// lock - This lock protects the ExecutionEngine and MCJIT classes. It must + /// be held while changing the internal state of any of those classes. sys::Mutex lock; //===--------------------------------------------------------------------===// @@ -172,44 +162,9 @@ public: virtual ~ExecutionEngine(); - /// create - This is the factory method for creating an execution engine which - /// is appropriate for the current machine. This takes ownership of the - /// module. - /// - /// \param GVsWithCode - Allocating globals with code breaks - /// freeMachineCodeForFunction and is probably unsafe and bad for performance. - /// However, we have clients who depend on this behavior, so we must support - /// it. Eventually, when we're willing to break some backwards compatibility, - /// this flag should be flipped to false, so that by default - /// freeMachineCodeForFunction works. - static ExecutionEngine *create(Module *M, - bool ForceInterpreter = false, - std::string *ErrorStr = nullptr, - CodeGenOpt::Level OptLevel = - CodeGenOpt::Default, - bool GVsWithCode = true); - - /// createJIT - This is the factory method for creating a JIT for the current - /// machine, it does not fall back to the interpreter. This takes ownership - /// of the Module and JITMemoryManager if successful. - /// - /// Clients should make sure to initialize targets prior to calling this - /// function. - static ExecutionEngine *createJIT(Module *M, - std::string *ErrorStr = nullptr, - JITMemoryManager *JMM = nullptr, - CodeGenOpt::Level OptLevel = - CodeGenOpt::Default, - bool GVsWithCode = true, - Reloc::Model RM = Reloc::Default, - CodeModel::Model CMM = - CodeModel::JITDefault); - - /// addModule - Add a Module to the list of modules that we can JIT from. - /// Note that this takes ownership of the Module: when the ExecutionEngine is - /// destroyed, it destroys the Module as well. - virtual void addModule(Module *M) { - Modules.push_back(M); + /// Add a Module to the list of modules that we can JIT from. + virtual void addModule(std::unique_ptr<Module> M) { + Modules.push_back(std::move(M)); } /// addObjectFile - Add an ObjectFile to the execution engine. @@ -223,6 +178,7 @@ public: /// /// MCJIT will take ownership of the ObjectFile. virtual void addObjectFile(std::unique_ptr<object::ObjectFile> O); + virtual void addObjectFile(object::OwningBinary<object::ObjectFile> O); /// addArchive - Add an Archive to the execution engine. /// @@ -230,11 +186,7 @@ public: /// resolve external symbols in objects it is loading. If a symbol is found /// in the Archive the contained object file will be extracted (in memory) /// and loaded for possible execution. - /// - /// MCJIT will take ownership of the Archive. - virtual void addArchive(object::Archive *A) { - llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive."); - } + virtual void addArchive(object::OwningBinary<object::Archive> A); //===--------------------------------------------------------------------===// @@ -263,11 +215,7 @@ public: /// it prints a message to stderr and aborts. /// /// This function is deprecated for the MCJIT execution engine. - /// - /// FIXME: the JIT and MCJIT interfaces should be disentangled or united - /// again, if possible. - /// - virtual void *getPointerToNamedFunction(const std::string &Name, + virtual void *getPointerToNamedFunction(StringRef Name, bool AbortOnFailure = true) = 0; /// mapSectionAddress - map a section to its target address space value. @@ -279,7 +227,7 @@ public: "EE!"); } - /// generateCodeForModule - Run code generationen for the specified module and + /// generateCodeForModule - Run code generation for the specified module and /// load it into memory. /// /// When this function has completed, all code and data for the specified @@ -293,7 +241,7 @@ public: /// locally can use the getFunctionAddress call, which will generate code /// and apply final preparations all in one step. /// - /// This method has no effect for the legacy JIT engine or the interpeter. + /// This method has no effect for the interpeter. virtual void generateCodeForModule(Module *M) {} /// finalizeObject - ensure the module is fully processed and is usable. @@ -302,8 +250,7 @@ public: /// object usable for execution. It should be called after sections within an /// object have been relocated using mapSectionAddress. When this method is /// called the MCJIT execution engine will reapply relocations for a loaded - /// object. This method has no effect for the legacy JIT engine or the - /// interpeter. + /// object. This method has no effect for the interpeter. virtual void finalizeObject() {} /// runStaticConstructorsDestructors - This method is used to execute all of @@ -312,11 +259,11 @@ public: /// \param isDtors - Run the destructors instead of constructors. virtual void runStaticConstructorsDestructors(bool isDtors); - /// runStaticConstructorsDestructors - This method is used to execute all of - /// the static constructors or destructors for a particular module. + /// This method is used to execute all of the static constructors or + /// destructors for a particular module. /// /// \param isDtors - Run the destructors instead of constructors. - void runStaticConstructorsDestructors(Module *module, bool isDtors); + void runStaticConstructorsDestructors(Module &module, bool isDtors); /// runFunctionAsMain - This is a helper function which wraps runFunction to @@ -373,13 +320,6 @@ public: /// getFunctionAddress instead. virtual void *getPointerToFunction(Function *F) = 0; - /// getPointerToBasicBlock - The different EE's represent basic blocks in - /// different ways. Return the representation for a blockaddress of the - /// specified block. - /// - /// This function will not be implemented for the MCJIT execution engine. - virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; - /// getPointerToFunctionOrStub - If the specified function has been /// code-gen'd, return a pointer to the function. If not, compile it, or use /// a stub to implement lazy compilation if available. See @@ -395,9 +335,9 @@ public: /// getGlobalValueAddress - Return the address of the specified global /// value. This may involve code generation. /// - /// This function should not be called with the JIT or interpreter engines. + /// This function should not be called with the interpreter engine. virtual uint64_t getGlobalValueAddress(const std::string &Name) { - // Default implementation for JIT and interpreter. MCJIT will override this. + // Default implementation for the interpreter. MCJIT will override this. // JIT and interpreter clients should use getPointerToGlobal instead. return 0; } @@ -405,14 +345,11 @@ public: /// getFunctionAddress - Return the address of the specified function. /// This may involve code generation. virtual uint64_t getFunctionAddress(const std::string &Name) { - // Default implementation for JIT and interpreter. MCJIT will override this. - // JIT and interpreter clients should use getPointerToFunction instead. + // Default implementation for the interpreter. MCJIT will override this. + // Interpreter clients should use getPointerToFunction instead. return 0; } - // The JIT overrides a version that actually does this. - virtual void runJITOnFunction(Function *, MachineCodeInfo * = nullptr) { } - /// getGlobalValueAtAddress - Return the LLVM global value object that starts /// at the specified address. /// @@ -427,18 +364,6 @@ public: void InitializeMemory(const Constant *Init, void *Addr); - /// recompileAndRelinkFunction - This method is used to force a function which - /// has already been compiled to be compiled again, possibly after it has been - /// modified. Then the entry to the old copy is overwritten with a branch to - /// the new copy. If there was no old copy, this acts just like - /// VM::getPointerToFunction(). - virtual void *recompileAndRelinkFunction(Function *F) = 0; - - /// freeMachineCodeForFunction - Release memory in the ExecutionEngine - /// corresponding to the machine code emitted to execute this function, useful - /// for garbage-collecting generated code. - virtual void freeMachineCodeForFunction(Function *F) = 0; - /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the /// Emitter. @@ -457,7 +382,7 @@ public: virtual void UnregisterJITEventListener(JITEventListener *) {} /// Sets the pre-compiled object cache. The ownership of the ObjectCache is - /// not changed. Supported by MCJIT but not JIT. + /// not changed. Supported by MCJIT but not the interpreter. virtual void setObjectCache(ObjectCache *) { llvm_unreachable("No support for an object cache"); } @@ -499,11 +424,6 @@ public: bool isCompilingLazily() const { return CompilingLazily; } - // Deprecated in favor of isCompilingLazily (to reduce double-negatives). - // Remove this in LLVM 2.8. - bool isLazyCompilationDisabled() const { - return !CompilingLazily; - } /// DisableGVCompilation - If called, the JIT will abort if it's asked to /// allocate space and populate a GlobalVariable that is not internal to @@ -544,7 +464,7 @@ public: } protected: - explicit ExecutionEngine(Module *M); + explicit ExecutionEngine(std::unique_ptr<Module> M); void emitGlobals(); @@ -564,36 +484,33 @@ namespace EngineKind { const static Kind Either = (Kind)(JIT | Interpreter); } -/// EngineBuilder - Builder class for ExecutionEngines. Use this by -/// stack-allocating a builder, chaining the various set* methods, and -/// terminating it with a .create() call. +/// Builder class for ExecutionEngines. Use this by stack-allocating a builder, +/// chaining the various set* methods, and terminating it with a .create() +/// call. class EngineBuilder { private: - Module *M; + std::unique_ptr<Module> M; EngineKind::Kind WhichEngine; std::string *ErrorStr; CodeGenOpt::Level OptLevel; - RTDyldMemoryManager *MCJMM; - JITMemoryManager *JMM; - bool AllocateGVsWithCode; + std::unique_ptr<RTDyldMemoryManager> MCJMM; TargetOptions Options; Reloc::Model RelocModel; CodeModel::Model CMModel; std::string MArch; std::string MCPU; SmallVector<std::string, 4> MAttrs; - bool UseMCJIT; bool VerifyModules; /// InitEngine - Does the common initialization of default options. void InitEngine(); public: - /// EngineBuilder - Constructor for EngineBuilder. If create() is called and - /// is successful, the created engine takes ownership of the module. - EngineBuilder(Module *m) : M(m) { - InitEngine(); - } + /// Constructor for EngineBuilder. + EngineBuilder(std::unique_ptr<Module> M); + + // Out-of-line since we don't have the def'n of RTDyldMemoryManager here. + ~EngineBuilder(); /// setEngineKind - Controls whether the user wants the interpreter, the JIT, /// or whichever engine works. This option defaults to EngineKind::Either. @@ -607,26 +524,8 @@ public: /// is only appropriate for the MCJIT; setting this and configuring the builder /// to create anything other than MCJIT will cause a runtime error. If create() /// is called and is successful, the created engine takes ownership of the - /// memory manager. This option defaults to NULL. Using this option nullifies - /// the setJITMemoryManager() option. - EngineBuilder &setMCJITMemoryManager(RTDyldMemoryManager *mcjmm) { - MCJMM = mcjmm; - JMM = nullptr; - return *this; - } - - /// setJITMemoryManager - Sets the JIT memory manager to use. This allows - /// clients to customize their memory allocation policies. This is only - /// appropriate for either JIT or MCJIT; setting this and configuring the - /// builder to create an interpreter will cause a runtime error. If create() - /// is called and is successful, the created engine takes ownership of the - /// memory manager. This option defaults to NULL. This option overrides - /// setMCJITMemoryManager() as well. - EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) { - MCJMM = nullptr; - JMM = jmm; - return *this; - } + /// memory manager. This option defaults to NULL. + EngineBuilder &setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager> mcjmm); /// setErrorStr - Set the error string to write to on error. This option /// defaults to NULL. @@ -664,18 +563,6 @@ public: return *this; } - /// setAllocateGVsWithCode - Sets whether global values should be allocated - /// into the same buffer as code. For most applications this should be set - /// to false. Allocating globals with code breaks freeMachineCodeForFunction - /// and is probably unsafe and bad for performance. However, we have clients - /// who depend on this behavior, so we must support it. This option defaults - /// to false so that users of the new API can safely use the new memory - /// manager and free machine code. - EngineBuilder &setAllocateGVsWithCode(bool a) { - AllocateGVsWithCode = a; - return *this; - } - /// setMArch - Override the architecture set by the Module's triple. EngineBuilder &setMArch(StringRef march) { MArch.assign(march.begin(), march.end()); @@ -688,13 +575,6 @@ public: return *this; } - /// setUseMCJIT - Set whether the MC-JIT implementation should be used - /// (experimental). - EngineBuilder &setUseMCJIT(bool Value) { - UseMCJIT = Value; - return *this; - } - /// setVerifyModules - Set whether the JIT implementation should verify /// IR modules during compilation. EngineBuilder &setVerifyModules(bool Verify) { diff --git a/include/llvm/ExecutionEngine/JIT.h b/include/llvm/ExecutionEngine/JIT.h deleted file mode 100644 index 581d6e6c35eb..000000000000 --- a/include/llvm/ExecutionEngine/JIT.h +++ /dev/null @@ -1,38 +0,0 @@ -//===-- JIT.h - Abstract Execution Engine Interface -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file forces the JIT to link in on certain operating systems. -// (Windows). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_JIT_H -#define LLVM_EXECUTIONENGINE_JIT_H - -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include <cstdlib> - -extern "C" void LLVMLinkInJIT(); - -namespace { - struct ForceJITLinking { - ForceJITLinking() { - // We must reference JIT in such a way that compilers will not - // delete it all as dead code, even with whole program optimization, - // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that getenv() never returns -1, this will do the job. - if (std::getenv("bar") != (char*) -1) - return; - - LLVMLinkInJIT(); - } - } ForceJITLinking; -} - -#endif diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index 99fe36c6b5f6..c3edec868783 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -15,6 +15,7 @@ #ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H #define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H +#include "RuntimeDyld.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/DebugLoc.h" #include "llvm/Support/DataTypes.h" @@ -25,7 +26,10 @@ class Function; class MachineFunction; class OProfileWrapper; class IntelJITEventsWrapper; -class ObjectImage; + +namespace object { + class ObjectFile; +} /// JITEvent_EmittedFunctionDetails - Helper struct for containing information /// about a generated machine code function. @@ -57,24 +61,7 @@ public: public: JITEventListener() {} - virtual ~JITEventListener(); - - /// NotifyFunctionEmitted - Called after a function has been successfully - /// emitted to memory. The function still has its MachineFunction attached, - /// if you should happen to need that. - virtual void NotifyFunctionEmitted(const Function &, - void *, size_t, - const EmittedFunctionDetails &) {} - - /// NotifyFreeingMachineCode - Called from freeMachineCodeForFunction(), after - /// the global mapping is removed, but before the machine code is returned to - /// the allocator. - /// - /// OldPtr is the address of the machine code and will be the same as the Code - /// parameter to a previous NotifyFunctionEmitted call. The Function passed - /// to NotifyFunctionEmitted may have been destroyed by the time of the - /// matching NotifyFreeingMachineCode call. - virtual void NotifyFreeingMachineCode(void *) {} + virtual ~JITEventListener() {} /// NotifyObjectEmitted - Called after an object has been successfully /// emitted to memory. NotifyFunctionEmitted will not be called for @@ -84,11 +71,15 @@ public: /// The ObjectImage contains the generated object image /// with section headers updated to reflect the address at which sections /// were loaded and with relocations performed in-place on debug sections. - virtual void NotifyObjectEmitted(const ObjectImage &Obj) {} + virtual void NotifyObjectEmitted(const object::ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) {} /// NotifyFreeingObject - Called just before the memory associated with /// a previously emitted object is released. - virtual void NotifyFreeingObject(const ObjectImage &Obj) {} + virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {} + + // Get a pointe to the GDB debugger registration listener. + static JITEventListener *createGDBRegistrationListener(); #if LLVM_USE_INTEL_JITEVENTS // Construct an IntelJITEventListener @@ -122,7 +113,8 @@ public: return nullptr; } #endif // USE_OPROFILE - +private: + virtual void anchor(); }; } // end namespace llvm. diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h deleted file mode 100644 index b22d899c9fec..000000000000 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ /dev/null @@ -1,164 +0,0 @@ -//===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H -#define LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H - -#include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/Support/DataTypes.h" -#include <string> - -namespace llvm { - - class Function; - class GlobalValue; - -/// JITMemoryManager - This interface is used by the JIT to allocate and manage -/// memory for the code generated by the JIT. This can be reimplemented by -/// clients that have a strong desire to control how the layout of JIT'd memory -/// works. -class JITMemoryManager : public RTDyldMemoryManager { -protected: - bool HasGOT; - -public: - JITMemoryManager() : HasGOT(false) {} - virtual ~JITMemoryManager(); - - /// CreateDefaultMemManager - This is used to create the default - /// JIT Memory Manager if the client does not provide one to the JIT. - static JITMemoryManager *CreateDefaultMemManager(); - - /// setMemoryWritable - When code generation is in progress, - /// the code pages may need permissions changed. - virtual void setMemoryWritable() = 0; - - /// setMemoryExecutable - When code generation is done and we're ready to - /// start execution, the code pages may need permissions changed. - virtual void setMemoryExecutable() = 0; - - /// setPoisonMemory - Setting this flag to true makes the memory manager - /// garbage values over freed memory. This is useful for testing and - /// debugging, and may be turned on by default in debug mode. - virtual void setPoisonMemory(bool poison) = 0; - - //===--------------------------------------------------------------------===// - // Global Offset Table Management - //===--------------------------------------------------------------------===// - - /// AllocateGOT - If the current table requires a Global Offset Table, this - /// method is invoked to allocate it. This method is required to set HasGOT - /// to true. - virtual void AllocateGOT() = 0; - - /// isManagingGOT - Return true if the AllocateGOT method is called. - bool isManagingGOT() const { - return HasGOT; - } - - /// getGOTBase - If this is managing a Global Offset Table, this method should - /// return a pointer to its base. - virtual uint8_t *getGOTBase() const = 0; - - //===--------------------------------------------------------------------===// - // Main Allocation Functions - //===--------------------------------------------------------------------===// - - /// startFunctionBody - When we start JITing a function, the JIT calls this - /// method to allocate a block of free RWX memory, which returns a pointer to - /// it. If the JIT wants to request a block of memory of at least a certain - /// size, it passes that value as ActualSize, and this method returns a block - /// with at least that much space. If the JIT doesn't know ahead of time how - /// much space it will need to emit the function, it passes 0 for the - /// ActualSize. In either case, this method is required to pass back the size - /// of the allocated block through ActualSize. The JIT will be careful to - /// not write more than the returned ActualSize bytes of memory. - virtual uint8_t *startFunctionBody(const Function *F, - uintptr_t &ActualSize) = 0; - - /// allocateStub - This method is called by the JIT to allocate space for a - /// function stub (used to handle limited branch displacements) while it is - /// JIT compiling a function. For example, if foo calls bar, and if bar - /// either needs to be lazily compiled or is a native function that exists too - /// far away from the call site to work, this method will be used to make a - /// thunk for it. The stub should be "close" to the current function body, - /// but should not be included in the 'actualsize' returned by - /// startFunctionBody. - virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment) = 0; - - /// endFunctionBody - This method is called when the JIT is done codegen'ing - /// the specified function. At this point we know the size of the JIT - /// compiled function. This passes in FunctionStart (which was returned by - /// the startFunctionBody method) and FunctionEnd which is a pointer to the - /// actual end of the function. This method should mark the space allocated - /// and remember where it is in case the client wants to deallocate it. - virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd) = 0; - - /// allocateSpace - Allocate a memory block of the given size. This method - /// cannot be called between calls to startFunctionBody and endFunctionBody. - virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) = 0; - - /// allocateGlobal - Allocate memory for a global. - virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0; - - /// deallocateFunctionBody - Free the specified function body. The argument - /// must be the return value from a call to startFunctionBody() that hasn't - /// been deallocated yet. This is never called when the JIT is currently - /// emitting a function. - virtual void deallocateFunctionBody(void *Body) = 0; - - /// CheckInvariants - For testing only. Return true if all internal - /// invariants are preserved, or return false and set ErrorStr to a helpful - /// error message. - virtual bool CheckInvariants(std::string &) { - return true; - } - - /// GetDefaultCodeSlabSize - For testing only. Returns DefaultCodeSlabSize - /// from DefaultJITMemoryManager. - virtual size_t GetDefaultCodeSlabSize() { - return 0; - } - - /// GetDefaultDataSlabSize - For testing only. Returns DefaultCodeSlabSize - /// from DefaultJITMemoryManager. - virtual size_t GetDefaultDataSlabSize() { - return 0; - } - - /// GetDefaultStubSlabSize - For testing only. Returns DefaultCodeSlabSize - /// from DefaultJITMemoryManager. - virtual size_t GetDefaultStubSlabSize() { - return 0; - } - - /// GetNumCodeSlabs - For testing only. Returns the number of MemoryBlocks - /// allocated for code. - virtual unsigned GetNumCodeSlabs() { - return 0; - } - - /// GetNumDataSlabs - For testing only. Returns the number of MemoryBlocks - /// allocated for data. - virtual unsigned GetNumDataSlabs() { - return 0; - } - - /// GetNumStubSlabs - For testing only. Returns the number of MemoryBlocks - /// allocated for function stubs. - virtual unsigned GetNumStubSlabs() { - return 0; - } -}; - -} // end namespace llvm. - -#endif diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h deleted file mode 100644 index 6221d3b335df..000000000000 --- a/include/llvm/ExecutionEngine/ObjectBuffer.h +++ /dev/null @@ -1,83 +0,0 @@ -//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares a wrapper class to hold the memory into which an -// object will be generated. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H -#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvm { - -/// ObjectBuffer - This class acts as a container for the memory buffer used during -/// generation and loading of executable objects using MCJIT and RuntimeDyld. The -/// underlying memory for the object will be owned by the ObjectBuffer instance -/// throughout its lifetime. The getMemBuffer() method provides a way to create a -/// MemoryBuffer wrapper object instance to be owned by other classes (such as -/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the -/// actual memory it points to. -class ObjectBuffer { - virtual void anchor(); -public: - ObjectBuffer() {} - ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {} - virtual ~ObjectBuffer() {} - - /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function - /// returns a pointer to an object that is owned by the caller. However, - /// the caller does not take ownership of the underlying memory. - MemoryBuffer *getMemBuffer() const { - return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), - Buffer->getBufferIdentifier(), false); - } - - const char *getBufferStart() const { return Buffer->getBufferStart(); } - size_t getBufferSize() const { return Buffer->getBufferSize(); } - StringRef getBuffer() const { return Buffer->getBuffer(); } - -protected: - // The memory contained in an ObjectBuffer - std::unique_ptr<MemoryBuffer> Buffer; -}; - -/// ObjectBufferStream - This class encapsulates the SmallVector and -/// raw_svector_ostream needed to generate an object using MC code emission -/// while providing a common ObjectBuffer interface for access to the -/// memory once the object has been generated. -class ObjectBufferStream : public ObjectBuffer { - void anchor() override; -public: - ObjectBufferStream() : OS(SV) {} - virtual ~ObjectBufferStream() {} - - raw_ostream &getOStream() { return OS; } - void flush() - { - OS.flush(); - - // Make the data accessible via the ObjectBuffer::Buffer - Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()), - "", - false)); - } - -protected: - SmallVector<char, 4096> SV; // Working buffer into which we JIT. - raw_svector_ostream OS; // streaming wrapper -}; - -} // namespace llvm - -#endif diff --git a/include/llvm/ExecutionEngine/ObjectCache.h b/include/llvm/ExecutionEngine/ObjectCache.h index d1849dfc3bf6..cc01a4e58999 100644 --- a/include/llvm/ExecutionEngine/ObjectCache.h +++ b/include/llvm/ExecutionEngine/ObjectCache.h @@ -27,13 +27,12 @@ public: virtual ~ObjectCache() { } /// notifyObjectCompiled - Provides a pointer to compiled code for Module M. - virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) = 0; + virtual void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) = 0; - /// getObjectCopy - Returns a pointer to a newly allocated MemoryBuffer that - /// contains the object which corresponds with Module M, or 0 if an object is - /// not available. The caller owns both the MemoryBuffer returned by this - /// and the memory it references. - virtual MemoryBuffer* getObject(const Module* M) = 0; + /// Returns a pointer to a newly allocated MemoryBuffer that contains the + /// object which corresponds with Module M, or 0 if an object is not + /// available. + virtual std::unique_ptr<MemoryBuffer> getObject(const Module* M) = 0; }; } diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h deleted file mode 100644 index 1fcedd8d6a92..000000000000 --- a/include/llvm/ExecutionEngine/ObjectImage.h +++ /dev/null @@ -1,71 +0,0 @@ -//===---- ObjectImage.h - Format independent executuable object image -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares a file format independent ObjectImage class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H -#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H - -#include "llvm/ExecutionEngine/ObjectBuffer.h" -#include "llvm/Object/ObjectFile.h" - -namespace llvm { - - -/// ObjectImage - A container class that represents an ObjectFile that has been -/// or is in the process of being loaded into memory for execution. -class ObjectImage { - ObjectImage() LLVM_DELETED_FUNCTION; - ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION; - virtual void anchor(); - -protected: - std::unique_ptr<ObjectBuffer> Buffer; - -public: - ObjectImage(ObjectBuffer *Input) : Buffer(Input) {} - virtual ~ObjectImage() {} - - virtual object::symbol_iterator begin_symbols() const = 0; - virtual object::symbol_iterator end_symbols() const = 0; - iterator_range<object::symbol_iterator> symbols() const { - return iterator_range<object::symbol_iterator>(begin_symbols(), - end_symbols()); - } - - virtual object::section_iterator begin_sections() const = 0; - virtual object::section_iterator end_sections() const = 0; - iterator_range<object::section_iterator> sections() const { - return iterator_range<object::section_iterator>(begin_sections(), - end_sections()); - } - - virtual /* Triple::ArchType */ unsigned getArch() const = 0; - - // Subclasses can override these methods to update the image with loaded - // addresses for sections and common symbols - virtual void updateSectionAddress(const object::SectionRef &Sec, - uint64_t Addr) = 0; - virtual void updateSymbolAddress(const object::SymbolRef &Sym, - uint64_t Addr) = 0; - - virtual StringRef getData() const = 0; - - virtual object::ObjectFile* getObjectFile() const = 0; - - // Subclasses can override these methods to provide JIT debugging support - virtual void registerWithDebugger() = 0; - virtual void deregisterWithDebugger() = 0; -}; - -} // end namespace llvm - -#endif // LLVM_EXECUTIONENGINE_OBJECTIMAGE_H diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h index b1d6810f374b..ef81cd328bdb 100644 --- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h +++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H -#define LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H +#ifndef LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H +#define LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H #include "llvm-c/ExecutionEngine.h" #include "llvm/ADT/StringRef.h" @@ -22,7 +22,10 @@ namespace llvm { class ExecutionEngine; -class ObjectImage; + + namespace object { + class ObjectFile; + } // RuntimeDyld clients often want to handle the memory management of // what gets placed where. For JIT clients, this is the subset of @@ -76,9 +79,15 @@ public: virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size); + /// This method returns the address of the specified function or variable in + /// the current process. + static uint64_t getSymbolAddressInProcess(const std::string &Name); + /// This method returns the address of the specified function or variable. /// It is used to resolve symbols during module linking. - virtual uint64_t getSymbolAddress(const std::string &Name); + virtual uint64_t getSymbolAddress(const std::string &Name) { + return getSymbolAddressInProcess(Name); + } /// This method returns the address of the specified function. As such it is /// only useful for resolving library symbols, not code generated symbols. @@ -103,7 +112,7 @@ public: /// address space can use this call to remap the section addresses for the /// newly loaded object. virtual void notifyObjectLoaded(ExecutionEngine *EE, - const ObjectImage *) {} + const object::ObjectFile &) {} /// This method is called when object loading is complete and section page /// permissions can be applied. It is up to the memory manager implementation @@ -123,4 +132,4 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS( } // namespace llvm -#endif // LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H +#endif diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index f123ffb803bd..799fc34eb659 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -15,58 +15,75 @@ #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H #include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/Support/Memory.h" +#include <memory> namespace llvm { namespace object { class ObjectFile; + template <typename T> class OwningBinary; } class RuntimeDyldImpl; -class ObjectImage; +class RuntimeDyldCheckerImpl; class RuntimeDyld { - friend class RuntimeDyldChecker; + friend class RuntimeDyldCheckerImpl; RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION; void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION; // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public // interface. - RuntimeDyldImpl *Dyld; + std::unique_ptr<RuntimeDyldImpl> Dyld; RTDyldMemoryManager *MM; bool ProcessAllSections; + RuntimeDyldCheckerImpl *Checker; protected: // 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: + + /// \brief Information about the loaded object. + class LoadedObjectInfo { + friend class RuntimeDyldImpl; + public: + LoadedObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx, + unsigned EndIdx) + : RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { } + + virtual ~LoadedObjectInfo() {} + + virtual object::OwningBinary<object::ObjectFile> + getObjectForDebug(const object::ObjectFile &Obj) const = 0; + + uint64_t getSectionLoadAddress(StringRef Name) const; + + protected: + virtual void anchor(); + + RuntimeDyldImpl &RTDyld; + unsigned BeginIdx, EndIdx; + }; + RuntimeDyld(RTDyldMemoryManager *); ~RuntimeDyld(); - /// Prepare the object contained in the input buffer for execution. - /// Ownership of the input buffer is transferred to the ObjectImage - /// instance returned from this function if successful. In the case of load - /// failure, the input buffer will be deleted. - ObjectImage *loadObject(ObjectBuffer *InputBuffer); - - /// Prepare the referenced object file for execution. - /// Ownership of the input object is transferred to the ObjectImage - /// instance returned from this function if successful. In the case of load - /// failure, the input object will be deleted. - ObjectImage *loadObject(std::unique_ptr<object::ObjectFile> InputObject); + /// Add the referenced object file to the list of objects to be loaded and + /// relocated. + std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O); /// Get the address of our local copy of the symbol. This may or may not /// be the address used for relocation (clients can copy the data around /// and resolve relocatons based on where they put it). - void *getSymbolAddress(StringRef Name); + void *getSymbolAddress(StringRef Name) const; /// Get the address of the target copy of the symbol. This is the address /// used for relocation. - uint64_t getSymbolLoadAddress(StringRef Name); + uint64_t getSymbolLoadAddress(StringRef Name) const; /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h index 8dd891e83648..35ceba27596c 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h +++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h @@ -7,18 +7,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_RUNTIMEDYLDCHECKER_H -#define LLVM_RUNTIMEDYLDCHECKER_H +#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H +#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H -#include "RuntimeDyld.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -#include <map> +#include "llvm/ADT/StringRef.h" namespace llvm { class MCDisassembler; +class MemoryBuffer; class MCInstPrinter; +class RuntimeDyld; +class RuntimeDyldCheckerImpl; +class raw_ostream; /// \brief RuntimeDyld invariant checker for verifying that RuntimeDyld has /// correctly applied relocations. @@ -61,14 +62,16 @@ class MCInstPrinter; /// | expr '>>' expr /// class RuntimeDyldChecker { - friend class RuntimeDyldCheckerExprEval; public: - RuntimeDyldChecker(RuntimeDyld &RTDyld, - MCDisassembler *Disassembler, - MCInstPrinter *InstPrinter, - llvm::raw_ostream &ErrStream) - : RTDyld(*RTDyld.Dyld), Disassembler(Disassembler), - InstPrinter(InstPrinter), ErrStream(ErrStream) {} + RuntimeDyldChecker(RuntimeDyld &RTDyld, MCDisassembler *Disassembler, + MCInstPrinter *InstPrinter, raw_ostream &ErrStream); + ~RuntimeDyldChecker(); + + // \brief Get the associated RTDyld instance. + RuntimeDyld& getRTDyld(); + + // \brief Get the associated RTDyld instance. + const RuntimeDyld& getRTDyld() const; /// \brief Check a single expression against the attached RuntimeDyld /// instance. @@ -79,20 +82,20 @@ public: /// method to be evaluated as an expression. bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const; -private: + /// \brief Returns the address of the requested section (or an error message + /// in the second element of the pair if the address cannot be found). + /// + /// if 'LinkerAddress' is true, this returns the address of the section + /// within the linker's memory. If 'LinkerAddress' is false it returns the + /// address within the target process (i.e. the load address). + std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName, + StringRef SectionName, + bool LinkerAddress); - bool isSymbolValid(StringRef Symbol) const; - uint64_t getSymbolAddress(StringRef Symbol) const; - uint64_t readMemoryAtSymbol(StringRef Symbol, int64_t Offset, - unsigned Size) const; - StringRef getSubsectionStartingAt(StringRef Name) const; - - RuntimeDyldImpl &RTDyld; - MCDisassembler *Disassembler; - MCInstPrinter *InstPrinter; - llvm::raw_ostream &ErrStream; +private: + std::unique_ptr<RuntimeDyldCheckerImpl> Impl; }; } // end namespace llvm -#endif // LLVM_RUNTIMEDYLDCHECKER_H +#endif |