diff options
Diffstat (limited to 'include/llvm/ExecutionEngine')
| -rw-r--r-- | include/llvm/ExecutionEngine/ExecutionEngine.h | 27 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/IntelJITEventsWrapper.h | 102 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/JITEventListener.h | 18 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/JITMemoryManager.h | 30 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/OProfileWrapper.h | 8 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/ObjectBuffer.h | 80 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/ObjectImage.h | 61 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/RuntimeDyld.h | 60 | ||||
| -rw-r--r-- | include/llvm/ExecutionEngine/SectionMemoryManager.h | 176 |
9 files changed, 397 insertions, 165 deletions
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index ae8b68d..2d60c36 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -15,19 +15,19 @@ #ifndef LLVM_EXECUTION_ENGINE_H #define LLVM_EXECUTION_ENGINE_H -#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include <vector> #include <map> #include <string> +#include <vector> namespace llvm { @@ -42,7 +42,7 @@ class JITMemoryManager; class MachineCodeInfo; class Module; class MutexGuard; -class TargetData; +class DataLayout; class Triple; class Type; @@ -88,7 +88,7 @@ public: /// \brief Erase an entry from the mapping table. /// - /// \returns The address that \arg ToUnmap was happed to. + /// \returns The address that \p ToUnmap was happed to. void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap); }; @@ -104,7 +104,7 @@ class ExecutionEngine { ExecutionEngineState EEState; /// The target data for the platform for which execution is being performed. - const TargetData *TD; + const DataLayout *TD; /// Whether lazy JIT compilation is enabled. bool CompilingLazily; @@ -123,7 +123,7 @@ protected: /// optimize for the case where there is only one module. SmallVector<Module*, 1> Modules; - void setTargetData(const TargetData *td) { TD = td; } + void setDataLayout(const DataLayout *td) { TD = td; } /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -213,7 +213,7 @@ public: //===--------------------------------------------------------------------===// - const TargetData *getTargetData() const { return TD; } + const DataLayout *getDataLayout() const { return TD; } /// removeModule - Remove a Module from the list of modules. Returns true if /// M is found. @@ -244,11 +244,18 @@ public: /// Map the address of a JIT section as returned from the memory manager /// to the address in the target process as the running code will see it. /// This is the address which will be used for relocation resolution. - virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) { + virtual void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) { llvm_unreachable("Re-mapping of section addresses not supported with this " "EE!"); } + // finalizeObject - This method 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. + virtual void finalizeObject() {} + /// runStaticConstructorsDestructors - This method is used to execute all of /// the static constructors or destructors for a program. /// diff --git a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h b/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h deleted file mode 100644 index ca87342..0000000 --- a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h +++ /dev/null @@ -1,102 +0,0 @@ -//===-- IntelJITEventsWrapper.h - Intel JIT Events API Wrapper --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a wrapper for the Intel JIT Events API. It allows for the -// implementation of the jitprofiling library to be swapped with an alternative -// implementation (for testing). To include this file, you must have the -// jitprofiling.h header available; it is available in Intel(R) VTune(TM) -// Amplifier XE 2011. -// -//===----------------------------------------------------------------------===// - -#ifndef INTEL_JIT_EVENTS_WRAPPER_H -#define INTEL_JIT_EVENTS_WRAPPER_H - -#include <jitprofiling.h> - -namespace llvm { - -class IntelJITEventsWrapper { - // Function pointer types for testing implementation of Intel jitprofiling - // library - typedef int (*NotifyEventPtr)(iJIT_JVM_EVENT, void*); - typedef void (*RegisterCallbackExPtr)(void *, iJIT_ModeChangedEx ); - typedef iJIT_IsProfilingActiveFlags (*IsProfilingActivePtr)(void); - typedef void (*FinalizeThreadPtr)(void); - typedef void (*FinalizeProcessPtr)(void); - typedef unsigned int (*GetNewMethodIDPtr)(void); - - NotifyEventPtr NotifyEventFunc; - RegisterCallbackExPtr RegisterCallbackExFunc; - IsProfilingActivePtr IsProfilingActiveFunc; - FinalizeThreadPtr FinalizeThreadFunc; - FinalizeProcessPtr FinalizeProcessFunc; - GetNewMethodIDPtr GetNewMethodIDFunc; - -public: - bool isAmplifierRunning() { - return iJIT_IsProfilingActive() == iJIT_SAMPLING_ON; - } - - IntelJITEventsWrapper() - : NotifyEventFunc(::iJIT_NotifyEvent), - RegisterCallbackExFunc(::iJIT_RegisterCallbackEx), - IsProfilingActiveFunc(::iJIT_IsProfilingActive), - FinalizeThreadFunc(::FinalizeThread), - FinalizeProcessFunc(::FinalizeProcess), - GetNewMethodIDFunc(::iJIT_GetNewMethodID) { - } - - IntelJITEventsWrapper(NotifyEventPtr NotifyEventImpl, - RegisterCallbackExPtr RegisterCallbackExImpl, - IsProfilingActivePtr IsProfilingActiveImpl, - FinalizeThreadPtr FinalizeThreadImpl, - FinalizeProcessPtr FinalizeProcessImpl, - GetNewMethodIDPtr GetNewMethodIDImpl) - : NotifyEventFunc(NotifyEventImpl), - RegisterCallbackExFunc(RegisterCallbackExImpl), - IsProfilingActiveFunc(IsProfilingActiveImpl), - FinalizeThreadFunc(FinalizeThreadImpl), - FinalizeProcessFunc(FinalizeProcessImpl), - GetNewMethodIDFunc(GetNewMethodIDImpl) { - } - - // Sends an event anncouncing that a function has been emitted - // return values are event-specific. See Intel documentation for details. - int iJIT_NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) { - if (!NotifyEventFunc) - return -1; - return NotifyEventFunc(EventType, EventSpecificData); - } - - // Registers a callback function to receive notice of profiling state changes - void iJIT_RegisterCallbackEx(void *UserData, - iJIT_ModeChangedEx NewModeCallBackFuncEx) { - if (RegisterCallbackExFunc) - RegisterCallbackExFunc(UserData, NewModeCallBackFuncEx); - } - - // Returns the current profiler mode - iJIT_IsProfilingActiveFlags iJIT_IsProfilingActive(void) { - if (!IsProfilingActiveFunc) - return iJIT_NOTHING_RUNNING; - return IsProfilingActiveFunc(); - } - - // Generates a locally unique method ID for use in code registration - unsigned int iJIT_GetNewMethodID(void) { - if (!GetNewMethodIDFunc) - return -1; - return GetNewMethodIDFunc(); - } -}; - -} //namespace llvm - -#endif //INTEL_JIT_EVENTS_WRAPPER_H diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index eea603f..3aa014e 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -15,10 +15,9 @@ #ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H #define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" - #include <vector> namespace llvm { @@ -26,6 +25,7 @@ class Function; class MachineFunction; class OProfileWrapper; class IntelJITEventsWrapper; +class ObjectImage; /// JITEvent_EmittedFunctionDetails - Helper struct for containing information /// about a generated machine code function. @@ -76,6 +76,20 @@ public: /// matching NotifyFreeingMachineCode call. virtual void NotifyFreeingMachineCode(void *) {} + /// NotifyObjectEmitted - Called after an object has been successfully + /// emitted to memory. NotifyFunctionEmitted will not be called for + /// individual functions in the object. + /// + /// ELF-specific information + /// 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) {} + + /// NotifyFreeingObject - Called just before the memory associated with + /// a previously emitted object is released. + virtual void NotifyFreeingObject(const ObjectImage &Obj) {} + #if LLVM_USE_INTEL_JITEVENTS // Construct an IntelJITEventListener static JITEventListener *createIntelJITEventListener(); diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 4c75b6a..29e01aa 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -10,6 +10,7 @@ #ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H #define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H +#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Support/DataTypes.h" #include <string> @@ -22,7 +23,7 @@ namespace llvm { /// 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 { +class JITMemoryManager : public RTDyldMemoryManager { protected: bool HasGOT; @@ -47,17 +48,6 @@ public: /// debugging, and may be turned on by default in debug mode. virtual void setPoisonMemory(bool poison) = 0; - /// getPointerToNamedFunction - This method returns the address of the - /// specified function. As such it is only useful for resolving library - /// symbols, not code generated symbols. - /// - /// If AbortOnFailure is false and no function with the given name is - /// found, this function silently returns a null pointer. Otherwise, - /// it prints a message to stderr and aborts. - /// - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true) = 0; - //===--------------------------------------------------------------------===// // Global Offset Table Management //===--------------------------------------------------------------------===// @@ -112,22 +102,6 @@ public: virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, uint8_t *FunctionEnd) = 0; - /// allocateCodeSection - Allocate a memory block of (at least) the given - /// size suitable for executable code. The SectionID is a unique identifier - /// assigned by the JIT and passed through to the memory manager for - /// the instance class to use if it needs to communicate to the JIT about - /// a given section after the fact. - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) = 0; - - /// allocateDataSection - Allocate a memory block of (at least) the given - /// size suitable for data. The SectionID is a unique identifier - /// assigned by the JIT and passed through to the memory manager for - /// the instance class to use if it needs to communicate to the JIT about - /// a given section after the fact. - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) = 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; diff --git a/include/llvm/ExecutionEngine/OProfileWrapper.h b/include/llvm/ExecutionEngine/OProfileWrapper.h index ab7f25e..99553a3 100644 --- a/include/llvm/ExecutionEngine/OProfileWrapper.h +++ b/include/llvm/ExecutionEngine/OProfileWrapper.h @@ -41,10 +41,10 @@ class OProfileWrapper { typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t); // Also used for op_minor_version function which has the same signature - typedef int (*op_major_version_ptr_t)(void); + typedef int (*op_major_version_ptr_t)(); // This is not a part of the opagent API, but is useful nonetheless - typedef bool (*IsOProfileRunningPtrT)(void); + typedef bool (*IsOProfileRunningPtrT)(); op_agent_t Agent; @@ -99,8 +99,8 @@ public: size_t num_entries, struct debug_line_info const* info); int op_unload_native_code(uint64_t addr); - int op_major_version(void); - int op_minor_version(void); + int op_major_version(); + int op_minor_version(); // Returns true if the oprofiled process is running, the opagent library is // loaded and a connection to the agent has been established, and false diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h new file mode 100644 index 0000000..96a48b2 --- /dev/null +++ b/include/llvm/ExecutionEngine/ObjectBuffer.h @@ -0,0 +1,80 @@ +//===---- 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/OwningPtr.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 { +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(), "", false); + } + + const char *getBufferStart() const { return Buffer->getBufferStart(); } + size_t getBufferSize() const { return Buffer->getBufferSize(); } + +protected: + // The memory contained in an ObjectBuffer + OwningPtr<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 { +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/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h new file mode 100644 index 0000000..d09e4de --- /dev/null +++ b/include/llvm/ExecutionEngine/ObjectImage.h @@ -0,0 +1,61 @@ +//===---- 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; + +protected: + OwningPtr<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; + + virtual object::section_iterator begin_sections() const = 0; + virtual object::section_iterator end_sections() const = 0; + + 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; + + // 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/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 9e5ad2f..e2905e3 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -15,43 +15,62 @@ #define LLVM_RUNTIME_DYLD_H #include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/Support/Memory.h" namespace llvm { class RuntimeDyldImpl; -class MemoryBuffer; +class ObjectImage; // RuntimeDyld clients often want to handle the memory management of -// what gets placed where. For JIT clients, this is an abstraction layer -// over the JITMemoryManager, which references objects by their source -// representations in LLVM IR. +// what gets placed where. For JIT clients, this is the subset of +// JITMemoryManager required for dynamic loading of binaries. +// // FIXME: As the RuntimeDyld fills out, additional routines will be needed // for the varying types of objects to be allocated. class RTDyldMemoryManager { - RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT - void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT + RTDyldMemoryManager(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; + void operator=(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; public: RTDyldMemoryManager() {} virtual ~RTDyldMemoryManager(); - /// allocateCodeSection - Allocate a memory block of (at least) the given - /// size suitable for executable code. + /// Allocate a memory block of (at least) the given size suitable for + /// executable code. The SectionID is a unique identifier assigned by the JIT + /// engine, and optionally recorded by the memory manager to access a loaded + /// section. virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) = 0; - /// allocateDataSection - Allocate a memory block of (at least) the given - /// size suitable for data. + /// Allocate a memory block of (at least) the given size suitable for data. + /// The SectionID is a unique identifier assigned by the JIT engine, and + /// optionally recorded by the memory manager to access a loaded section. virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) = 0; - + unsigned SectionID, bool IsReadOnly) = 0; + + /// This method returns the address of the specified function. As such it is + /// only useful for resolving library symbols, not code generated symbols. + /// + /// If AbortOnFailure is false and no function with the given name is + /// found, this function returns a null pointer. Otherwise, it prints a + /// message to stderr and aborts. virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) = 0; + + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. + /// + /// Returns true if an error occurred, false otherwise. + virtual bool applyPermissions(std::string *ErrMsg = 0) = 0; }; class RuntimeDyld { - RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT - void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT + RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION; + void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION; // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public // interface. @@ -62,11 +81,14 @@ protected: // Any relocations already associated with the symbol will be re-resolved. void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: - RuntimeDyld(RTDyldMemoryManager*); + RuntimeDyld(RTDyldMemoryManager *); ~RuntimeDyld(); - /// Load an in-memory object file into the dynamic linker. - bool loadObject(MemoryBuffer *InputBuffer); + /// 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); /// 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 @@ -80,11 +102,11 @@ public: /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); - /// mapSectionAddress - map a section to its target address space value. + /// Map a section to its target address space value. /// Map the address of a JIT section as returned from the memory manager /// to the address in the target process as the running code will see it. /// This is the address which will be used for relocation resolution. - void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress); + void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); StringRef getErrorString(); }; diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h new file mode 100644 index 0000000..ba4ba8d0 --- /dev/null +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -0,0 +1,176 @@ +//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of a section-based memory manager used by +// the MCJIT execution engine and RuntimeDyld. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H +#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Memory.h" + +namespace llvm { + +/// This is a simple memory manager which implements the methods called by +/// the RuntimeDyld class to allocate memory for section-based loading of +/// objects, usually those generated by the MCJIT execution engine. +/// +/// This memory manager allocates all section memory as read-write. The +/// RuntimeDyld will copy JITed section memory into these allocated blocks +/// and perform any necessary linking and relocations. +/// +/// Any client using this memory manager MUST ensure that section-specific +/// page permissions have been applied before attempting to execute functions +/// in the JITed object. Permissions can be applied either by calling +/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions +/// directly. Clients of MCJIT should call MCJIT::finalizeObject. +class SectionMemoryManager : public JITMemoryManager { + SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; + void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; + +public: + SectionMemoryManager() { } + virtual ~SectionMemoryManager(); + + /// \brief Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + + /// \brief Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + bool isReadOnly); + + /// \brief Applies section-specific memory permissions. + /// + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. Code sections cannot be executed + /// until this function has been called. + /// + /// \returns true if an error occurred, false otherwise. + virtual bool applyPermissions(std::string *ErrMsg = 0); + + /// This method returns the address of the specified function. As such it is + /// only useful for resolving library symbols, not code generated symbols. + /// + /// If \p AbortOnFailure is false and no function with the given name is + /// found, this function returns a null pointer. Otherwise, it prints a + /// message to stderr and aborts. + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true); + + /// \brief Invalidate instruction cache for code sections. + /// + /// Some platforms with separate data cache and instruction cache require + /// explicit cache flush, otherwise JIT code manipulations (like resolved + /// relocations) will get to the data cache but not to the instruction cache. + /// + /// This method is not called by RuntimeDyld or MCJIT during the load + /// process. Clients may call this function when needed. See the lli + /// tool for example use. + virtual void invalidateInstructionCache(); + +private: + struct MemoryGroup { + SmallVector<sys::MemoryBlock, 16> AllocatedMem; + SmallVector<sys::MemoryBlock, 16> FreeMem; + sys::MemoryBlock Near; + }; + + uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, + unsigned Alignment); + + error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions); + + MemoryGroup CodeMem; + MemoryGroup RWDataMem; + MemoryGroup RODataMem; + +public: + /// + /// Functions below are not used by MCJIT or RuntimeDyld, but must be + /// implemented because they are declared as pure virtuals in the base class. + /// + + virtual void setMemoryWritable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setMemoryExecutable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setPoisonMemory(bool poison) { + llvm_unreachable("Unexpected call!"); + } + virtual void AllocateGOT() { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *getGOTBase() const { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *startFunctionBody(const Function *F, + uintptr_t &ActualSize){ + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize, + unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void deallocateFunctionBody(void *Body) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *startExceptionTable(const Function *F, + uintptr_t &ActualSize) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endExceptionTable(const Function *F, uint8_t *TableStart, + uint8_t *TableEnd, uint8_t *FrameRegister) { + llvm_unreachable("Unexpected call!"); + } + virtual void deallocateExceptionTable(void *ET) { + llvm_unreachable("Unexpected call!"); + } +}; + +} + +#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H + |
