summaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ExecutionEngine')
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h19
-rw-r--r--include/llvm/ExecutionEngine/IntelJITEventsWrapper.h102
-rw-r--r--include/llvm/ExecutionEngine/JITEventListener.h15
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h31
-rw-r--r--include/llvm/ExecutionEngine/ObjectBuffer.h80
-rw-r--r--include/llvm/ExecutionEngine/ObjectImage.h61
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h47
7 files changed, 205 insertions, 150 deletions
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index ae8b68d0241e..8073d8f92c51 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -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 ca873420299c..000000000000
--- 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 eea603fcee2c..e6586e778c19 100644
--- a/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/include/llvm/ExecutionEngine/JITEventListener.h
@@ -26,6 +26,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 +77,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 4c75b6ab970e..90896465018c 100644
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -10,7 +10,9 @@
#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>
namespace llvm {
@@ -22,7 +24,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 +49,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 +103,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/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
new file mode 100644
index 000000000000..a0a77b8ba888
--- /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/SmallVector.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.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 000000000000..82549add62e8
--- /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/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.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_RUNTIMEDYLD_OBJECT_IMAGE_H
+
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index a5c9272d3ca6..891f534862f4 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -15,43 +15,55 @@
#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.
+ /// 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.
+ /// 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;
+ /// 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 returns a null pointer. Otherwise, it prints a
+ /// message to stderr and aborts.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) = 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,17 +74,24 @@ 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);
+ /// loadObject - 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
/// and resolve relocatons based on where they put it).
void *getSymbolAddress(StringRef Name);
+ /// Get the address of the target copy of the symbol. This is the address
+ /// used for relocation.
+ uint64_t getSymbolLoadAddress(StringRef Name);
+
/// Resolve the relocations for all symbols we currently know about.
void resolveRelocations();
@@ -80,7 +99,7 @@ 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.
- void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress);
+ void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
StringRef getErrorString();
};